Netty ReadTimeoutHandler和CLOSE_WAITs

时间:2016-02-18 18:25:55

标签: java netty

我正在使用readTimeoutHandler在Netty服务器(4.0.33)上工作,但由于某些原因,当有大量流量时,许多套接字会在CLOSE_WAIT状态下堆叠。我将readTimeoutHandler超时设置为5秒,但是在收到请求时将其删除。这是管道初始化程序:

@Override
protected void initChannel(Channel channel) throws Exception {

    ChannelPipeline p = channel.pipeline();
    p.addLast("decoder", new HttpRequestDecoder(4096, 8192, 64 * 1024));
    p.addLast("encoder", new HttpResponseEncoder());
    p.addLast("chunkedwritehandler", new ChunkedWriteHandler());
    p.addLast("readtimeout", new ReadTimeoutHandler(5, TimeUnit.SECONDS) 
    p.addLast("writetimeout", new WriteTimeoutHandler(0, TimeUnit.SECONDS));
    p.addLast("handler", new MyHandler());
}

我的简化处理程序方法:

@Override
public void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {

    // If it's an HTTP request
    if(msg instanceof HttpRequest)
    {
        this.request = (HttpRequest) msg;
        this.prepareHttpDecoder(ctx);
    }

    // If it's HTTP content
    else if(msg instanceof HttpContent)
    {
        HttpContent chunk = (HttpContent) msg;

        try {
            // Offer the chunk to the HTTP decoder
            httpDecoder.offer(chunk);
        }
        catch(HttpPostRequestDecoder.ErrorDataDecoderException e) {

            // Log the error

            // Write the response with a force close
            ctx.writeAndFlush("DecoderError").addListener(ChannelFutureListener.CLOSE);

            // Add a 15 second readTimeout
            ctx.pipeline().replace("readtimeout", "readtimeout", new ReadTimeoutHandler(15, TimeUnit.SECONDS));
            return;
        }

        // Handle the final chunk
        if(chunk instanceof LastHttpContent)
        {
            // We've received the whole request, cancel the readTimeout
            ctx.pipeline().replace("readtimeout", "readtimeout", new ReadTimeoutHandler(0, TimeUnit.SECONDS));

            // Process the request

            resetHttpDecoder();
        }
    }

@Override
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {

    // Log things, clean session

    // Close the context
    if(ctx != null)
    {
        ctx.close();
    }
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable e) throws Exception {

    // Log things, clean the session

    // Close the context
    if(ctx != null)
    {
        ctx.close();
    }
}

对于保留在CLOSE_WAIT中的套接字,我得到以下Netty日志:

2016-02-18 01:46:34,994 DEBUG [nioEventLoopGroup-3-2] [id: 0xbe795f05, /10.221.2.135:44859 => /10.221.1.128:631] REGISTERED
2016-02-18 01:46:34,994 DEBUG [nioEventLoopGroup-3-2] [id: 0xbe795f05, /10.221.2.135:44859 => /10.221.1.128:631] ACTIVE
2016-02-18 01:46:39,995 DEBUG [nioEventLoopGroup-3-2] [id: 0xbe795f05, /10.221.2.135:44859 => /10.221.1.128:631] CLOSE()
2016-02-18 01:46:39,995 DEBUG [nioEventLoopGroup-3-2] [id: 0xbe795f05, /10.221.2.135:44859 :> /10.221.1.128:631] CLOSE()
2016-02-18 01:46:39,995 DEBUG [nioEventLoopGroup-3-2] [id: 0xbe795f05, /10.221.2.135:44859 :> /10.221.1.128:631] INACTIVE
2016-02-18 01:46:39,995 DEBUG [nioEventLoopGroup-3-2] [id: 0xbe795f05, /10.221.2.135:44859 :> /10.221.1.128:631] UNREGISTERED
2016-02-18 01:46:39,995 DEBUG [nioEventLoopGroup-3-2] [id: 0xbe795f05, /10.221.2.135:44859 :> /10.221.1.128:631] CLOSE()

看起来当Netty没有收到任何数据时,readTimeout会在5秒后按预期发生。但是,套接字仍保留在CLOSE_WAIT中。有谁知道我在这里做错了什么?先谢谢!

0 个答案:

没有答案