邱 杰,朱晓姝,孙小雁
(玉林师范学院 计算机科学与工程学院,广西 玉林 537000)
基于Epoll模型的消息推送研究与实现
邱杰,朱晓姝,孙小雁
(玉林师范学院 计算机科学与工程学院,广西 玉林537000)
摘要:当前消息推送已成为网络消息传递的一种主流方式,特别在移动平台上得到广泛应用,淘宝、QQ及微信等大型交流平台都使用消息推送方式。在Linux系统下的Epoll模型是一种优秀的通信模型,它优于Select模型和Poll模型,在连接数量上限制很小,并且对CPU的负担比较小。文章基于Epoll模型和长连接方法设计一种新的消息推送方法,并与国际流行的消息推送方法进行对比仿真实验,实验结果表明,基于Epoll模型的消息推送方法在及时性与连接数量耗时上均优于传统的方法。
关键词:消息推送;Epoll模型;Linux系统;长连接;数据包
0引言
随着互联网与移动平台的快速发展,淘宝、QQ、微信及Facebook等都已经把重点方向转移到移动端方面[1],它们对在移动平台上的消息发送与获取都有很高的需求和期待,特别是在及时性方面,要求发送与接收的信息必须在规定的时间内送达与收到。消息推送方式则应运而生,消息推送的服务器会不断地更新信息,通过建立一条手机与服务器的连接链路,当有更新好的消息需要发送到手机时,通过此链路发送即可。与传统的发送方式相比,消息推送减少了服务器与客户端的交互次数和通信时间,提高了通信效率,而且是由服务器直接将更新好的消息推送过去,并不需要客户端主动参与,客户端可以第一时间获取更新的消息[2]。
基于消息推送的上述优点,近年来消息推送方式将会是主流的消息发送方式。本文提出一种基于Epoll模型的消息推送方式,这种方式可以提高消息推送的效率。
1消息推送的原理
消息推送的流程[3-4]如下:
(1)启动服务器与客户端。
(2)客户端请求连接服务器,并建立基于TCP协议的长连接。
(3)服务器端获取或者更新消息,可以由其他网络系统或者自行循环扫描获得。
(4)服务器把消息放入一个由内存制造出来的队列中。
(5)服务器把消息发送给客户端。
(6)客户端接收到消息并做异步处理。
在上述推送过程中,要注意以下4点[5-6]:
(1)要保证服务器正常运行,则需要在服务端开一个监控服务,用来监控这个服务端正常运行。如果服务端异常,强制重启,并返回一个通知。
(2)为了保证服务器与客户端不中断连接,服务端每25 s给客户端发送一个特定消息包或者称之为心跳包。如果客户端收到这个心跳包,说明连接是正常的,如果未收到则说明这个包连接已经中断,此时客户端的监控程序监控到中断,就会强制重启客户端,并再次与服务端进行连接。
(3)为确保服务端与客户端之间通信所传送数据的完整性,两端之间用json格式进行传输,然后在对方得到数据后进行反序列化解析,如果格式不正确则丢弃。
(4)数据传输过程中为了防止数据丢失,服务端会每15 min检查1次,如果用户没有获取信息,则说明客户端掉线,在下次连接后,再把断线这个时间段积累的消息发给客户端。
当前使用比较多的消息推送机制有轮询与长连接2种:① 轮询(polling),客户端阶段性地与服务器进行连接并查询服务器是否有新的消息送达,必须保持两者之间时刻处于通信状态,要考虑轮询的频率,若太慢可能导致某些消息的延迟,若太快则会消耗大量网络带宽;② 长连接,这个方案可以解决由轮询带来的性能问题。
2Epoll模型
2.1Epoll模型的特点
Epoll模型是Linux环境下的通信模型,Linux环境中的并行通信方式有很多种类型,主要支持的I/O模型有Select、Poll和Epoll 3种模型[7]。
Select模型的最大并发数是受限制的,扫描频繁导致效率比较低,提取信息的方式是内存拷贝,从而导致提取速度非常慢。
Poll模型和Select模型具有相近的效率,性能测试发现,Select模型与Poll模型有相似的时间调用与CPU资源占用率,在活动连接数量不变的情况下,随着数据量的增加或连接数的增加,系统资源的消耗也相应增加。Poll模型也存在着Select模型的2个缺点。Poll模型被用于Polling消息推送上,它是一个被动推送的过程,客户端对服务器做轮询,服务器方监听到轮询后就会给客户端发送更新的消息,轮询频率过密会使服务器负担加重,轮询间隔太久,获取消息的及时性又不好[8-9]。
Epoll模型与上述2种模型相比,没有最大并发连接的限制,连接上限与系统内存有关,即内存越大能并发的连接就越多。Epoll另一个优点在于它只管“活跃”地并发连接数量,而不用去管连接总数的多少,因此在实际的网络环境中,Epoll模型的效率会远远高于Select模型和Poll模型。Epoll模型对信息的提取使用了“共享内存”,省略了内存拷贝,从而避免了巨大的资源消耗。
由此可见,Epoll模型是一种高并发和高承载I/O方式,可以用在大型的服务器线程处理上。在Linux系统下,每访问1个连接就要创建1个socket句柄,当需要访问很多时就会创建很多的句柄,从而使服务器消耗大量的资源,服务器也会进入监听新句柄的状态,而使用Epoll模型就可以解决这个问题,服务器不会在监听新句柄上浪费资源,Epoll模型支持socket集合的return,不需要在socket上进行一次次遍历。
2.2Epoll模型的接口
Epoll的接口主要有以下3个函数:
(1)int epoll-create(int size)。此函数可创建一个epoll的句柄。
(2)int epoll-ctl(int epfd,int op,int fd,struct epoll-event *event)。该函数是epoll的事件注册函数,不同于Select模型中监听事件时指示内核要监听什么类型的事件,而是先注册要监听的事件类型,然后监听相应事件类型即可。其中event有7个宏,分别是:EPOLLIN,表示可以读出对应的文件描述符;EPOLLOUT,表示可以写入对应的文件描述符;EPOLLPRI,表示对应的文件描述符有紧急的数据可读;EPOLLERR,表示对应的文件描述符发生错误;EPOLLHUP,表示对应的文件描述符已经被挂断;EPOLLET,将EPOLL设为Edge Triggered模式,这是相对于Level Triggered来说的;EPOLLONESHOT,只监听一次事件,当监听完这次事件后,如果还需要继续监听该socket的话,需要再次把socket加入到EPOLL队列里。
(3)int epoll-wait(int epfd,struct epoll-event * events,int maxevents,int timeout)。该函数是等待监听的事件发生。Epoll模型有如下2种工作方式:① 水平触发方式,该方式在套接字下可以支持处理阻塞与非阻塞工作模式;② 边缘触发方式,该方式只能支持处理非阻塞工作模式,因此它是一种快速的工作方式,没有阻塞干扰。
3Epoll-MP的设计与实现
3.1Epoll-MP服务构架与程序结构
基于Epoll模型的消息推送(epoll massege push,Epoll-MP)服务构架如图1所示。
由图1可看出,客户端上线后,首先连接推送消息服务器,并发送第1条身份验证的消息,将自己的ID组、播号等信息发送给服务器;服务器收到验证消息后,将验证消息及其文件描述符插入到连接状态表中;客户端启动一个单独的线程,用来接收服务器发过来的消息;服务端会定期发送心跳包给客户端。
图1 服务构架
当客户端A给客户端B推送消息时,服务器会解析该消息,根据客户端B的ID查找客户端B的文件描述符,并判断客户端B的连接状态,若客户端B已连接,则对其推送,如果未连接,则将推送消息正文插入到延迟推送消息表内,而当客户端出现网络异常,或者程序出错,则服务器会修改其连接状态。
高性能程序设计结构如图2所示,由图2可知,该服务有2个线程池(读消息线程池和发送消息线程池)、1个消息备份线程(异步备份消息)、1个日志线程(异步记录日志)、1个句柄池、1个消息任务池、1个日志任务池。
图2 程序结构
当客户端A向客户端B发送消息时,主线程接收其句柄(即文件描述符),将其放入句柄池。读消息线程池从句柄池中取出句柄,读消息并对其解析,将解析出来的消息放入消息任务池。发送消息线程池,从消息任务池中取消息,然后根据推送目标ID及其连接状态,对其进行消息推送或者消息延迟处理。消息备份线程则根据消息任务池中的消息对其进行备份,日志线程记录程序中各种异常情况信息。
3.2Epoll-MP数据库表结构
本文在实现Epoll-MP时,主要采用连接信息表、推送消息备份表和推送消息延迟表。
连接状态表记录了手机登录ID、组播号、文件描述符及连接状态,通过该表链决定推送目标,以及根据连接状态确定是否要延迟推送消息,连接状态表结构如下:
CREATE TABLE ′PushBlockMsg′(
′id′int(11)NOT NULL AUTO_INCREMENT,
′client_id′varchar(32)DEFAULT NULL COMMENT ′客户ID′,
′msgsize′int(11)DEFAULT NULL,
′blockmsg′varchar(1536)DEFAULT NULL COMMENT ′阻塞重传消息′,
′msg_time′datetime DEFAULT NULL,
′remark′varchar(1024)DEFAULT NULL,
PRIMARY KEY(′id′)
)ENGINE=MyISAM AUTO_INCREMENT=25 DEFAULT CHARSET=latin1.
延迟推送表主要记录了未推送成功的消息,以便推送目标上线后对其推送,延迟推送表结构如下:
CREATE TABLE ′PushConnectInfo′(
′client_id′varchar(32)CHARACTER SET utf8 NOT NULL COMMENT ′用户登录ID′,
′group_id′varchar(32)CHARACTER SET utf8 DEFAULT NULL COMMENT ′用户所在的群组′,
′client_fd′int(11)DEFAULT NULL COMMENT ′用户连接句柄′,
′flag′int(11)DEFAULT NULL COMMENT ′连接状态:0—未连接,1—连接′,
′last_connect_time′datetime DEFAULT NULL COMMENT ′上次成功连接的时间′,
′remark′varchar(1024)CHARACTER SET utf8 DEFAULT NULL COMMENT ′注释′,
PRIMARY KEY(′client_id′)
)ENGINE=MyISAM DEFAULT CHARSET=latin1.
消息备份表主要是对消息进行一个备份,具体如下:
CREATE TABLE ′PushMsgSave′(
′id′int(11)NOT NULL AUTO_INCREMENT,
′SrouceId′varchar(32)CHARACTER SET utf8 DEFAULT NULL COMMENT ′推送消息发送方′,
′ObjId′varchar(32)CHARACTER SET utf8 DEFAULT NULL COMMENT ′推送消息接收方′,
′ObjId_type′int(11)DEFAULT NULL COMMENT ′推送方类型 1—个人,2—组′,
′msg′varchar(32)CHARACTER SET utf8 DEFAULT NULL COMMENT ′消息′,
′msg_time′datetime DEFAULT NULL COMMENT ′时间′,
′remark′varchar(1024)CHARACTER SET utf8 DEFAULT NULL,
PRIMARY KEY(′id′)
)ENGINE=MyISAM AUTO_INCREMENT=1983 DEFAULT CHARSET=latin1.
3.3Epoll-MP数据包结构
本方法采用TCP长连接的通信方式,但是在发送包的过程中会存在粘包问题。为了解决粘包问题,对数据包进行定义,发送消息由包头和包体组成,具体定义如下。
包头:4个字节表明包体长度。
包体:json串格式发送,下面给出字段。
ProType:处理类型有1—连接、2—点对点消息、3—点对多消息。
SelfId:该客户端本身的ID号,即app登录号。
GroupId:连接时,为自己本身组号;推送时为目标组号。
ObjId:推送信息目标ID。
PushMsg:推送信息内容[UrlCode编码]。
MsgSize:推送内容大小。
具体实例如下:
0108 01{“ProType”:2,“SelfId”:“Ribbon”,“GroupId”:“Canton”,“ObjId”:“Ribbon”,“PushMsg”:“hello+world”,“MsgSize”:11}
由上述定义后的包结构就不会出现粘包,它规定了自身与目标ID,但在该通信过程中客户端会通过以下4个规律发送与接收消息:
(1)在连接消息推送服务器成功后,首先发1个连接信息的消息到服务端。
(2)连接成功后,单独开启1个线程来接收推送来的消息。
(3)由于有心跳包的发送,所以对接收到的数据按格式解析,符合规则的则推送成功。
(4)发送失败,则重新连接,接收线程重启。
4实验及分析
本文方法是一个主动推送的过程,只要服务器方检测到有更新的消息马上会推送给客户端,并且本文方法用到的Epoll模型在连接数量增加的情况下,对服务器的负担增加不会太严重。为了测试其性能,将Epoll-MP与当前流行的自适应消息推送策略(adaptive message push strategy,AMPS)[10]和传统Polling消息推送方法做对比实验,分别在多消息接收时间、多连接接收时间2个方面进行测试。
4.1多消息接收时间测试
测试平台参数为:CPU Intel 酷睿i3 4130,内存2 G,硬盘1 T,操作系统为Linux2.6,网卡为100 Mb/s。
测试方法如下:客服端向服务器发送1 000条消息,客户端记录接收消息的时间,将接收消息的时间进行处理,结果见表1所列。
表1 多消息接收时间表 ms
由表1可见,Polling模型最慢接收时间为856 ms,及时性很差,如果客户端处于轮询间隔期间,则发送出去的消息就会延迟;AMPS最慢接收时间为88 ms,是采用长连接的一种自适应方法,在效率上比Polling模型有所提高。本文方法最慢接收时间为28 ms,在消息及时性上要优于其他2个模型,只要有更新的消息可以马上推送出去。
4.2多连接接收时间测试
用多连接的方法来测试消息的耗时性,测试软件如图3所示。
图3 多线程连接图
本文分别用1 000个连接和10 000个连接来测试2种模型的消息发送时间,记录接收时间,将接收时间进行处理,结果见表2所列。
表2 多连接接收时间 s
由表2可见,Polling模型在连接数量从1 000个增加到10 000个时,耗时会从12 s提高到485 s,多负载性比较差;AMPS在耗时上提升没有Polling模型明显,但是随着连接数量的增加,其自适应效果会慢慢下降,10 000个连接耗时368 s;而本文模型在连接数量提升后耗时232 s,Epoll模型对连接数量的负载几乎可以忽略,本文模型的耗时大主要是CPU的占用率过高而导致的。如果服务器的性能更加强大,则耗时会减少很多。
5结束语
实验数据表明Epoll-MP不仅在连接数量上有所优化,而且推送的及时性会更好,客户端接收到的消息会及时准确,而且在多连接的情况下不会导致过慢。以后的工作将在多媒体文件的消息推送方面展开,其原因主要有:
(1)多媒体文件的容量很大,不管客户端将文件上传到消息推送服务器,还是消息推送服务器将文件推送给客户端、都要考虑到粘包问题,而且不管服务端,还是客户端程序都变得更为复杂。
(2)在非WiFi情况下,发送多媒体消息,会因为数据过大容易丢失而失败,而如果是一个链接,获取失败可以多次进行。
(3)在非WiFi情况下,客户并不一定想接收推送过来的耗流量的多媒体消息。比如客户端A向客户端B推送一个图片有以下3种情况:① 将图片上传到图片服务器上,返回一个连接;② 消息推送服务将该链接推送给客户端B;③ 客户端B选择性地打开该链接获取图片。
[参考文献]
[1]李伙钦.基于WebSocket的实时消息推送的设计与实现[J].科技视界,2015(3):93.
[2]许金喜,张新有.Android平台基于MQTT协议的推送机制[J].计算机系统应用,2015,24(1):185-190.
[3]李欣,杜震洪,张丰,等.基于BlazeDS消息推送的WebGIS系统设计与实现[J].计算机应用与软件,2012,29(8):14-16,33.
[4]林作佳.基于长连接的移动终端消息推送系统的设计与实现[D].西安:西安电子科技大学,2014.
[5]王利文,刘士军,武蕾.ESB支持的SaaS应用动态互操作方法[J].合肥工业大学学报:自然科学版,2013,36(4):425-430.
[6]任亨,马跃,杨海波,等.基于MQTT协议的消息推送服务器[J].计算机系统应用,2014,23(3):77-82.
[7]张超,潘旭东.Linux下基于EPOLL机制的海量网络信息处理模型[J].强激光与粒子束,2013,25(Z1):46-50.
[8]刘永玲,刘兀,郭克华.一种面向移动终端的自适应消息推送策略[J].计算机工程与科学,2013,35(12):114-119.
[9]Boon M A A,Van der Mer R D,Winands E M M.applications of polling systems[J].Surveys in Operations Research and Management Science,2011,16(2):67-82.
[10]Guo Kehua,Liu Yongling,Ma Jianhua.AMPS:an adaptive message push strategy for ubiquitous terminals[C]//IEEE International Conference on Green Computing and Communications and IEEE Internet of Things(iThings/CPSCom),and IEEE Cyber,Physical and Social Computing,2013:731-736.
(责任编辑闫杏丽)
Research and implementation of message push based on Epoll model
QIU Jie,ZHU Xiao-shu,SUN Xiao-yan
(School of Computer Science and Engineering,Yulin Normal University,Yulin 537000,China)
Abstract:At present,the message push has become a major way of the network messaging,and has been widely implemented by many large communication platforms,such as Taobao,QQ and WeChat,especially the mobile platform.In the Linux system,Epoll model is an excellent communication model which is superior to Select and Poll models,it has a small limit on the number of connections and its burden on the CPU is very small.In this paper,a new message push method is designed by using the Epoll model and long connection method.Then the designed method is compared with internationally popular methods and the results show that the method based on Epoll model is better than traditional methods in the timeliness and the number of connections.
Key words:message push;Epoll model;Linux system;long connection;data packet
收稿日期:2015-07-01;修回日期:2016-02-22
基金项目:广西壮族自治区自然科学基金资助项目(2013GXNSFAA019337);广西青年自然科学基金资助项目(2014GXNSFBA118010;2014GXNSFBA118268)和广西教育厅重点科研资助项目(2013ZD056)
作者简介:邱杰(1987-),男,广西北流人,玉林师范学院助教;朱晓姝(1973-),女,湖北新洲人,玉林师范学院教授,硕士生导师.
doi:10.3969/j.issn.1003-5060.2016.04.009
中图分类号:TP393.01
文献标识码:A
文章编号:1003-5060(2016)04-0476-05