【问题标题】:netty server getting too many close_wait connectionsnetty 服务器获得太多 close_wait 连接
【发布时间】:2014-01-28 08:47:15
【问题描述】:

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

此服务器构建为每分钟接受 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 连接。

请有人指出我们在这里做错了什么?

【问题讨论】:

    标签: netty


    【解决方案1】:

    你试过了吗?

            .childOption(ChannelOption.SO_REUSEADDR, true);
    

    【讨论】:

    • 我们没有使用这个选项。让我试着观察一下。只是好奇地问这个选项是如何解决问题的?
    • 与 CLOSE_WAIT 无关。
    【解决方案2】:

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

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

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

    检查您是否出于某种原因将频道设置为长时间不可读(无论是否错误)。

    有关 TCP 连接终止 FSM 状态的更多信息,您可以查看本指南The TCP/IP Guide

    【讨论】:

    • 传输根本不会关闭连接,更不用说只有在接收缓冲区为空时。应用程序必须这样做,而事实并非如此。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-25
    • 2012-09-23
    • 1970-01-01
    • 1970-01-01
    • 2015-10-29
    • 1970-01-01
    相关资源
    最近更新 更多