tomcat connectionTimeout 问题解决
问题现象
在某个时刻,后端收到了平时 4-6 倍的请求(保密起见,略去产品和事件),在 10 分钟后居然没有请求可以接进来
问题原因
经过分析,首先,是后端服务器的线程池满了,线程池满的原因:
server.xml
中maxThread=512
,导致超过 512 的之后的请求只能排队,等待有线程释放后,才能被处理;connectionTimeout
配置为10000
,这个配置导致建立一个 socket 连接后,如果一直没有收到客户端的 FIN,也没有数据过来,那么此连接也必须等到 10s 后,才能被超时释放,巧了,现网的客户端真的不会发 FIN 包过来,那一直陪它耗够 10 秒,和 1 一起,处理的 512 个线程只能等待 10s 后,超时释放才能处理后面排队的请求,所以浪涌一来,分分钟就满了,特慢
接下来是怎么接不进来的呢?
部分用户忍不了了,发了个登出请求,依然在特慢的排队,部分进入了队列的客户端加上前面时间一共等了几秒都没响应,客户端就发了个 FIN 过来,说要不咱主动断开算了,后端收到请求变为 CLOSE_WAIT 状态,说你等我会,处理点事,巧了,用户这几秒也受不了了,整个重启客户端,客户端 ip 再来就变了,结果后端处理好后的第三次握手本该通知"我处理好了,你断吧"的请求发不过去,好死不死,后台还配的重发 15 次,重发 15 次需要大概 20~30 分钟左右,啊哦,于是这条请求一直占着线程 20 多分钟,这样的请求多点,线程就一直占着,于是别的请求就一直就接不进来咯
问题解决
- 修改
maxThread=1024
,提高一倍的线程数 - 修改
connectionTimeout=2000
,没数据了之后 2 秒就断,别等这么久(keepAlivetimeout 是请求处理完了之后等多久关闭连接,connectionTimeout
是本条连接等多久没数据关连接) - 修改
/proc/sys/net/ipv4/
目录下的tcp_retries2
文件为 4,别重发 15 次了,一般也用不了这么多
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论