首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

TCP 服務端收到 SYN 卻不回應 SYN-ACK:tcp_tw_recycle 在 NAT 環境下的陷阱

     編輯:Java 綜合教學

問題現象:服務端無響應導致連線失敗

近期在協助客戶排查問題時,發現一種詭異的現象:客戶端發起的 TCP 連線請求(SYN 封包)明明已到達服務端,但服務端卻始終不回應 SYN-ACK。經確認,服務端的連線數並未達上限,排除了連線佇列滿載的可能。靈光一閃,想起 net.ipv4.tcp_tw_recycle 這個核心參數可能是禍首,關閉後問題隨即解決。本文將深入剖析背後原理。

tcp_tw_recycle 的初衷與運作機制

為了加速 TIME_WAIT 狀態的連線回收,避免大量佔用資源,許多伺服器會開啟 net.ipv4.tcp_tw_recycle=1。此功能依賴 net.ipv4.tcp_timestamps(預設開啟)提供的時間戳選項。根據 RFC 1323,啟用後,核心會記錄每個遠端主機最後一個到達封包的時間戳。若同一 IP 的新封包時間戳小於記錄值,即判定為無效並直接丟棄。

NAT 環境下的「誤傷」:為什麼 SYN 被無視?

現代架構常見 LVS 或 Nginx 等四層負載均衡,後端伺服器看到的來源 IP 全是 LB 的地址。由於不同客戶端的系統時間不一致,經過 NAT 後,時間戳在後端看來便出現「亂序」。後端核心誤以為是舊連線的重傳或無效封包,直接丟棄了正常的 SYN,導致客戶端連線超時。

驗證與解決方案

如何確認封包被丟棄?

netstat -s | grep timestamp
# 輸出中若見到:
# packets rejects in established connections because of timestamp
# 即證實是時間戳檢查導致丟包。

建議配置

  • 關閉 tcp_tw_recycle(推薦):sysctl -w net.ipv4.tcp_tw_recycle=0,永久生效請寫入 /etc/sysctl.conf。
  • 若需緩解 TIME_WAIT 過多,可開啟 net.ipv4.tcp_tw_reuse=1(僅對客戶端發起的連線有效)。
  • 或關閉 tcp_timestamps,但會失去 PAWS(防序號繞回)等保護,不建議。

核心結論:處於 NAT/負載均衡後端的伺服器,嚴禁開啟 tcp_tw_recycle,否則會導致正常連線請求被靜默丟棄,極難排查。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved