未来的Netty.writeAndFlush成功杀死了主机

时间:2014-02-10 12:56:19

标签: java network-programming netty

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

  1. kill -9 server
  2. 从客户端发送一些数据
  3. 期望客户端 writeAndFlush 失败
  4. 由于某些原因有时,我们看到:

    1. writeAndFlush 成功,然后
    2. 之后
    3. java.io.IOException:通过对等方重置连接
    4. 即使服务器已经消失, writeAndFlush 有时也可能成功完成,而有时它会失败?

      可能是因为已杀死进程的OS套接字清理机制的计划而发生这种情况?

      客户端测试代码:

          channel.writeAndFlush(new TextWebSocketFrame("blah blah")).addListeners(
          <snip>
                  public void operationComplete(ChannelFuture future) {
                      assert future.isSuccess() == false;  <-- sometimes this is not triggered
                  }
          </snip>
      

      感谢任何想法,

1 个答案:

答案 0 :(得分:2)

这是一个简单的竞争条件,你必须接受的事情可能会发生。您只能通过不从远程主机接收数据来确定远程主机已消失。通常,这是通过设置一个计时器来实现的,并假设如果没有收到数据(可能是为了响应保持活动消息),则远程主机已经死了。

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

有关TCP重传的更多信息并保持活跃herehere