localhost kernel: TCP: time wait bucket table overflow
執行 netstat -an | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' | sort -rn 發現:
LISTEN 11
ESTABLISHED 514
CLOSE_WAIT 19
TIME_WAIT 864 ← 異常佔比極高
大量 TIME_WAIT 佔滿內核連接追蹤表,導致新連接無法建立,服務拒絕響應。
TIME_WAIT 為 主動關閉方 發送最後 ACK 後進入,持續 2 MSL (Maximum Segment Lifetime,Linux 預設 60 秒),確保對端收到 ACK、防止舊封包干擾新連接。TIME_WAIT,連接速率超過回收速率即堆積。tcp_tw_buckets 哈希表追蹤 TIME_WAIT 套接字,預設上限 net.ipv4.tcp_max_tw_buckets = 180000 (視記憶體而定)。溢出即記錄 time wait bucket table overflow 並丟棄新連接。# /etc/sysctl.conf
net.ipv4.tcp_max_tw_buckets = 360000 # 雙倍或根據記憶體調大 (每桶約 256 bytes)
# 立即生效
sysctl -p
風險:僅緩解症狀,記憶體佔用線性增長,極端流量仍可能耗盡。
net.ipv4.tcp_tw_reuse = 1 # 允許將 TIME_WAIT 套接字用於新的外向連接 (需時間戳支援)
net.ipv4.tcp_tw_recycle = 1 # 啟用快速回收 (自然時間戳機制,RFC 1323)
net.ipv4.tcp_timestamps = 1 # 前提:雙端支援時間戳選項
⚠️ 重大警示:tcp_tw_recycle 在 NAT 環境極其危險!多客戶端共用公網 IP 時,時間戳單調遞增假設失效,導致合法連接被誤判為舊封包而丟棄,表現為間歇性連接失敗。**Linux 4.12+ 內核已移除 `tcp_tw_recycle`**。
net.ipv4.tcp_fin_timeout = 30 # 預設 60 秒,調整為 30 秒 (僅影響主動關閉方)
# 注意:不建議低於 2 MSL (約 30 秒),違反 RFC 793 可能導致舊封包干擾
| 方案 | 原理 | 適用場景 |
|---|---|---|
| HTTP Keep-Alive | 複用長連接,大幅減少建立/關閉次數 | Web 服務、API 閘道、微服務間通訊 |
| 連接池 | 應用層維護持久連接池 (如 HikariCP, HTTPClient Pool) | 資料庫連接、下游服務調用 |
| SO_LINGER (凌遲關閉) | 發送 RST 直接關閉,跳過 TIME_WAIT (違協議,慎用) | 極端壓測、無狀態廣播 |
| SO_REUSEPORT (Linux 3.9+) | 多執行緒/進程監聽同埠,分散連接壓力 | 高併發服務端 (Nginx, Go, Java Netty) |
# /etc/sysctl.d/99-tcp-tuning.conf
# 連接追蹤表擴容
net.ipv4.tcp_max_tw_buckets = 500000
net.netfilter.nf_conntrack_max = 1000000
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 30
# TIME_WAIT 優化 (僅非 NAT 環境)
net.ipv4.tcp_tw_reuse = 1
# net.ipv4.tcp_tw_recycle = 0 # 明確關閉,避免 NAT 災難
net.ipv4.tcp_timestamps = 1
# 縮短 FIN 等待
net.ipv4.tcp_fin_timeout = 30
# 協議棧整體調優
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3
# 生效
sysctl --system
watch -n 1 'netstat -an | grep TIME_WAIT | wc -l' 實時觀察數量變化。ss -s | grep timewait (iproute2 更高效)。netstat_Tcp_CurrEstab、netstat_Tcp_TimeWait 等指標,設置告警閾值。tcp_max_tw_buckets 擴容與 tcp_tw_reuse 能快速緩解症狀,但高併發短連接模式本身才是病灶。生產環境請優先實施:全鏈路啟用 Keep-Alive、部署連接池、採用 SO_REUSEPORT 多進程監聽、引入側車代理 (Envoy) 統一管理上游連接。內核參數調優僅作為兜底安全網,配合應用層架構優化,才能徹底解決 TIME_WAIT 風暴,構建彈性高可用的 Linux 網路服務。