【问题标题】:ZMQ socket - disconnect when all request are servedZMQ 套接字 - 处理完所有请求后断开连接
【发布时间】:2017-10-30 07:49:45
【问题描述】:

我正在尝试用 Java 实现 ZMQ REQ/REP 模型

我有一个服务器-角色,在 5564 后运行,它充当回复者

ZMQ.Socket repSock = context.socket(ZMQ.REP);

我有一个客户-角色,在 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 的方法


我需要以下两件事中的任何一件:

  1. 一种跟踪Socket-instance 的方法,我将要断开连接,等待所有消息都处理完毕,这样syncclient.recvStr() 就不会被阻止

  2. 一种重置syncclient-socket 的方法,这样我就可以不断收到REQ/REP 响应而不会中断

【问题讨论】:

    标签: sockets zeromq jzmq


    【解决方案1】:

    在实际场景中,避免使用 ZeroMQ .send() / .recv() 方法的阻塞模式,而最好使用 .poll()

    虽然这可能需要更多 SLOC 的代码,但结果会让您处于控制状态,而阻塞的 SLOC 会从您的代码中获取所有控制权,在(如果有的话)下一条消息之前,您无能为力交付。这是一种非常错误的设计实践,除了最简单的教科书示例之外,这实际上是现实世界的反模式。

    所以,不要指望 问题 2 会以某种方式神奇地解决,这不是 ZeroMQ API 的一部分(出于许多相当大声宣传的原因)。如果 API 版本和使用环境允许,最好在 .setsockopt( ZMQ.REQ_RELAXED, 1 ) 之间做出决定,或者根本不使用琐碎的 REQ/REP 模式(因为它已知有陷入一个无法挽救的相互僵局(参考我在这个主题上的其他帖子,其中对这种现象进行了说明和无数次解释)。

    以类似的方式,如果您从未阅读过 ZeroMQ 规范和/或文档以及 ZeroMQ“最佳实践”,那么问 问题 1 似乎是合理的。在此花费了一些时间后,您的选择将一目了然。没有这样的内置工具可以做到这一点。如果需要为她/他自己的需要添加任何类似的非核心逻辑,可以添加一些附加组件。 .setsockopt( ZMQ.LINGER, 0 ) 中提供了唯一间接影响aSocket.close() 行为的设置,这可能有助于防止系统转换到有效的挂起状态,一旦aSocket 无限等待在消息队列仍然非空(消息仍在等待传递)的情况下永远不会发生的状态。

    进入分布式系统设计就像进入一个新世界。不保证任何序列(发生非串行代码执行路径)。无法对远程实体、它们的状态、它们的故障、它们的存在、它们的实际 ZeroMQ API 版本进行任何本地控制。

    确实是一个充满挑战的世界。

    注意:
    您可能已经知道,一个人可以在不使用代理的情况下将.connect()aSocket-instance(最好是aSocket-instance 的接入点)连接到多个远程端。将一些额外的.setsockopt() 调整为 ZMQ.IMMEDIATE 值为 1,将有助于更好地管理循环分发策略,而不管用于实际消息传递的传输类 ({ tcp:// | ipc:// | vmci:// | pgm:// | epgm:// | inproc:// } )。所有这些都触手可及。

    【讨论】:

      猜你喜欢
      • 2012-08-27
      • 2019-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-05
      • 2018-11-26
      • 1970-01-01
      相关资源
      最近更新 更多