Netty客户端生成许多TIME_WAIT套接字状态

时间:2018-12-17 14:12:13

标签: sockets netty

我写了一个netty客户代码,将一些处理过的数据发送到多个客户。运行3-4小时后,我用尽了所有插槽,无法再进行连接。另外,当我检查操作系统中的套接字状态时,大量的套接字处于TIME_WAIT状态。

var fromCurrencyDim = ndx.dimension(d => d.Market.slice(0,3))

这是ChannelInBoundHandler类中的方法

public class NettyClient {

private static LogHelper logger = new LogHelper(NettyClient.class);

private static EventLoopGroup workerGroup = new NioEventLoopGroup();

private static Bootstrap nettyClient = new Bootstrap()
        .group(workerGroup)
        .channel(NioSocketChannel.class)
        .option(ChannelOption.SO_KEEPALIVE, true)
        .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000);

private URL url;
private RequestVo Req;
private ChannelFuture chFuture;
private Object ReportData;
private JAXBContext jbContext;
private static final int CHANNEL_READ_TIMEOUT = 5;


public NettyClient() {
    // TODO Auto-generated constructor stub
}

public NettyClient(RequestVo Req, JAXBContext jbCtx,Object data) {
    this.Req = Req;
    this.ReportData = data;
    this.jbContext = jbCtx;
}

public void sendRequest() {

    logger.debug("In sendRequest()");
    //ChannelFuture chFuture = null;
    try {
        this.url = new URL(Req.getPushAddress());
        //add handlers
        nettyClient.handler(new ChannelInitializer<SocketChannel>() {

            @Override
            public void initChannel(SocketChannel ch) {
                ch.pipeline()
                  .addLast("timeout",
                    new ReadTimeoutHandler(CHANNEL_READ_TIMEOUT, TimeUnit.SECONDS));

                ch.pipeline()
                  .addLast("codec", new HttpClientCodec());

                ch.pipeline()
                  .addLast("inbound",
                     new NettyClientInBoundHandler(Req, jbContext, ReportData));
            }
        });

        //make a connection to the Client
        int port = url.getPort() == -1? url.getDefaultPort():url.getPort();
        chFuture = nettyClient.connect(url.getHost(), port);
        chFuture.addListener(new NettyClientConnectionListener(this.Req.getRequestId()));
    } catch (Exception e) {
        logger.error("Exception: Failed to connect to Client ", e);
    } finally {

    }
}
}

任何想法代码中的错误将对我有很大帮助。 谢谢

1 个答案:

答案 0 :(得分:0)

我对 netty 不熟悉,但是我认为我可以解释您的部分问题,并希望在整个过程中对您有所帮助:

使用端口然后将其关闭时,该端口将不会立即自动供其他进程使用。相反,它将在一段时间内进入TIME_WAIT状态。对于Windows,我相信这将是240秒(四分钟)。

我猜您的代码正在缓慢占用系统上的所有可用端口,原因是从TIME_WAIT状态释放端口的过程太慢。

我尚不清楚实际的端口号是从哪里来的(也许它们是由url.getDefaultPort()自动生成的?),但是也许您可以找到某种方法来重用它们?如果您可以保留一个或多个打开的连接并以某种方式重用它们,则可以减少对新端口的请求频率,使关闭的端口脱离其TIME_WAIT状态。