1 ZMQ是什么?
ZeroMQ是一种基于消息队列的多线程网络库,它对套接字类型、连接处理、帧、甚至路由的底层细节进行抽象,提供跨越多种传输协议的套接字,并且支持多种通讯环境(进程内、跨进程、跨主机)。
ZMQ更多的是关注通讯双方的职责,传递的内容是一个个的消息,在使用的时候不用关心具体的细节,开发者不再需要 bind/listen/accept 来架设服务器。ZMQ在 Socket API 之上做了一层封装,将网络通讯、进程通讯和线程通讯抽象为统一的 API 接口。
2 ZMQ基本通信模型
ZeroMQ将消息通信分成3种模型,分别是请求回应模型(Request-Reply)、发布订阅模型(Publish-Subscribe)、推拉模型(Push-Pull)。这3种模型总结出了通用的网络通信模型,在实际中可以根据应用需要,组合其中的2种或多种模型来形成自己的解决方案。
2.1 Request-Reply模型
由 Client (ZMQ_REQ)发起请求,并等待 Server(ZMQ_REP) 回应请求。请求端发送一个简单的 “Hello”,服务端则回应一个 “World”。请求端和服务端都可以是 1:N 的模型。通常把 1 认为是 Server ,N 认为是 Client 。把 1:N 扩展为N:M 只需要加入若干路由节点。如图1所示:
图1:Request-Reply模型
说明:
1、服务端和客户端无论谁先启动,效果是相同的,这点不同于 Socket。
2、在服务端收到信息以前,程序是阻塞的,会一直等待客户端连接上来。
3、在REQ-REP模式中要遵循Client 连接上来以后send 消息给 Server,然后 Server rev后响应 Client这种一问一答式的模式。如果 Server 先 send,client 先 rev 程序会报错。
2.2Publish-subscribe 模型
PUB-SUB模型是一种数据分发的方法,服务器(ZMQ_PUB)把数据发送到一系列的客户端(ZMQ_SUB)上,客户端需要设置订阅接收消息,如图2所示:
图2 Publish-subscribe模型
说明:
1、 客户端需要设置订阅,否则收不到任何消息。
2、 PUB套接字无法调用函数zmq_recv来接收消息。
3、 一个客户端可以连接多个服务器。
4、 服务器一直不断的广播,如果中途有客户端退出,并不影响继续广播。当客户端再连接上来的时候,收到的就是后来发送的新的信息。
2.3PipeLine 模型
管道模型中PUSH 端向 PULL 端单向的推送数据流。Ventilator将消息发送到Worker节点,在Worker节点上使用 ZMQ_PULL 从上游接收任务,并使用 ZMQ_PUSH 将结果汇集到 Sink。如图3所示:
图3 PipeLine 模型
说明:
1、 Ventilator的PUSH套接字负载均衡的发送消息到Worker节点。
2、 Sink监听的PULL套接字也是从Worker节点中均等的接收消息。
通信协议
ZMQ提供了进程内、进程间、主机间、广播等四种通信协议。通信协议配置非常简单,用类似于URL形式的字符串指定即可,格式分别为inproc://、ipc://、tcp://、pgm://。ZMQ会自动根据指定的字符串解析出协议、地址、端口号等信息。
4、ZMQ特性总结
4.1使用简单
1、仅仅提供24个API接口,风格类似于BSD Socket。
2、处理了网络异常,包括连接异常中断、重连等。
3、改变TCP基于字节流收发数据的方式,以msg为单位收发数据,结合Protocol Buffers,可以对应用层彻底屏蔽网络通信层。
4、服务器端和客户端的启动没有先后顺序。
4.2灵活
1、支持多种通信协议,可以灵活地适应多种通信环境,包括进程内、进程间、主机间、广播。
2、支持多种消息模型,消息模型之间可以相互组合,形成特定的解决方案。
4.3跨平台
支持Linux、Windows、OS X等。
4.4多语言支持
可以绑定C、C++、Java、.NET、Python等30多种开发语言。