問題
公司用瀏覽器訪問線上服務一會失敗一會成功,通過ssh連接服務器排查時發現ssh也是這樣;
檢查
抓包后發現建立連接的請求已經到了服務器,但它沒有響應;
糾結了好久,后來在騰訊云技術支持及查了相關資料后發現是開啟了net.ipv4.tcp_tw_recycle導致的,將其設為0即可解決;
原因
收集了幾個與TIME_WAIT相關的內核參數:
net.ipv4.tcp_timestamps 默認開啟(1),數據包加時間戳,需要兩端都開啟,可以防止高速率寬帶時引起的序號回繞(序號不夠用重新開始了),可以精確計算出RTT(往返時延) net.ipv4.tcp_tw_reuse 默認關閉(0),允許TIME_WAIT的socket在超過1秒后重用,作用于發起連接的client端 net.ipv4.tcp_tw_recycle 默認關閉(0),允許快速回收處于TIME_WAIT的socket,作用于接受連接的server端 net.ipv4.ip_local_port_range 默認(32768 61000),可用的端口范圍 net.ipv4.tcp_max_tw_buckets 默認(180000),允許處于TIME_WAIT狀態socket的最大數量
若TIME_WAIT過多,可以開啟reuse和recycle來快速回收,值得注意的一點是,reuse和recycle需要timestamps開啟才會生效,當然timestamps一般都是開啟的;
上面問題的原因是,當多個client通過nat方式聯網時(一個局域網)它們的源ip相同但發出的時間戳很可能是亂的,而開啟了recycle的server端就會丟棄這些混亂的數據包,于是現象就是有時能連上有時不行;
至于reuse,開啟可能導致端口重用后還會收到上個socket延遲到達的數據,這個一般問題不大,應用程序都會校驗;
雖然reuse在client端配置有效,而recycle在server端,但現在很多機器都是接受連接后再去連接別人,所以視情況而定吧。
總結
官方文檔是不建議開啟reuse和recycle的,因為違反了tcp協議,所以臨時開啟來解決異常情況后應及時關閉;
若TIME_WAIT過多導致系統很慢(Linux對其優化很好,且現在不缺這點內存,所以一般不會),可以降低tcp_max_tw_buckets,阿里云和騰訊云分別默認設置為了5000、65536;
若端口不足可以考慮加大 ip_local_port_range,最大不超過:1024? 65535;
TIME_WAIT過多長遠的解決方式還是通過程序開發方面:
1. 代碼中及時正確的調用socket的close;
2. 讓client端主動斷開連接,而不是server端;
3. 盡量使用長連接,而不是短連接;
?
over