高併發短連接場景(HTTP API、微服務 RPC、負載測試)下,Linux 伺服器常因海量 TIME_WAIT 狀態 Socket 耗盡連接追蹤表、端口資源或記憶體,導致新連接建立失敗、延遲飆升。本文深入內核原理,提供從參數調優到架構優化的完整方案。
TCP 四次揮手結束連接時,主動關閉端 進入 TIME_WAIT,持續 2 MSL(Maximum Segment Lifetime),Linux 定為 60 秒(TCP_TIMEWAIT_LEN = 60*HZ)。
struct inet_timewait_sock(約 168 bytes)、佔用客戶端暫時端口(預設 32768-60999)、增加查找開銷。# 統計 TIME_WAIT 數量 ss -tan state time-wait | wc -l # 或 netstat -ant | grep -c TIME_WAIT # 查看端口範圍 cat /proc/sys/net/ipv4/ip_local_port_range # 32768 60999 (約 28k 可用端口)
tcp_fin_timeout 無效網路上流傳調整 /proc/sys/net/ipv4/tcp_fin_timeout(預設 60)可縮短 TIME_WAIT,**這是錯誤的**。該參數僅影響 FIN_WAIT_2 狀態超時,不控制 TIME_WAIT。內核中 TIME_WAIT 由硬編碼宏定義:
// include/net/tcp.h #define TCP_TIMEWAIT_LEN (60 * HZ) // 60 秒,編譯期固定
修改需重編內核,生產環境極不推薦。
net.ipv4.tcp_tw_reuse = 1(重用 TIME_WAIT Socket 發起新連出連接)tcp_timestamps=1,預設開啟)啟用,且經過 1 秒(RTO)後才重用。net.ipv4.tcp_tw_recycle = 0(必須關閉)sysctl -w net.ipv4.ip_local_port_range="1024 65535" # 持久化:/etc/sysctl.d/99-tcp-tuning.conf net.ipv4.ip_local_port_range = 1024 65535
net.netfilter.nf_conntrack_max = 1000000 net.netfilter.nf_conntrack_tcp_timeout_time_wait = 30
net.ipv4.tcp_syncookies = 1
| 策略 | 原理 | 適用場景 |
|---|---|---|
| 連接池/長連接 | 復用 TCP 連接,減少建立/關閉頻率 | 資料庫、Redis、HTTP Keep-Alive、gRPC |
| SO_REUSEPORT | 多執行緒/進程監聽同一埠,核心分發 | 高併發 Server(Nginx、Go、Java Netty) |
| Client 端綁定固定源端口 | 配合 tcp_tw_reuse 精確控制 | 特殊協議、測試環境 |
| 負載均衡器終結連接 | L4/L7 LB 吸收短連接,後端走長連接 | 微服務架構、K8s Ingress |