英文版本为准
本页译自英文,由模型翻译。若与英文原文存在差异,以英文原文为准。
队列
zeromq 客户端不保存消息队列:一次发送把帧写进对端的连接,在途的数据由内核的套接字缓冲区保存。
以文字阅读本图
- PUSH/PULL: PUSH 发送 选出轮到的 那个对端; 把帧写进 该对端的 连接; 内核的 套接字缓冲区, 两端都有; PULL 接收 轮流读取各对端 的连接
- PUB/SUB: PUB 发送 发给过滤器匹配的 每个订阅者; 逐一写进 每个订阅者的 连接; 内核的 套接字缓冲区, 两端都有; SUB 接收 读取过滤器 放行的消息
- PUSH 发送 选出轮到的 那个对端 → 把帧写进 该对端的 连接: 轮流
- 把帧写进 该对端的 连接 → 内核的 套接字缓冲区, 两端都有
- 内核的 套接字缓冲区, 两端都有 → PULL 接收 轮流读取各对端 的连接
- PUB 发送 发给过滤器匹配的 每个订阅者 → 逐一写进 每个订阅者的 连接
- 逐一写进 每个订阅者的 连接 → 内核的 套接字缓冲区, 两端都有
- 内核的 套接字缓冲区, 两端都有 → SUB 接收 读取过滤器 放行的消息
- zeromq 客户端不保存消息队列: 帧写完,一次发送就结束
- libzmq 则为每个连接保存 1000 条消息 (SNDHWM、RCVHWM):到达高水位时 PUB 丢弃,PUSH 阻塞
PUSH 发送选出下一个轮到的对端,把帧写进该对端的连接。帧写完,发送才结束,因此读得慢的对端会让发送等待。
PULL 套接字在被要求取一条消息时,轮流从每个已连接的对端读取一条。在此之前,帧留在内核的缓冲区里,本端和发送端都有。
PUB 发送把消息逐一写进每个过滤器匹配的订阅者的连接。因此最慢的那个匹配订阅者会拖住发布者,但慢的订阅者也不会丢失消息。不匹配任何过滤器的消息会被丢弃,不报告错误。
libzmq 是其他大多数语言使用的 C 库,它的做法不同。在那里每个连接有自己的队列,默认 1000 条消息(高水位 SNDHWM 和 RCVHWM)。队列满时,PUB 丢弃消息,PUSH 阻塞发送。zeromq 客户端把一次发送直接写进连接,套接字的选项只有对端身份和连接超时。
限制本 crate 的订阅预读多远的,是 crate 自己的通道,深度为 read_ahead,背压一页画出了它。
libzmq 的数字来自 zguide(「High-Water Marks」一节)。客户端的行为依据 zeromq 0.6 的源码。