我正在使用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中。有谁知道我在这里做错了什么?先谢谢!