跳到主要内容
英文版本为准

本页译自英文,由模型翻译。若与英文原文存在差异,以英文原文为准。

队列

zeromq 客户端不保存消息队列:一次发送把帧写进对端的连接,在途的数据由内核的套接字缓冲区保存。

在两个 zeromq 套接字之间,消息在哪里等待:PUSH/PULL 与 PUB/SUBPUSH/PULLPUB/SUBPUSH 发送选出轮到的那个对端把帧写进该对端的连接内核的套接字缓冲区,两端都有PULL 接收轮流读取各对端的连接PUB 发送发给过滤器匹配的每个订阅者逐一写进每个订阅者的连接内核的套接字缓冲区,两端都有SUB 接收读取过滤器放行的消息zeromq 客户端不保存消息队列:帧写完,一次发送就结束libzmq 则为每个连接保存 1000 条消息(SNDHWM、RCVHWM):到达高水位时 PUB 丢弃,PUSH 阻塞
以文字阅读本图
  1. PUSH/PULL: PUSH 发送 选出轮到的 那个对端; 把帧写进 该对端的 连接; 内核的 套接字缓冲区, 两端都有; PULL 接收 轮流读取各对端 的连接
  2. PUB/SUB: PUB 发送 发给过滤器匹配的 每个订阅者; 逐一写进 每个订阅者的 连接; 内核的 套接字缓冲区, 两端都有; SUB 接收 读取过滤器 放行的消息
  3. PUSH 发送 选出轮到的 那个对端 → 把帧写进 该对端的 连接: 轮流
  4. 把帧写进 该对端的 连接 → 内核的 套接字缓冲区, 两端都有
  5. 内核的 套接字缓冲区, 两端都有 → PULL 接收 轮流读取各对端 的连接
  6. PUB 发送 发给过滤器匹配的 每个订阅者 → 逐一写进 每个订阅者的 连接
  7. 逐一写进 每个订阅者的 连接 → 内核的 套接字缓冲区, 两端都有
  8. 内核的 套接字缓冲区, 两端都有 → SUB 接收 读取过滤器 放行的消息
  9. zeromq 客户端不保存消息队列: 帧写完,一次发送就结束
  10. 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 的源码。