生产环境大量的CLOSE_WAIT解决思路

问题描述:

项目某个模块的接口无法使用

问题排查:

  • 查看运行日志,未发现相关接口的异常信息。

  • 打印gc日志,对gc日志进行分析,未发现频繁GC的日志信息。

-XX:+PrintGCDateStamps -XX:+PrintGCDetails -Xloggc:/home/gc.log

  • 查看服务器的cpu占用情况,CPU占用的并不高。,排除内存溢出的情况。

top -H -p 进程号

  • 查看TCP连接状况,发现大量的TCP连接处于CLOSE_WAIT状态。

netstat -anop --tcp -p 进程号

  • 进一步使用jstack工具对于进程进行分析。

jstack -l 进程号 >> /home/stack.log

stack日志分析:

  1. 查看具体wait线程的堆栈信息,定位具体方法。
  2. 如果上述步骤无法定位的具体方法,则向下追溯线程ID,直到找到对应的线程堆栈信息,发现两个问题。
    问题一,初步判断,行锁问题。

Alt

上述图片说明,线程100处于等待状态,继续向下追溯,

Alt

一直到线程97,线程处于运行状态,但是未获取到数据库的锁,由于该堆栈的方法定位是数据库操作,初步判断可能未在同一事务下同时进行插入和更新操作,导致行锁。
问题二,初步判断,RestTemplate未设置超时时间。

Alt

猜测网络阻塞情况下,未设置超时时间,长时间获取输入流,导致程序僵死,无法继续执行下去。

解决措施:

  1. 优化相关业务代码。
  2. 添加Rest配置。

后续:

如上述措施无法解决该问题,则需要bug复现,然后使用tcpdump进行抓包分析,使用Wireshark分析tomcat和nginx之间的数据包内容,定位到具体的一次tcp连接导致服务器未响应FIN_WAIT_2,导致CLOSE_WAIT。

  1. tcpdump使用,监测网卡和端口,生成cap文件。

tcpdump -i eno16780032 -e tcp port 8080 -w target.cap -w target.cap

  1. Wireshark使用,下载cap文件,导入,分析数据包。

Alt

相关博客参考

  • TCP通讯流程

https://blog.youkuaiyun.com/m0_38121874/article/details/81990457

  • TCP协议详解

https://blog.youkuaiyun.com/qq_37884273/article/details/82188586

  • jstack中pid状态解释

https://blog.youkuaiyun.com/dongyansheng_max/article/details/23922059

  • close_wait问题分析流程

https://mp.weixin.qq.com/s?__biz=MzI4MjA4ODU0Ng==&mid=402163560&idx=1&sn=5269044286ce1d142cca1b5fed3efab1&3rd=MzA3MDU4NTYzMw==&scene=21#wechat_redirect

  • tcpdump和wireshark使用

https://www.cnblogs.com/pyng/p/9698723.html

### SMB 协议中的 TIME_WAIT 状态原因与解决方案 SMB(Server Message Block)协议是一种用于网络文件共享的应用层协议。在网络通信过程中,TCP 连接的状态转换对于理解其行为至关重要。其中,`TIME_WAIT` 是 TCP 那一端主动关闭连接后进入的一个状态,在此状态下,系统会等待一段时间以确保所有可能的延迟数据包都被处理完毕。 #### 原因分析 当客户端或服务器通过调用 `close()` 函数来终止一个 TCP 连接时,该端会发送最后一个 ACK 数据包给对方并进入 `TIME_WAIT` 状态[^1]。这种设计是为了防止旧的数据包重新出现在新的连接中造成混乱。具体来说: - **超时时间设置**:通常情况下,操作系统会在 `TIME_WAIT` 状态下保持两倍的最大段生命周期 (MSL),即大约 1 到 4 分钟不等的时间窗口。 - **资源消耗问题**:如果短时间内有大量的短寿命连接被创建和销毁,则可能会导致大量套接字处于 `TIME_WAIT` 状态,从而占用宝贵的端口资源[^2]。 #### 解决方案探讨 针对上述提到的原因可以采取以下几种方法缓解由过多 `TIME_WAIT` 引发的问题: 1. **调整内核参数** 修改操作系统的相关配置项能够有效减少此类现象的发生频率。例如,在 Linux 平台上可以通过更改 `/proc/sys/net/ipv4/tcp_tw_reuse` 和 `/proc/sys/net/ipv4/tcp_tw_recycle` 参数允许重用这些处于 `TIME_WAIT` 的 socket 来建立新连接[^3]: ```bash echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse ``` 2. **优化应用逻辑** 应用程序层面也可以做出相应改进措施降低频繁断开重建带来的影响。比如让服务端维持更长时间的闲置链接而不是轻易切断它们;或者考虑使用长轮询技术代替传统的短请求模式等等。 3. **负载均衡策略** 当面对高并发场景下的大规模瞬态流量冲击时,合理规划部署架构显得尤为重要。引入反向代理设备或将任务分摊到多个实例上运行都是不错的思路方向之一。 ```python import os def enable_tcp_tw_reuse(): try: with open('/proc/sys/net/ipv4/tcp_tw_reuse', 'w') as f: f.write('1') print("Enabled tcp_tw_reuse successfully.") except Exception as e: print(f"Failed to enable tcp_tw_reuse: {e}") if __name__ == "__main__": enable_tcp_tw_reuse() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值