netty服务器获得太多close_wait连接

时间:2014-01-28 08:47:15

标签: netty

我们有一个服务器程序构建来处理来自客户端程序的数据。

构建此服务器以接受每分钟50K连接的数据。当我们没有服务器上的巨大负载时,它工作得很好。如果我们遇到负载,我们开始获得许多close_wait连接,这将永远不会被服务器释放。

这是我们正在做的方法。

  • 服务器只有在读写空闲时间为3分钟时才会关闭通道。
  • 客户端的责任是仅在将数据发送到云时才关闭连接。构建服务器以在同一套接字通道中接受多条消息

这是我们使用的示例代码

public class Server {

public void start() {
   bossGroup = new NioEventLoopGroup(bossThreads);
   workerGroup = new NioEventLoopGroup(workerThreads);

   bootstrap = new ServerBootstrap();
   bootstrap.group(bossGroup, workerGroup)
   .channel(NioServerSocketChannel.class)
        .childHandler(new PipelineFactory())
        .option(ChannelOption.SO_BACKLOG, serverBackLog);

   try {
       // Bind and start to accept incoming connections.
       bootstrap.bind(new InetSocketAddress("127.0.0.1",6754));
   } catch (Exception e) {
       throw new RuntimeException(e.getMessage(), e.getCause());
   }
 }
}

class PipelineFactory extends ChannelInitializer<SocketChannel>{

    private static final int SESSION_IDLE_TIME_MIN = 3;

    public void addPipeline(ChannelPipeline pipeline) {
        // Idle Timer
        pipeline.addLast("timeout", new CustomTimeoutHandler(SESSION_IDLE_TIME_MIN, SESSION_IDLE_TIME_MIN, 0, TimeUnit.MINUTES));
        // Message Decoder
        pipeline.addLast("decoder", new SomeDecoder());
        // Message Encoder
        pipeline.addLast("encoder", new SomeEncoder());
        // Protocol Handler
        pipeline.addLast("handler", new DataHandler());
    }

    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
        ChannelPipeline p = ch.pipeline();
        addPipeline(p);
    }
}

我们仍然不知道为什么会产生许多close_wait连接。

有人可以指出我们在这里做错了吗?

2 个答案:

答案 0 :(得分:-1)

你试过用吗?

        .childOption(ChannelOption.SO_REUSEADDR, true);

答案 1 :(得分:-1)

客户端似乎尝试从其侧面关闭连接,但服务器不会从其侧面关闭连接,并且连接仍处于CLOSE_WAIT状态。

当应用程序未读取服务器读取缓冲区中的所有数据时,会发生这种情况,在从客户端收到第一个FIN后,不允许传输级别关闭连接。

我知道当您将通道设置为不可读时会发生这种情况,这会阻止应用程序从读取缓冲区接收新数据。在这种情况下,只有当通道设置为可读或服务器应用程序从其侧面明确关闭连接时,通道才会关闭。 如果我理解正确,您的服务器将在3分钟后关闭此连接,因为它将处于空闲状态。您可以通过捕获流量来查看这是否是问题。如果服务器用重置标志关闭连接,那么当没有从缓冲区读取所有数据时,可能表示连接已关闭。

检查您是否由于某种原因将通道设置为长时间不可读(错误与否)。

有关TCP连接终止FSM的更多信息,请参阅本指南The TCP/IP Guide