简体   繁体   English

ZeroMQ选择性发布/订阅模式?

[英]ZeroMQ selective pub/sub pattern?

I'm trying to design ZeroMQ architecture for N front-end servers and M back-end workers, where front-end servers would send task to back-end ones. 我正在尝试为N个前端服务器和M个后端工作器设计ZeroMQ架构,其中前端服务器会将任务发送到后端服务器。 Front-end servers do have information about back-end ones, but back-end ones do not know about front-end. 前端服务器确实具有有关后端服务器的信息,但是后端服务器不知道有关前端服务器的信息。 I have two types of tasks, one type should use round robin and go to just one back-end server, while other type should be broadcasted to all back-end servers. 我有两种类型的任务,一种类型应该使用轮询,并且仅转到一台后端服务器,而另一种类型应该广播到所有后端服务器。 I don't want to have a central broker, as it would be single point of failure. 我不想有一个中央经纪人,因为这将是单点故障。

For the first type of tasks request/response pattern seems to be the right one, while for the second it would be publisher/subscriber pattern. 对于第一种任务,请求/响应模式似乎是正确的,而对于第二种任务,则是发布者/订阅者模式。 But how about pattern combining the two? 但是如何将两者进行模式组合? Is there any patter that would allow me to select at send time if I want to sent message to all or just one random back-end servers? 如果要向所有或仅一个随机后端服务器发送消息,是否有任何模式可以让我在发送时进行选择?

The solution I've come up with is just use publisher/subscriber and prepend messages with back-end server ID and some magic value if it's addressed to all. 我想出的解决方案是仅使用发布者/订阅者,并在消息前添加后端服务器ID和一些神奇的值(如果寻址到所有人)。 However, this would create lot unnecessary traffic. 但是,这会产生很多不必要的流量。 Is there cleaner and more efficient way to do it? 有没有更清洁,更有效的方法?

I'd probably use pub sub message envelopes - if you're using pub/sub broadcast over UDP I don't believe it will generate unnecessary network traffic but it will incur extra processing however like most of these things it's a trade-off between design elegance and performance. 我可能会使用pub sub邮件信封 -如果您使用的是UDP上的pub / sub广播,我不认为它会产生不必要的网络流量,但是会引起额外的处理,但是像大多数其他情况一样,这是一个折衷方案设计优雅和性能。 ØMQ tends to take the route of performance first, but I'd be inclined to measure it and use quantified performance results to decide if this was acceptable. ØMQ倾向于首先采用性能路线,但我倾向于对其进行衡量,并使用量化的性能结果来确定这是否可以接受。

For me the elegant solution would be to use two sets of sockets because this in itself is differentiating the workflow through the system - whereas using a single socket is mixing things up in a very non ØMQ way, these should be different to allow for future changes and dynamic/unstable systems. 对我来说,一种优雅的解决方案是使用两组套接字,因为这本身就可以区分整个系统的工作流程-而使用单个套接字以一种非常非ØMQ的方式混合事物,则这些套接字应该有所不同以允许将来进行更改和动态/不稳定的系统。

What I see as the only possibility is to use the DEALER-ROUTER combination. 我认为唯一的可能性是使用DEALER-ROUTER组合。 DEALER at the frontend, ROUTER at the backend. 前端为DEALER,后端为ROUTER。 Every frontend server shall contain a DEALER socket for every backend server (for broadcast) and one DEALER socket on top connected to all the backend servers at once for the round-robin thing. 每个前端服务器都应为每个后端服务器(用于广播)包含一个DEALER套接字,并在顶部将一个DEALER套接字一次连接到所有后端服务器,以进行轮询。 Now let me explain why. 现在让我解释一下原因。

  1. You can't really use PUB-SUB in such a critical case, because that pattern can very easily drop messages silently, it does not queue. 在这种紧急情况下,您不能真正使用PUB-SUB,因为该模式可以很容易地以静默方式丢弃消息,并且不会排队。 So in fact the message posted to PUB can arrive to any subset of SUB since it's (dis)connecting in the background. 因此,实际上,发布到PUB的消息可以到达SUB的任何子集,因为它在后台(断开)连接。 For this reason you need to simulate broadcast by looping over DEALER sockets assigned to all the background servers. 因此,您需要通过循环分配给所有后台服务器的DEALER套接字来模拟广播。 It will queue messages if the backend part is not connected, but beware of the HWM. 如果未连接后端部分,但请注意HWM,它将使消息排队。 The only final solution is to use heartbeat to know when a backend is dead and destroy the socket assigned to it. 唯一的最终解决方案是使用心跳来了解后端何时死亡,并销毁分配给它的套接字。
  2. A ROUTER socket at the background is a logical solution since you can asynchronously accept any number of requests and since it's a ROUTER socket it is super easy to send the response back to the frontend that requested the task. 后台的ROUTER套接字是一种逻辑解决方案,因为您可以异步接受任意数量的请求,并且由于它是ROUTER套接字,因此将响应发送回请求任务的前端非常容易。 By having a single ROUTER in the background servers you can make it in a way that they are not even aware of the fact that there is a broadcast happening, they see everything as a direct request to them. 通过在后台服务器中使用一个ROUTER,您可以使他们甚至不知道发生广播的事实,从而将一切视为对他们的直接请求。 Broadcasting is purely a frontend thing. 广播纯粹是前端的事情。 The only issue with this solution might be that if your backend server is not fast enough, all the frontend servers may fill it up so that it reaches the HWM and starts dropping the packages. 此解决方案的唯一问题可能是,如果您的后端服务器不够快,则所有前端服务器可能会填满它,以使其到达HWM并开始丢弃程序包。 You can prevent this by having more threads/processes processing the messages from the ROUTER socket. 您可以通过让更多线程/进程处理ROUTER套接字中的消息来防止此情况。 zmq_proxy() is a useful function for this stuff. zmq_proxy()是此功能有用的功能。

Hope this helps ;-) 希望这可以帮助 ;-)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM