记一次netty http server给客户端返回reset包排除
2019-10-11 21:58 Loull 阅读(1604) 评论(1) 编辑 收藏 举报类似文章:解决用netty去做web服务时,post长度过大的问题
现象:当客户端给server发送的请求体较大时,服务直接给客户端返回reset包。
tcpdump:
应用还没有完全收上去,就close这个fd,造成发送reset包。
https://github.com/torvalds/linux/blob/master/net/ipv4/tcp.c#L2384
netstat -s |grep "connections reset due to early user close" 这个计数器一直在增加
因为返回的 RST 包有窗口大小,所以这是主动调用的 tcp_send_active_reset, 代码里有 bug,读缓冲里有数据没读完直接 close 了。
程序里判断如果msg不可读,就把channel close掉。而当请求体过大时,netty会把msg设置为chunked,而chunked的msg也是不可读的,结果就导致了问题:缓冲区还有数据,但不可读,程序就把channel close了,操作系统这时会发送reset包,导致客户端收到reset包。
netty3的HttpRequestDecoder注释:
/** * Creates a new instance with the default * {@code maxInitialLineLength (4096}}, {@code maxHeaderSize (8192)}, and * {@code maxChunkSize (8192)}. */ public HttpRequestDecoder() { }
org.jboss.netty.handler.codec.http.HttpMessageDecoder#decode方法里:
case READ_VARIABLE_LENGTH_CONTENT: if (buffer.readableBytes() > maxChunkSize || HttpHeaders.is100ContinueExpected(message)) { // Generate HttpMessage first. HttpChunks will follow. checkpoint(State.READ_VARIABLE_LENGTH_CONTENT_AS_CHUNKS); message.setChunked(true); return message; } break;
修复方式,在netty handler pipeline里添加 HttpChunkAggregator