上層網路裝置斷線,ubuntu下tcp established 狀態連線總是等待15分鐘才關閉,為什麼?

Anjie發表於2018-08-04
  • 背景: 客戶端:ubuntu 下 tcp socket 長連線;每 30 秒發一次心跳;發出的訊息都需要服務端 ACK(ACK 自身除外),未收到 ACK 則關閉連線;部署在客戶現場,出口公網電信; 服務端:ubuntu 下 tcp socket 長連線自定義服務端;收到任何訊息都需要發 ACK(ACK 自身除外);60 秒內未收到任何訊息(含心跳),則關閉連線;部署在阿里雲;
  • 問題: 客戶現場出口網路裝置不穩定,經常閃斷;導致客戶端 socket 處於 tcp established 狀態下傳送 send 訊息不報錯,但收不到 ACK,於是主動關閉連線 close。在主動呼叫關閉 close 連線後,socket 一直存在,且為 established 狀態,直到 15 分鐘左右才會消失。每次都是如此,原因何在?
  • 分析: 1)established 狀態下,上層網路裝置斷網,socket 一般不會立刻感知(觸發 close); 2)那麼, 可能是 established 狀態下,重傳或超時機制導致的;

  • 核實: 檢視客戶現場 ubuntu 主機 tcp 相關引數:sysctl -a |grep tcp root@Anjie:~# sysctl -a |grep tcp ..... net.ipv4.tcp_retries1 = 3 net.ipv4.tcp_retries2 = 15 net.ipv4.tcp_rfc1337 = 0 net.ipv4.tcp_rmem = 4096 87380 6291456 net.ipv4.tcp_sack = 1 net.ipv4.tcp_slow_start_after_idle = 1 net.ipv4.tcp_stdurg = 0 net.ipv4.tcp_syn_retries = 6 net.ipv4.tcp_synack_retries = 5 net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_thin_dupack = 0 net.ipv4.tcp_thin_linear_timeouts = 0 net.ipv4.tcp_timestamps = 1 net.ipv4.tcp_tso_win_divisor = 3 net.ipv4.tcp_tw_recycle = 0 net.ipv4.tcp_tw_reuse = 0 net.ipv4.tcp_window_scaling = 1 net.ipv4.tcp_wmem = 4096 16384 4194304 net.ipv4.tcp_workaround_signed_windows = 0 ...... 逐個引數排查(主要明白用途,調整影響,參考https://blog.csdn.net/hytfly/article/details/53426630) 注意到引數: net.ipv4.tcp_retries2 = 15 TCP 失敗重傳次數,預設值 15,意味著重傳 15 次才徹底放棄.可減少到 5,以儘早釋放核心資源

  • 驗證: 設定成 1(net.ipv4.tcp_retries2 = 1 ) 後,斷開上層路由,觀察到 socket 連線很快就消失了(約 1 分鐘);close 事件觸發,socket 進入重連機制。

  • 總結: net.ipv4.tcp_retries2 控制 established 狀態下訊息重傳次數;調小可以提高中間網路斷開的感知靈敏度。

  • 思考: 如果 net.ipv4.tcp_retries2 = 15 不變更,上層網路在 15 分鐘內恢復正常,在恢復正常時間範圍內傳送的訊息能正常到達服務端嗎?有興趣的同學可以嘗試下。

  • 注:寫得匆忙,省略了很多細節,權當備忘錄了。

更多原創文章乾貨分享,請關注公眾號
  • 上層網路裝置斷線,ubuntu下tcp established 狀態連線總是等待15分鐘才關閉,為什麼?
  • 加微信實戰群請加微信(註明:實戰群):gocnio

相關文章