ZeroMQ总结
2014-03-18 16:48 DVwei 阅读(9594) 评论(0) 编辑 收藏 举报Socket types
Thread safety: ZeroMQ的socket是非线程安全的,并且ZeroMQ本身不建议在多个线程中传递同一个Socket,即使保证了线程同步。
Socket types: ZeroMQ一共具有12种类型的socket,5种消息模式。
- 请求/应答模式:ZMQ_REQ、ZMQ_REP、ZMQ_DEALER、ZMQ_ROUTER
- 发布/订阅模式:ZMQ_PUB、ZMQ_SUB、ZMQ_XPUB、ZMQ_XSUB
- 管道模式:ZMQ_PUSH、ZMQ_PULL
- 配对模式:ZMQ_PAIR
- 本地模式:ZMQ_STREAM
目前只用到前两种模式,此文档暂时只阐述前两种。
请求/应答模式
ZMQ_REQ
一般用于客户端发送请求消息,此类型的socket必须严格遵循先发送后接收的顺序,即:
如果发生异常或者当前没有可用的服务(连接),socket会阻塞,直到有可用的服务(新连接到来),再把消息发送出去。REQ类型的socket不会丢弃消息。
ZMQ_REP发送消息时会自动在消息顶部插入一个空帧。
特点总结:
- 可兼容的Socket types: ZMQ_REP, ZMQ_ROUTER
- 数据传输: 双向
- 发送/接收模式: 发送à接收à发送…
- 发送路由策略: Round-robin(循环队列)
- 接收路由策略: Last peer
- 进入mute状态后: 阻塞
ZMQ_REP
一般用于服务端接收消息,此类型的socket必须严格遵循先接收后发送的顺序,即:
从客户端接收请求消息使用了公平队列,回应客户端时,所有的reply都会被路由到最后下达请求的客户端。
如果发生异常或者当前没有可用的客户端连接,所有消息都会毫无提示的被丢弃,不会发生阻塞。
特点总结:
- 可兼容的Socket types: ZMQ_REQ, ZMQ_DEALER
- 数据传输: 双向
- 发送/接收模式: 接收à发送à接收…
- 发送路由策略: Last peer
- 接收路由策略: Fair-queued(公平队列)
ZMQ_DEALER
DEALER是一种用于请求/答应模式的更高级的扩展Socket,它可以自由的收发消息,没有ZMQ_REP/ZMQ_REQ那样的限制。
对于每一个连接,接收消息也是使用了公平队列,发送使用了循环队列(RR)。
如果当前没有有效的连接,zmq_send操作也会阻塞,直到有新的连接到来为止。
注意:如果ZMQ_DEALER连接到ZMQ_REP,每一个消息包必须包含一个空帧,然后再紧跟着数据包体。
ZMQ_ROUTER
ZMQ_ROUTER是一种用于请求/答应模式的更高级的扩展Socket,它可以自由的收发消息。
当ZMQ_ROUTER接收到消息时,会自动在消息顶部加入来源地址标识符,接收消息使用了公平队列。当发送消息时,ZMQ_ROUTER又会自动去掉这个标识符,并且根据这个标识符路由到相应的端点。
如果此地址标识的端点不存在,默认会毫无征兆的丢弃消息,除非将ZMQ_ROUTER_MANDATORY 选项设置为1。
当队列达到阀值时,Socket就会进入mute状态,此时所有后续发送到此Socket的消息都会被丢弃,直到mute状态结束。同样的,如果对端的接收队列达到了阀值,消息也会被丢弃。
如果ZMQ_REQ连接到ZMQ_ROUTER,从ZMQ_ROUTER接收到ZMQ_REQ的消息时,除了会在消息前加上来源地址标识符之外,还会加上一个空帧与原消息分隔,即:
发送消息时,ZMQ_ROUTER会根据第一个地址标识符路由到对应的端点;
发布/订阅模式
ZMQ_PUB
ZMQ_PUB类型的Socket以发布者的身份向订阅者分发消息,消息以扇出的形式发送给所有订阅者连接。
ZMQ_PUB类型的Socket没有实现zmq_recv函数,所以不能对其调用zmq_recv函数!
当ZMQ_PUB Socket达到阀值时进入mute状态,此时后续发送的消息会被丢弃,知道mute状态结束。
对ZMQ_PUB Socket调用zmq_send永远不会发生阻塞。
ZMQ_SUB
ZMQ_SUB类型的Socket以订阅者的身份接收消息。初始的ZMQ_SUB Socket没有订阅任何消息,可以通过设置ZMQ_SUBSRIBE选项来指定需要订阅的消息。
ZMQ_SUB Socket没有实现zmq_send函数,所以不能对其调用zmq_send函数!
Socket options(部分)
概要:通过zmq_setsockopt和zmq_getsockopt函数来设置/读取指定选项。
ZMQ_SNDHWM
设置指定Socket的发送消息队列的高水位标识(阀值),ZMQ会严格限制发送队列的上限数。0表示无限制。
如果达到了这个限制,socket就会进入异常状态,ZMQ此时会采取适当的措施——阻塞或丢弃消息,这取决于socket的类型。
Note: ZMQ不保证socket一定能接受ZMQ_SNDHWM这么多的消息,甚至可能会低60%-70%,这取决于socket上的信息流。
ZMQ_RCVHWM
设置指定Socket的接受消息队列的高水位标识(阀值),ZMQ会严格限制接受队列的上限数。0表示无限制。
如果达到了这个限制,socket就会进入异常状态,ZMQ此时会采取适当的措施——阻塞或丢弃消息,这取决于socket的类型。
ZMQ_SUBSCRIBE
ZMQ_SUBSCRIBE选项会在ZMQ_SUB Socket上建立一个消息过滤器。初始的ZMQ_SUB Socket会过滤掉所有的消息,因此必须设置这个选项,否则将收不到任何消息。
ZMQ_UNSUBSCRIBE
此选项用来删除ZMQ_SUB Socket上通过ZMQ_SUBSCRIBE设置过的消息过滤器。如果Socket有多个实例有相同的过滤器,只删除其中一个。
ZMQ_IDENTITY
此选项用来设置Socket的身份标识,只能用于请求/答应模式。ROUTER Socket可以根据这个身份标识来路由信息。
身份标识的长度规定在1-255 bytes. 由二进制零开头的标识符为ZMQ保留使用。
如果两个身份标识相同的Socket连接到同一个对端(ROUTER),结果行为是未定义的。
ZMQ_RCVTIMEO
如果为0,则zmq_recv会立即返回,如果没有接收到消息,会返回一个EAGAIN错误;
如果为其他值,Socket要么阻塞达到指定的时间还没接收到可用的消息,返回一个EAGAIN错误,要么在指定时间前接收到可用消息。
ZMQ_SNDTIMEO
如果为0,则zmq_send会立即返回,如果消息没有发送成功,会返回一个EAGAIN错误;
如果为其他值,Socket要么阻塞达到指定的时间还没发送完成,返回一个EAGAIN错误,要么在指定时间前发送完消息。