1 ZeroMQ概述算法
ZeroMQ是一种基于消息队列的多线程网络库,其对套接字类型、链接处理、帧、甚至路由的底层细节进行抽象,提供跨越多种传输协议的套接字。ZeroMQ是网络通讯中新的一层,介于应用层和传输层之间(按照TCP/IP划分),其是一个可伸缩层,可并行运行,分散在分布式系统间。服务器
2 系统架构网络
2.1整体架构多线程
ZeroMQ几乎全部的I/O操做都是异步的,主线程不会被阻塞。ZeroMQ会根据用户调用zmq_init函数时传入的接口参数,建立对应数量的I/O Thread。每一个I/O Thread都有与之绑定的Poller,Poller采用经典的Reactor模式实现,Poller根据不一样操做系统平台使用不一样的网络I/O模型(select、poll、epoll、devpoll、kequeue等)。主线程与I/O线程经过Mail Box传递消息来进行通讯。Server开始监听或者Client发起链接时,在主线程中建立zmq_connecter或zmq_listener,经过Mail Box发消息的形式将其绑定到I/O线程,I/O线程会把zmq_connecter或zmq_listener添加到Poller中用以侦听读/写事件。Server与Client在第一次通讯时,会建立zmq_init来发送identity,用以进行认证。认证结束后,双方会为这次链接建立Session,之后双方就经过Session进行通讯。每一个Session都会关联到相应的读/写管道, 主线程收发消息只是分别从管道中读/写数据。Session并不实际跟kernel交换I/O数据,而是经过plugin到Session中的Engine来与kernel交换I/O数据。架构
图1整体架构 并发
2.2所处层次 负载均衡
ZeroMQ不是单独的服务或者程序,仅仅是一套组件,其封装了网络通讯、消息队列、线程调度等功能,向上层提供简洁的API,应用程序经过加载库文件,调用API函数来实现高性能网络通讯。 异步
图2所处层次 tcp
2.3消息模型 分布式
ZeroMQ将消息通讯分红4种模型,分别是一对一结对模型(Exclusive-Pair)、请求回应模型(Request-Reply)、发布订阅模型(Publish-Subscribe)、推拉模型(Push-Pull)。这4种模型总结出了通用的网络通讯模型,在实际中能够根据应用须要,组合其中的2种或多种模型来造成本身的解决方案。
2.3.1 一对一结对模型
最简单的1:1消息通讯模型,能够认为是一个TCP Connection,可是TCP Server只能接受一个链接。数据能够双向流动,这点不一样于后面的请求回应模型。
2.3.2 请求回应模型
由请求端发起请求,而后等待回应端应答。一个请求必须对应一个回应,从请求端的角度来看是发-收配对,从回应端的角度是收-发对。跟一对一结对模型的区别在于请求端能够是1~N个。该模型主要用于远程调用及任务分配等。Echo服务就是这种经典模型的应用。
图3请求回应模型
2.3.3 发布订阅模型
发布端 单向分发数据,且不关心是否把所有信息发送给订阅端。若是发布端开始发布信息时,订阅端还没有链接上来,则这些信息会被直接丢弃。订阅端未链接致使信息丢失 的问题,能够经过与请求回应模型组合来解决。订阅端只负责接收,而不能反馈,且在订阅端消费速度慢于发布端的状况下,会在订阅端堆积数据。该模型主要用于 数据分发。天气预报、微博明星粉丝能够应用这种经典模型。
图4发布订阅模型
2.3.4 推拉模型
Server端做为Push端,而Client端做为Pull端,若是有多个Client端同时链接到Server端,则Server端会在内部作一个负载均衡,采用平均分配的算法,将全部消息均衡发布到Client端上。与发布订阅模型相比,推拉模型在没有消费者的状况下,发布的消息不会被消耗掉;在消费者能力不够的状况下,可以提供多消费者并行消费解决方案。该模型主要用于多任务并行。
图5 推拉模型
2.4通讯协议
提供进程内、进程间、机器间、广播等四种通讯协议。通讯协议配置简单,用相似于URL形式的字符串指定便可,格式分别为inproc://、ipc://、tcp://、pgm://。ZeroMQ会自动根据指定的字符串解析出协议、地址、端口号等信息。
3 工做流程
图6 基本流程
4 性能分析
目前,市面上相似的产品很多,主要有4种:MSMQ(微软产品)、ActiveMQ(Java)、RabbitMQ(Erlang)、ZeroMQ(C++)。除ZeroMQ外,其它3款产品都是一个单独服务或者进程,须要单独安装和运行,且对环境有必定依赖。其中,MSMQ在非Windows平台下安装很是复杂,ActiveMQ须要目标机器上已经安装了Java,RabbitMQ须要Erlang环境。而ZeroMQ是以库的形式存在,由应用程序加载、运行便可。可是ZeroMQ仅提供非持久性的消息队列。
图7是来自于Internet的性能测试数据。显示的是每秒钟发送和接受的消息数。整个过程共产生1百万条1K的消息,测试环境为Windows Vista。从测试数据能够看出,ZeroMQ的性能远远高于其它3个MQ。
可是测试数据仅供参考,由于缺乏必须的环境参数和性能指标,好比:CPU参数、内存参数、消息模型、通讯协议、极限时消耗CPU百分比、极限时消耗内存百分比等。
图7性能测试
5 应用场景
应用ZeroMQ的Push-Pull模型实现联众游戏服务器的“热插拔”、负载均衡和消息派发。按照如图8部署服务器,Push端充当Gateway,做为一组游戏服务器集群最上层的一个Proxy,起负载均衡的做用,全部Gameserver做为Pull端。当一个请求到达Push端(Gateway)时,Push端根据必定的分配策略将任务派发到Pull端(Gameserver)。以联众某款游戏A为例,游戏A刚上线时,预计最大同时在线人数是10W,单台Gameserver并发处理能力为1W,须要10台Gameserver,因为游戏A可玩性很是好,半个月后最大同时在线人数暴增到50W,那么不须要在某天的凌晨将Gateway和Gameserver停机,只须要随时在机房新添加40台Gameserver,启动并链接到Gateway便可。
ZeroMQ中对Client和Server的启动顺序没有要求,Gameserver之间若是须要通讯的话,Gameserver的应用层不须要管理这些细节,ZeroMQ已经作了重连处理。
图8应用场景
6 总结
6.1简单
1、仅仅提供24个API接口,风格相似于BSD Socket。
2、处理了网络异常,包括链接异常中断、重连等。
3、改变TCP基于字节流收发数据的方式,处理了粘包、半包等问题,以msg为单位收发数据,结合Protocol Buffers,能够对应用层完全屏蔽网络通讯层。
4、对大数据经过SENDMORE/RECVMORE提供分包收发机制。
5、经过线程间数据流动来保证同一时刻任何数据都只会被一个线程持有,以此实现多线程的“去锁化”。
6、经过高水位HWM来控制流量,用交换SWAP来转储内存数据,弥补HWM丢失数据的缺陷。
7、服务器端和客户端的启动没有前后顺序。
6.2灵活
1、支持多种通讯协议,能够灵活地适应多种通讯环境,包括进程内、进程间、机器间、广播。
2、支持多种消息模型,消息模型之间能够相互组合,造成特定的解决方案。
6.3跨平台
支持Linux、Windows、OS X等。
6.4多语言
能够绑定C、C++、Java、.NET、Python等30多种开发语言。
6.5高性能
相对同类产品,性能卓越。