首先,欢迎来到Zen-of-Zero的世界,延迟最为重要。
序言:
ZeroMQ由Pieter HINTJENS团队设计,其中最有经验的大师Martin SUSTRIK被命名为第一位。该设计专业精良,以避免任何不必要的延迟。因此,问及是否具有(有限的)持久性?不,先生,未经确认的“PUB/SUB可扩展正式通信模式原型”将不会内置它,因为这会增加问题并降低性能和可伸缩性(添加延迟,处理和内存管理)。
如果需要(有限的)持久性(用于不存在远程SUB端代理的连接),请随意在应用程序端实现它,或者可以设计并实现一个新的符合ZMTP标准的行为模式原型,扩展ZeroMQ框架,如果这项工作进入稳定和公开接受的状态,但不要请求高性能,削减延迟的标准PUB/SUB朝这个方向进行修改。这绝对不是正确的做法。
解决方案?
使用双指针循环缓冲区,工作在一种类似于Persistence-PROXY
的(app-side-managed)模式下,App端可以轻松实现您添加的逻辑,但位于PUB
发送方之前。
如果您的设计还喜欢使用最近提供的内置ZeroMQ-socket_monitor
组件来设置额外的控制层并在那里接收事件流,则您的设计可能会成功地从ZeroMQ内部细节中挤出一些额外的内容。这些与网络和连接管理相关的事件可以为您的(app-side-managed)-Persistence-PROXY带来更多的启示。
然而,请注意:
_zmq_socket_monitor()_
方法仅支持面向连接的传输,即TCP、IPC和TIPC。
所以如果计划使用最终有趣的传输类之一,就可以直接忘记这个
{ inproc:// | norm:// | pgm:// | epgm:// | vmci:// }
。
注意!
我们的社区荣誉成员smac89提供的信息存在不准确、甚至错误的部分,他尽力回答了您在评论中表达的额外兴趣:
"...zmq 优化了主题发布吗?比如如果你快速地在一些 100 字符长的 topic
上发布,它实际上是每次都发送 topic
吗,还是将其映射到某个 int 并随后发送 int...?"
他告诉你:
"它将始终发布topic。
当我使用pub-sub
模式时,我通常先发布topic
,然后再发布实际消息,所以在订阅者中,我只需读取第一帧并忽略它,然后读取实际消息"
ZeroMQ 不是这样工作的。没有“单独”的<topic>
,后面跟着一个<message-body>
,相反是相反的
TOPIC
和主题过滤的机械化工作方式非常不同。
1) 你永远不知道,谁会调用 .connect()
:
例如,可以几乎确定版本2.x到版本4.2+将以不同的方式处理主题过滤(ZMTP:RFC定义了初始能力版本握手,让Context
-实例决定使用哪个版本的主题过滤:
ver 2.x 通常将所有消息移动到所有对等方,并让所有SUB-side(来自ver 2.x+)接收消息(并让SUB-side Context-实例处理本地topic
列表过滤处理)
而
ver 4.2+ 确定在**PUB-side Context
-实例上执行topic
-列表过滤处理(CPU使用率增加,网络传输相反),因此您的SUB-side将永远不会收到任何“无用”的字节读作“未订阅”消息。
2) (你可以这样做,但是)没有必要将“主题”分成因此暗示的多帧消息的第一帧。也许恰恰相反(在高性能、低延迟的分布式系统设计中这样做是一种反模式)。
主题过滤过程被定义为逐字节工作,从左到右,对于主题列表成员值,进行与传递的消息有效负载的每个模式匹配。
添加额外数据,额外的帧管理处理只会增加端到端的延迟和处理开销。这不是一个好主意,而是应该进行适当的分布式系统设计工作。
结语:
在专业的分布式系统设计中,没有容易的胜利,也没有低垂的果实,特别是当低延迟或超低延迟是设计目标时。
另一方面,确保ZeroMQ框架考虑到了这一点,并且这些努力得到了稳定、终极性能良好、平衡的一套工具,用于智能(按设计)、快速(运行)和可扩展(魔鬼也会羡慕)的信令/消息服务,人们喜欢使用它们,正因为这种设计智慧。
希望您享受ZeroMQ的使用,并随意在您选择的应用程序套件内添加任何额外的功能“前端”。
socket.monitor
并监听ZMQ_EVENT_DISCONNECTED
事件吗? - smac89zeromq
HWM docs,它说:“当您的套接字达到其HWM时,它将根据套接字类型阻止或丢弃数据。PUB和ROUTER套接字如果达到其HWM,则会丢弃数据,而其他套接字类型则会阻塞。在inproc传输中,发送方和接收方共享相同的缓冲区,因此真正的HWM是由双方设置的HWM之和。”所以我的问题是,您是否正在寻找一个外部内存缓冲区作为解决方案?除了我的建议之外,使用大HWM是唯一的解决方案。 - smac89