没有中介的ZeroMQ Pub-Sub +动态发现

时间:2013-08-20 05:53:49

标签: zeromq publish-subscribe message-bus

我正在测试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)解决方案,因为大多数消息只有一个/几个感兴趣的各方,我们不喜欢过度拥挤网络。

1 个答案:

答案 0 :(得分:8)

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

您可以在自己的计算机上部署多个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会相应地将流量路由到剩余的代理节点;订阅者不会受到影响,因为他们使用所有可用的代理。

慢速订阅者可以通过同步来解决,在this上阅读 查看订阅转发并最大限度地减少网络流量here

enter image description here