用于可靠多播的zmq模式

时间:2014-05-29 17:20:00

标签: c replication zeromq

我正在努力研究如何使用zmq来实现我需要的架构。我有一个经典的发布/订阅情况,除了一旦客户端x订阅了一个主题,我需要将主题数据发送给它,如果客户端在重新连接时死亡并重新发送则将其缓存。数据顺序很重要,如果客户端暂停一段时间,我就不会错过消息。

PUB / SUB模式似乎并不了解个别客户端,如果它死了就会停止发送给客户端x。另外,我无法发现这种情况已经发生并缓存消息,或者知道何时重新连接。

为了试图解决这个问题,我使用了REQ / REP模式,因此客户可以宣布自己并有一些持久性,但由于以下几个原因,这并不理想:

1)客户必须不断询问"为我获取任何数据?"这会冒犯我的感情

2)如果没有数据要发送到客户端x但是客户端y会发生什么?如果没有zmq,我每个客户端都有一个线程,只是阻止没有数据的线程,但是我不能阻止客户端x而不会在单个线程中阻塞客户端y。

我试图在方孔中推一个圆钉,在这里?有什么方法我可以从PUB获得反馈说“未能发送给客户x&#39 ;?所以我可以缓存消息呢?或者我应该使用其他一些模式吗?

否则我会回到低级别的tcp ...

非常感谢;

杰里米

3 个答案:

答案 0 :(得分:1)

这是一个积极研究的领域。

我目前正在做类似的事情。我们的解决方案是拥有一个TCP“反向通道”,可以在其上接收错过的数据,并让订阅者知道最后成功收到的出版物是什么,这样当他们重新连接时,他们可以要求提供自那个以来的出版物。

答案 1 :(得分:1)

在某种意义上,你试图在方孔中推一个圆钉。您已经选择了工具 - PUB / SUB - 并且正在尝试解决它不能解决的问题,至少在没有其他设计的情况下是这样。

PUB / SUB是一个不可靠的广播。客户端可能会错过消息,原因如下:

  • 订阅者加入时间较晚,因此他们会错过服务器已发送的邮件。
  • 订阅者可以过慢地获取邮件,因此队列会累积然后溢出。
  • 订阅者可以在他们离开时丢失并丢失消息。
  • 订阅者可能会崩溃并重新启动,并丢失他们已收到的任何数据。
  • 等...

对于REQ / RSP,客户端不必经常询问"为我获取任何数据?"而是客户端应该确认每个数据,以便服务器可以在下次发送正确的数据。如果服务器没有任何东西可以发送,那就完全了。 例如

client               server
Hello ---------------->
                     (wait until something exist to send)
<-------------------- Msg 1
Ack 1 ---------------->
                     (wait ...)
<-------------------- Msg 2
                      ...

有很多好的方法可以用zmq做你想做的事。首先,您应该尝试设计您的协议。连接时会发生什么?我应该收到任何旧消息吗?如果是这样,多大了?如果我在连接时错过了一条消息,我能不能得到它?如果客户端重新启动,我是否应该收到任何旧消息?

我强烈推荐非常好的zmq指南http://zguide.zeromq.org/page:all,它有很多关于在协议中获得可靠性的不同方法的非常好的信息。阅读完整指南,包括第4章和第5章,讨论获得可靠运输的不同技术。根据您的问题讨论:第5章似乎是一个良好的开端。试试一些例子。然后设计你的协议。

答案 2 :(得分:0)

添加Archiver进程怎么样?客户的订阅过程的一部分也是通知Archiver开始存档相同的订阅。 Archiver会将收到的所有消息保存在有序列表中。

客户端将记录他们收到的上次发布消息的时间或ID。当他们在崩溃后开始工作时,他们会首先联系Archiver,然后说出#34;从X&#34;开始给我所有的消息。他们会重新订阅发布者。当客户端从发布者和Archiver收到相同的消息时,它会告诉Archiver停止重播。

Archiver可以清除早于离线客户端最大预期停机时间的消息。或者,客户可以定期办理登机手续说“我最新消息Y&#34;”,允许清除所有旧项目。