Java Netty ReadTimeoutHandler和CLOSE\u等待
我正在使用带有readTimeoutHandler的Netty服务器(4.0.33)上工作,但由于某些原因,当存在大量流量时,许多套接字会以关闭等待状态堆积起来。我已将readTimeoutHandler超时设置为5秒,但在收到请求时将其删除。以下是管道初始值设定项:Java Netty ReadTimeoutHandler和CLOSE\u等待,java,netty,Java,Netty,我正在使用带有readTimeoutHandler的Netty服务器(4.0.33)上工作,但由于某些原因,当存在大量流量时,许多套接字会以关闭等待状态堆积起来。我已将readTimeoutHandler超时设置为5秒,但在收到请求时将其删除。以下是管道初始值设定项: @Override protected void initChannel(Channel channel) throws Exception { ChannelPipeline p = channel.pipeline(
@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秒后按预期发生。但是,套接字仍处于关闭状态,请等待。有人知道我可能做错了什么吗?事先谢谢 尝试将
ReadTimeoutHandler
放在管道的最开始处,看看是否有区别。尝试将ReadTimeoutHandler
放在管道的最开始处,看看是否有区别。