中转服务TCP keepalive参数
中转服务出现大量 TIME_WAIT 连接堆积,通常不是因为 keepalive 没开,而是 keepalive 的探测时机和回收策略没有匹配实际业务。
本文会用可复制的命令和配置,告诉你如何在 Linux 上调整 TCP keepalive 参数,并配合必要的内核选项减少 TIME_WAIT 堆积。
适合 Nginx、HaProxy、Envoy 等转发层出现大量短连接、主动关闭连接后端口被占满的场景。
先确认症状:TIME_WAIT 到底算不算多
登录服务器执行下面命令,查看当前连接状态统计:
ss -s
重点看 timewait 数量。
如果持续稳定在几千甚至上万,同时业务出现 Cannot assign requested address 或新连接耗时变长,就说明本地端口或连接表快被占满了。
还可以用下面命令看具体来源:
ss -tan | awk '{print $1}' | sort | uniq -c | sort -rn
如果 TIME-WAIT 占比超过总连接数的 20%,且重业务无明显长连接,就值得调整。
调整 TCP keepalive:让空闲连接更快被回收
TCP keepalive 的作用是探测空闲连接是否还活着。
默认参数过于保守,对中转服务来说常常要等很久才能回收失效连接。
临时生效,直接写入 /proc/sys/net/ipv4/:
sysctl -w net.ipv4.tcp_keepalive_time=600
sysctl -w net.ipv4.tcp_keepalive_intvl=30
sysctl -w net.ipv4.tcp_keepalive_probes=3
说明:
tcp_keepalive_time:连接空闲多少秒后开始探测,默认 7200 秒太长,改成 600 秒更适合中转场景。tcp_keepalive_intvl:每次探测间隔,默认 75 秒,改成 30 秒可以更快确认连接状态。tcp_keepalive_probes:连续几次未响应就判定连接失效,3 次足够。
这三个参数配合后,空闲连接最多 600 + 30*3 = 690 秒内会被确认并回收。
缓解 TIME_WAIT 堆积的补充参数
除了 keepalive,还需要确认下面两个参数没有限制你:
sysctl -w net.ipv4.tcp_tw_reuse=1
sysctl -w net.ipv4.ip_local_port_range="1024 65535"
tcp_tw_reuse 允许客户端复用处于 TIME_WAIT 状态的连接,只对主动发起连接的一方有效。
中转服务作为客户端连接后端时作用明显。
注意:tcp_tw_recycle 已经在新版内核中移除,旧文档里建议开启 tcp_tw_recycle 的做法不要再用,它会导致 NAT 环境下连接异常。
端口范围扩大后,服务器能够使用的临时端口更多,可以从根源上减少端口耗尽。
永久写入配置,避免重启失效
编辑 /etc/sysctl.conf(或在 /etc/sysctl.d/ 下新建 keepalive.conf):
vim /etc/sysctl.d/99-keepalive.conf
写入:
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 1024 65535
保存后执行:
sysctl --system
如果用的是旧版 CentOS 6 等系统,使用 sysctl -p 生效。
验证调整效果与常见避坑
执行以下命令确认参数已生效:
sysctl net.ipv4.tcp_keepalive_time net.ipv4.tcp_keepalive_intvl net.ipv4.tcp_keepalive_probes net.ipv4.tcp_tw_reuse
再观察 ss -s,在业务高峰时段对比调整前后的 timewait 数量。
如果下降不明显,说明 TIME_WAIT 主要来源是中转服务主动关闭连接,此时 keepalive 只是辅助,真正有效的是 tcp_tw_reuse 和业务侧改用长连接。
避坑提醒:
- 不要同时开启
tcp_tw_recycle,除非你确定所有客户端都没有 NAT。 - 调整
tcp_keepalive_time不要低于 300 秒,否则空闲连接容易被误杀,尤其是数据库或长连接池场景。 - 如果中转服务本身是 Nginx,后端连接池
keepalive配置也要同步调整,比如upstream中的keepalive 32;,两端配合才能看到明显效果。 - 修改端口范围后,如果业务有防火墙策略,需要同步放行新端口段。
如果调整后 TIME_WAIT 仍有堆积,建议抓包确认是否有大量连接被对端先行关闭,再结合业务超时时间做进一步优化。
保持观察一个业务周期,确认连接状态稳定后再固化配置。