一次TCP TIME_WAIT连接数过多告警处理
问题回顾
客户反馈收到如下告警,主机TCP timewait连接数过多
prometheus告警表达式
收到连接数过多的告警并不代表一定会产生生产问题,此时要关注负载是否直线上升,连接数一直无法释放,如果出现此情况,则需要及时处理,避免造成生产环境宕机。
连接数数据来源:/proc/net/sockstat
线上场景中,持续的高并发场景
一部分 TIME_WAIT 连接被回收,但新的 TIME_WAIT 连接产生,新产生的连接数超过释放的速度;一些极端情况下,会出现大量的 TIME_WAIT 连接。Think:上述大量的 TIME_WAIT 状态 TCP 连接,有什么业务上的影响吗?
Nginx 作为反向代理时,大量的短链接,可能导致 Nginx 上的 TCP 连接处于 time_wait 状态:
每一个 time_wait 状态,都会占用一个「本地端口」,上限为 65535
当大量的连接处于 time_wait 时,新建立 TCP 连接会出错,address already in use : connect 异常
Tips:TCP 本地端口数量,上限为 65535(6.5w),这是因为 TCP 头部使用 16 bit,存储「端口号」,因此约束上限为 65535。
图片
TCP 连接中,「主动发起关闭连接」的一端,会进入 time_wait 状态
time_wait 状态,默认会持续 2 MSL(报文的最大生存时间)
time_wait 状态下,TCP 连接占用的端口,无法被再次使用
TCP 端口数量,上限是 6.5w(65535,16 bit)
大量 time_wait 状态存在,会导致新建 TCP 连接会出错,address already in use : connect 异常
大量的连接会导致服务器资源使用上升
现实场景服务内部调用过多,优化业务模式,也可以是连接关闭方式需要优化
Nginx 反向代理场景中,可能出现大量短链接,服务器端可能存在
解决思路1、服务器端允许 time_wait 状态的 socket 被重用
2、缩减 time_wait 时间,设置为 1 MSL(即,2 mins)
解决方案
TCP连接数统计脚本
通过这个脚本可以统计出当前分配连接数的进程,通过进程可以找到对应的服务,如果是服务关闭连接的姿势不对,业务方优化即可
在业务侧解决此问题之前,我们可以通过操作系统的内核参数缓解此问题
方案
修改配置文件/etc/sysctl.conf
1、允许将TIME_WAIT状态的socket重新用于新的TCP连接
2、快速回收TIME_WAIT状态的socket
3、修改time_wait连接数的回收时间
最后sudo sysctl -p 使配置生效即可,从修改前后的效果上可以看到,timewait的回收明显加快了