我正在研究分布式应用程序。网络基于ZMQ(jeromq),这是我的架构:
N Clients (Dealer socket) <---> (Router) Proxy (Dealer) <---> 1 (Dealer) Reciving Worker
<---> N (Dealer) Processing Workers
- 所以我的接收工作线程在一个单独的线程中运行,监听消息并将它们放入队列中。
- 处理工作线程从队列中选取消息,进行一些处理并将其发送回客户端(处理工作线程连接到代理后端)
当客户端发送一条消息时,它被接收工作线程接收,放入队列中,处理工作线程将其拾取并进行一些处理并将其发回,客户端收到响应后发送另一个请求,即接收工作人员未收到请求,但该请求是由客户端发送的。基本上只有第一“轮”有效。我在这里缺少什么?!
最佳答案
您缺少的是经销商套接字以循环方式向任何连接的客户端发送消息。结果是您的架构无法按您预期的方式工作。
首先,我将为您的预期架构编写一个更准确的图表(目前,我忽略套接字类型):
Client <-----> Broker ------> Receiver
^ |
| |
\ v
---------- Processor
当您发送第一条消息时,它会被发送到接收方 - 因为它是队列中第一个连接的套接字。当您发送第二消息时,代理上的DEALER
套接字将以循环方式发送到队列中的下一个套接字,这是第一个处理器。基本上,问题是您的代理无法区分您的“接收器”套接字和“处理器”套接字,它将它们视为同一事物。
有几种方法可以解决这个问题。首先,您可能并不真正需要“接收器”套接字作为中间人,您可能能够在代理和处理工作人员之间直接来回通信。我建议首先这样做,因为这通常是这些类型的架构的工作方式。
您还可以向代理添加另一个套接字,让一个套接字发送到接收器,另一个套接字从处理器接收。
或者,您可以将代理上的 DEALER
套接字替换为另一个 ROUTER
套接字,这将允许您每次都直接寻址接收者套接字。
跟进,解决评论中的问题:
每个工作人员都有不同的职责,这是用 ROUTER
套接字替换代理上的 DEALER
套接字的充分理由。
我的现成建议是围绕 the Majordomo Protocol 重新构建架构(更高版本可以找到 here ,并在 ZMQ 指南 here, with Java code samples 中讨论)。它完全符合您的要求,而且做得很好。
但是,在更简单的层面上,您将执行以下操作:
- 启动您的代理,在前端和后端都使用
ROUTER
套接字 - 这两个套接字都是bind()
-ed。 - 加快您的工作人员的步伐。每个 worker 都知道自己的责任。删除“接收器”,我们不会使用它。
connect()
你的工作人员就是你的经纪人。- 每个工作人员都会向代理发送一条消息,告诉代理该工作人员负责什么。经纪人通过 ID 记录每个 worker 以及该 worker 负责的工作。
- 当代理想要发送特定作业时,它会查找负责该作业的工作人员,并将作业发送给它。
- 如果工作线程立即可用,它将对其进行处理,否则它将保留该作业,直到准备好处理它为止。
- 工作线程完成后,会将作业发回并继续处理新作业(如果有)。
所有这些都是 Majordomo 协议(protocol)所实现的,再加上心跳等其他必要元素,构成了一个完全充实的 ZMQ 应用程序。这就是为什么我建议您直接使用该协议(protocol)(如果它满足您想要实现的需求),而不是尝试构建自己的协议(protocol)。
关于java - 路由器/经销商代理不传送消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34938886/