12

我正在测试 ZeroMQ 作为中型系统的 Pub-Sub(服务总线样式)基础设施。我们大约有 50 个节点,它们都应该是发布者和订阅者。网络是一种星型拓扑,但边缘相互“对话”。我们需要动态发现(无需对参与者的网络地址进行硬编码),但也不需要 SPOF(单点故障)。

我已阅读http://zeromq.org/whitepapers:0mq-3-0-pubsub并且据我了解,建议的 0MQ 动态发现方式涉及转发订阅和发布的代理节点 (XPUB/XSUB)。我考虑在我们的系统中使用这样的代理作为中央调解器,但是,我对这种架构有以下担忧:(A)代理节点是 SPOF - 当它失败时,整个系统无法运行(B)所有流量,包括数据,通过代理节点,这意味着延迟和性能问题。

假设我正确理解了 pub-sub 白皮书,是否有一种相对简单的方法可以在 ZeroMQ 中实现 pub-sub + dynamic-discovery + no-SPOF?

附加点:我已经排除了多播(PGM)解决方案,因为大多数消息都有一个/几个感兴趣的方,我们不喜欢过度拥挤网络。

4

1 回答 1

9

具有单个发布者的多个订阅者不需要中介,因为订阅者可以直接与发布者对话。但同时有很多发布者和订阅者并不是那么容易;除非中间有什么东西,否则维护将是一场噩梦,因为新订阅者必须与所有现有发布者一起配置。

您可以部署多个 XSUB/XPUB 代理,每个代理在它们自己的机器上,然后在发布者和代理之间部署一个负载平衡器(如 F5)。这在上游侧实现了负载平衡和容错。

代理代码很简单:

Socket frontend = context.socket(ZMQ.XSUB);
frontend.bind("tcp://proxy1:5444");
Socket backend = context.socket(ZMQ.XPUB);
backend.bind("tcp://proxy1:5555");
frontend.subscribe("".getBytes());
ZMQ.proxy (frontend, backend, null);

如果代理节点出现故障,重启即可;重新连接/订阅应该由 zmq 自动处理。

对于下游订阅者,将每个订阅者直接连接到所有可用代理:

subscriber = ctx.createSocket(ZMQ.SUB)
subscriber.connect( "tcp://proxy1:5555")
subscriber.connect( "tcp://proxy2:5555")
subscriber.connect( "tcp://proxy3:5555")

发布者将比代理更频繁地来来往往,因此将订阅者直接连接到代理会减少配置维护,因为代理的数量在很大程度上是静态的。

如果代理节点发生故障,上游 LTM 会将流量相应地路由到剩余的代理节点;订阅者不会受到影响,因为他们从所有可用的代理中消费。

慢速订阅者可能会通过同步来解决,请阅读内容。在此处
查看订阅转发和最小化网络流量。

在此处输入图像描述

于 2013-08-20T14:22:17.053 回答