如果 socket.send() 仅使用一次,则 zmq 订阅者无法订阅已发布的消息

A zmq subscriber unable to subscribe to the published messages if socket.send() was used only once

如果 socket.send() 在发布者中 仅使用一次 ,则 zmq 订阅者无法订阅消息。

当在发布者中使用以下代码时,订阅者能够订阅消息:

var zmq = require('zmq')
  , sock = zmq.socket('pub')

sock.bindSync('tcp://127.0.0.1:3000');
var message = {"test" : true};
setInterval(function(){
    sock.send(['notify_anomaly', JSON.stringify(message)]);
},1000);

但是发布者代码中去掉setInterval就不行了,如下:

var zmq = require('zmq')
  , sock = zmq.socket('pub')

sock.bindSync('tcp://127.0.0.1:3000');
var message = {"test" : true};
sock.send(['notify_anomaly', JSON.stringify(message)]);

嗯,不完全是,先生。

历史上,
ZeroMQ 使用 SUB 端订阅(主题过滤)。这意味着两件事。 PUB-lisher 对谁 SUB 做了什么一无所知并且在主题过滤处理上花费了零精力。此外,它倾倒并且必须这样做,所有消息都将发送到所有不同的传输-class 渠道,朝向(仅向下的主题过滤)SUB-抄写员(这主要创建了一些级别传输层资源效率低下)。

因此,如果您的代码使用 "old" ZeroMQ 包装器/语言绑定,那么您的 "PUB-lisher" 毫无疑问,而不是问题的根本原因,因为它的设计并不关心关于任何交易对手,包括 "late-SUBscriber"。时间延迟有帮助(不是 PUB.send(),而是

// unknown SUB code, a default SUB-state is TOPIC-FILTER throws everything, YES !
//                                                       THROWS EVERYTHING AWAY
SUB.setsockopt( zmq.SUBSCRIBE,
                "<some_TOPIC_FILTER_string_to_be_used_after_this_happens_in_time"
                );

所以这与PUB方面的代码本身无关,Q.E.D.,但设计人员必须承担时间- 如果设计稳健的应用程序架构,请牢记巧合。

接下来,
较新的 ZeroMQ 版本已切换到 PUB 端过滤。这似乎是一个重大变化,但它对您的示例没有任何重大影响。

PUB 端过滤刚刚通过 PUB 端的集中式主题过滤消除了传输层拥塞,代价是现在集中在 PUB 侧的(到目前为止便宜的原因分布式)工作负载总和。

所以,您的观察结果仍然显示在 SUB 端没有收到任何消息,那么为什么要深入了解这些细节呢?那么,现在,在较新版本的情况下,如果 SUB 没有设法 "tell & deliver" 它是 SUB-script 首选项 PUB这边,之前已经派出PUB.send( aFirstMESSAGE_to_Those_whom_I_know_they_SUBed_to_this_TOPICFILTER ) 由于分布式系统事件及时传播和传递的 时间巧合 不是 PUB-端(仅)代码调整.

结语:

无论哪种情况,ZeroMQ 都是一个无代理的消息传递框架。这意味着,消息的持久性甚至不打算创建或提供。 Scalable Formal Communication Pattern 的每个行为原型节点在 API-documentation、buffer-management 和 message-{ retain |丢弃 } 和其他规则。一定要检查 ZeroMQ 低级协议的不同版本,它正在分布式系统领域的所有节点上使用(通常无法控制,但可以设计版本感知行为策略实施来处理这种生产生态系统不确定性)。


最佳
下一步
步骤:

If one strives to remain some time in an area of a professional design of distributed systems, the best thing one can do is to read the fabulous book from one of the ZeroMQ fathers, Pieter HINTJENS ( may check other post on ZeroMQ and follow the direct link to the book's PDF-version ).

这是 "slow joiner" 问题的结果。

引用自guide

There is one more important thing to know about PUB-SUB sockets: you do not know precisely when a subscriber starts to get messages. Even if you start a subscriber, wait a while, and then start the publisher, the subscriber will always miss the first messages that the publisher sends. This is because as the subscriber connects to the publisher (something that takes a small but non-zero time), the publisher may already be sending messages out.

基本上,当发布者运行时,它会与订阅者握手。由于这是异步的,发布者可能会在握手完成之前完成发送消息。在那种情况下,订阅者将错过消息。要让订阅者收到第一条消息,发布者需要等待发送,直到确定订阅者已连接。

这里是进一步引用:

In Chapter 2 - Sockets and Patterns we'll explain how to synchronize a publisher and subscribers so that you don't start to publish data until the subscribers really are connected and ready.

它显示了如何使用另一个套接字对使用 REQ-REP 在订阅者准备好在订阅套接字上接收时发出信号 here