如何识别没有订阅者的节点? (零MQ)

Posted

技术标签:

【中文标题】如何识别没有订阅者的节点? (零MQ)【英文标题】:How to identify a node that has no subscriber? (ZeroMQ) 【发布时间】:2019-07-16 13:01:39 【问题描述】:

我目前正在 CZMQ(ZeroMQ 的高级 C 绑定)中设计消息代理。我的代理设计有点像典型的星型拓扑,但有额外的REP-sockets 来与发布者和订阅者通信。我还有一个PUB-socket 来通知发布者订阅者。

当一个节点连接到代理时,它必须通过这个REP-socket 进行握手,然后该节点被添加到服务器的内部列表中。我的节点结构如下所示:

struct node 
    int type;
    char *uuid;
    char *path;
    size_t path_len;
    int64_t timestamp;
; 

path 变量是发布者/订阅者正在使用的订阅路径,例如/path/to/subscription

我保留了两个不同的内部列表,一个用于发布者,一个用于订阅者。我想设计它,以便当发布者没有订阅者时,服务器会通知该发布者,以便它可以停止发送消息,直到另一个订阅者订阅该发布者。

我遇到的问题是我不知道如何确定发布者是否没有订阅者,例如假设发布者发布到/path/to/data,然后我需要查找是否有任何订阅者订阅了/path/path/to/path/to/data

此网络中的每个节点都有一个唯一的 ID,即uuid。每个发布者都有一个SUB-socket 订阅它自己的uuid,以便它可以从服务器接收更新。

【问题讨论】:

【参考方案1】:

几个选项:

Alt.1) 创建您自己的显式订阅管理层,独立于标准PUB/SUB Scalable Formal Communication Behavior Archetype Pattern。在那里,您可以实现您的设计想要拥有的任何功能。

Alt.2) 使用标准的XPUB/XSUB Archetype,其中包含订阅和取消订阅消息。然而,这些是弱类型的信号,可能会错过或从未打算接收此类消息,因此您的处理策略必须足够稳健,以免在未呈现弱信号消息时遇到麻烦。

ZMQ_XPUB

ZMQ_PUB 相同,只是您可以以传入消息的形式接收来自对等方的订阅。订阅消息是字节1(用于订阅)或字节0(用于取消订阅)后跟订阅正文。不带 sub/unsub 前缀的消息也会被接收,但不会影响订阅状态。

ZMQ_XSUB

ZMQ_SUB 相同,只是您通过发送订阅消息到套接字进行订阅。订阅消息是字节1(用于订阅)或字节0(用于取消订阅)后跟订阅正文。也可以发送没有 sub/unsub 前缀的消息,但不会影响订阅状态。

最后但同样重要的是,不必担心没有SUB-s 存在,因为 Context()-instances 的内部数据泵管理非常了解连接的状态并且不会在SUB-s 的空列表。如果使用.setsockopt( ZMQ_CONFLATE, 1 ) 方法,则为SUB-s 的队列存储容量管理本地分配的资源将仅在本地队列头端存储中为每个几乎“活”-SUB

很可爱,不是吗?

【讨论】:

我倾向于选项 2,但我不太了解订阅/取消订阅的订阅消息。这是 ZeroMQ 在后台处理的事情,还是我必须手动发送此类请求? 是的,显式发送是利用 XPUB/XSUB 原型来完成您设置的任务的方法。阅读发送端的多部分消息组合和接收端的分解,你会喜欢的。测试第一部分内容大小 ( 1B ) 和值 0|1 是相当便宜的成本,可以从所有这些智能且可重复使用的机制中获益,不是吗? 我读了一些关于多部分消息的内容,现在我理解了这个概念。我在 CZMQ 中做了一个最小的例子,一个使用 zproxyXSUBXPUB 套接字的服务器和一个捕获套接字,以便我可以看到来自服务器的内容,以及一个在 @987654341 上发送的非常简单的客户端@套接字并在SUB套接字上接收,如果我在PUB套接字上发送消息之前启动SUB套接字,这一切都很好,如果我先启动PUB套接字并发送信息。这是因为慢连接综合症吗?如果是这样,有没有一种干净的方法来解决它? 我弄清楚了为什么会发生这种情况,并通过在开始发送数据之前在PUB 套接字上使用 rep-req 同步握手来解决它。感谢大家的帮助!

以上是关于如何识别没有订阅者的节点? (零MQ)的主要内容,如果未能解决你的问题,请参考以下文章

MQ的订阅模式

带有 Active-MQ 的 Mule 发布/订阅模型。如何在 Active-MQ JMS 中的消息到达时以异步方式调用 tomcat-consumers

MQ和redis对比

Stripe - 当我使用零计划更新订阅时,PaymentIntent 为空

理解JAVA MQ消息中间件

redis发布订阅模式