我正在将ZeroMQ作为中型系统的Pub-Sub(服务总线样式)进行测试。
我们大约有50个节点,它们都应该是发布者和订阅者。
网络有点像星形拓扑,但是边缘彼此“交谈”。
我们需要动态发现(无需对参与者的网络地址进行硬编码),也不需要SPOF(单点故障)。
我已经阅读了http://zeromq.org/whitepapers:0mq-3-0-pubsub,据我了解,建议的0MQ动态发现方式涉及一个代理节点(XPUB/XSUB),该节点转发订阅和发布。
我考虑过将这样的代理用作我们系统中的中央中介,但是,我对此体系结构存在以下担忧:
(A)代理节点是SPOF-当它失败时,整个系统将无法运行
(B)所有流量(包括数据)都通过代理节点,这意味着延迟和性能问题。
假设我正确理解pub-sub白皮书,是否有一种相对简单的方法可以在ZeroMQ中实现pub-sub +动态发现+无SPOF?
另外一点:我已经排除了多播(PGM)解决方案,因为大多数消息只有一个/很少的相关方,而且我们不希望网络拥挤。
最佳答案
具有单个发布者的多个订阅者不需要中介,因为订阅者可以直接与发布者对话。但是同时拥有许多发布者和订阅者并不是那么容易。除非中间有问题,否则维护将是一场噩梦,因为新订户必须与所有现有发布者一起配置。
您可以在自己的计算机上部署多个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上读取。
checkout 禁止订阅并最小化网络流量here。