Java Netty.WriteAndFuture成功杀死主机

Java Netty.WriteAndFuture成功杀死主机,java,network-programming,netty,Java,Network Programming,Netty,我们有一个基于Netty(4.0.15)的Websocket服务器,运行在Ubuntu v10上,在弹性测试期间,我们会: kill-9服务器 从客户端发送一些数据 在客户端上预期writeAndFlush失败 由于某些原因,有时我们会看到: 写下丰盛的成功,然后 java.io.IOException:对等方重置连接 因此,有时即使服务器不在,writeAndFlush也会成功完成,而其他时候会失败,这是不是可能的 这可能是因为被终止进程的操作系统套接字清理机制的时间表造成的 客户端测试代码:

我们有一个基于Netty(4.0.15)的Websocket服务器,运行在Ubuntu v10上,在弹性测试期间,我们会:

  • kill-9服务器
  • 从客户端发送一些数据
  • 在客户端上预期writeAndFlush失败
  • 由于某些原因,有时我们会看到:

  • 写下丰盛的成功,然后
  • java.io.IOException:对等方重置连接
  • 因此,有时即使服务器不在,writeAndFlush也会成功完成,而其他时候会失败,这是不是可能的

    这可能是因为被终止进程的操作系统套接字清理机制的时间表造成的

    客户端测试代码:

        channel.writeAndFlush(new TextWebSocketFrame("blah blah")).addListeners(
        <snip>
                public void operationComplete(ChannelFuture future) {
                    assert future.isSuccess() == false;  <-- sometimes this is not triggered
                }
        </snip>
    
    channel.writeAndFlush(新的TextWebSocketFrame(“废话”)).addListeners(
    公共无效操作完成(通道未来){
    
    assert future.issucess()==false;这是一个简单的竞争条件,您必须接受的情况可能会发生。您只能通过不从远程主机接收数据来确定远程主机已消失。通常,这是通过设置计时器并假设未接收到数据(可能是响应保持活动消息)来实现的远程主机已死亡

    从本质上说,如果远程主机尝试在没有收到确认的情况下重新传输某些数据一定次数,或者没有收到保持活动状态的响应(默认情况下通常为关闭),则TCP假定远程主机已死亡。但是,假设主机的发送缓冲区中有空间,您可以继续成功调用writeAndFlush,因为它将在网络缓冲区中排队。一旦Netty将数据写入内核发送缓冲区,writeAndFlush将被视为已成功。无法确定数据是否已到达远程主机t应用程序级确认。因此,您可能在TCP确定远程主机已死亡时调用writeAndFlush,因此writeAndFlush成功,但数据未发送。或者,您也可以在TCP确定远程主机已死亡并因此引发错误的同时调用writeAndFlush


    关于TCP重新传输和保持活动状态有更多信息,这听起来像是操作系统级套接字清理问题。但是,将套接字选项设置为保持活动状态可能会降低发生这种情况的可能性(即改进死套接字检测)。试一试。@brettw谢谢,我们可以解决这个问题,只需要解释一下为什么会发生。同时,我们发现博客提供了更多信息。