我正在尝试在Java中实现ZMQ REQ/REP
模型
我有一个服务器 -role,在帖子5564上运行,作为Replier
ZMQ.Socket repSock = context.socket(ZMQ.REP);
我有一个客户端 -role,在帖子5563上运行
ZMQ.Socket syncclient = context.socket(ZMQ.REQ);
我在中间有一个代理 - 服务器,它传递请求和响应
ZMQ.proxy(reqSocket, repSocket, null);
拥有代理的好处是我可以添加多个服务器
repSocket.connect("tcp://" + addr.getHostAddress() + ":" + port);
哪种方法正常。
现在,当我从代理
中删除服务器节点时repSocket.disconnect("tcp://" + addr.getHostAddress() + ":" + port);
客户端被卡住了,因为已经发出请求并且 REQ
-socket等待响应。
因此,流程停留在 syncclient.recvStr()
for (int request_nbr = 0; request_nbr < (request_nbr + 1); request_nbr++) {
syncclient.send(str.getBytes(),0);
System.out.println("Send Dataaaa....... " );
String data = syncclient.recvStr(Charset.defaultCharset());
System.out.println(" here.. " +data);
request_nbr++;
}
我搜索过,无法找到跟踪REQ
- 套接字
跟踪我即将断开连接的Socket
- 实例的方法,等待所有邮件都被处理,以便syncclient.recvStr()
不会被阻止
重置syncclient
- 套接字的方法,以便我可以不间断地响应REQ/REP
答案 0 :(得分:1)
在实际场景中,请避免使用ZeroMQ .send()
/ .recv()
方法的阻止模式,并更好地使用.poll()
。
虽然这可能需要更多SLOC代码,但结果会让您处于控制之中,而阻塞SLOC会从您的代码中获取所有控制权,并且在(如果有的话)下一条消息之前您无法做很多事情交付。这是一个非常错误的设计实践,除了最简单的教科书例子,它实际上是对现实世界的反模式。
所以,不要指望问题2 以某种方式神奇地解决,这不是ZeroMQ API的一部分(对于许多相当大声传播的原因)。如果API版本和使用环境允许,或者根本不使用简单的 .setsockopt( ZMQ.REQ_RELAXED, 1 )
模式,则可以更好地在 REQ/REP
之间做出决定(因为它已知)陷入无法挽回的共同死锁的风险(参考我关于这个问题的其他帖子,这种现象既有说明也有无数次解释)。)
以类似的方式,在您从未阅读过ZeroMQ规范和/或文档以及ZeroMQ“最佳实践”的情况下,询问问题1 似乎是合理的。花了一些时间在这里,你的选择将是清晰的。没有这样的工具可以用来做这个内置的。如果需要为她/他自己的需要添加任何类似的非核心逻辑,可以添加一些附加组件。唯一可以间接影响aSocket.close()
行为的设置可在 .setsockopt( ZMQ.LINGER, 0 )
中找到,这有助于防止系统过渡到有效的挂断状态,一次{{ 1}}无限期地等待一个在情况下永远不会发生的状态,当消息队列仍然是非空的时候(消息仍在等待传递)。
进入分布式系统设计就像进入一个新世界。没有保证序列(非串行代码执行路径发生)。没有任何本地控制远程实体,它们的状态,它们的失败,它们的存在,它们的实际ZeroMQ API版本。
确实是一个充满挑战的世界。
<强> N.b:强>
您可能已经知道,在不使用代理的情况下,可以aSocket
.connect()
- 实例(更好的aSocket
- 实例的访问点)到多个远程端。通过一些额外的aSocket
调整 .setsockopt()
到值1,将有助于更好地管理循环分配策略,而不管用于实际消息传递的传输类(ZMQ.IMMEDIATE
)。一切都在你的指尖。