Linux下TIME_WAIT連接優化內核參數tcp_tw_reuse與tcp_tw_recycle區別與聯系淺析


概述

最近學習網絡相關知識點,很多文章提到針對TCP time wait(后續簡稱TW)狀態連接進行優化的參數tcp_tw_reuse和tcp_tw_recycle,並且不少文章提到了啟用tcp_tw_recycle會導致的問題,不建議開啟該選項,但是並沒有找到一篇能完全解答自己所有疑惑的文章,如:

  1. Linux會丟棄所有來自遠端的timestramp時間戳小於上次記錄的時間戳(由同一個遠端發送的)的任何數據包。也就是說要使用該選項,則必須保證數據包的時間戳是單調遞增的,這里的遠端定義的是ip還是ip+port? 是一定時間內丟棄時間戳過期packet還是tcp_tw_recycle啟用后一直丟棄?
  2. 很多文章都會提到tcp_tw_reuse 僅作用於客戶端連接,tcp_tw_recycle則同時作用於客戶端與服務端連接,這里客戶端、服務端連接具體指的是什么?與TCP三次握手的客戶端、服務端概念上有什么區別?

通過學習網上大家的總結+閱讀了部分4.9內核源碼,這里整理總結一下從各處學習到的知識點及自己的理解。

過多time wait會導致的問題

  1. 客戶端主動發起的連接總數受 max open file數限制,過多連接導致達到max open file限制將無法創建新的連接。
  2. 客戶端主動發起的連接總數也受可用端口號限制,一般使用端口號為1024~65000,如果過多TW連接將端口號耗盡同樣無法再創建新的連接。
  3. 每個TW連接都會占用一定的系統資源-如內存--實際耗費內存很小,這點一般可忽略

tcp_tw_reuse與tcp_tw_recycle相同點

  1. 兩者目的均是為了解決系統中過多TW狀態 TCP連接的問題。
  2. 兩者都需要和tcp_timestamps 同時開啟方能生效。
  3. 根據RFC定義,主動關閉連接方其TW狀態需維持2MSL時間才正式關閉連接,Linux上MSL默認定義為30s,即TW狀態默認需要維持1分鍾方能正式關閉,tcp_tw_reuse與tcp_tw_recycle均為通過縮短TW狀態時間進行復用來進行優化。
  4. 兩個參數默認均為關閉狀態

tcp_tw_reuse作用

  1. 僅作用於客戶端方主動發起連接,即出向連接。
  2. 連接進入TW狀態>1s,且新連接的timestamp大於舊連接記錄的timestamp時方能復用連接。
  3. client提前中止TW狀態進行復用,發起新連接,server依然處於last ack狀態時,交互流程如下:
    1. client發送新SYN => server
    2. client <= server由於處於LAST ACK,不理會SYN,重發 FIN+ACK
    3. client收到FIN+ACK,發現timestamp已過期,發送RST => server, server收到后重置關閉舊連接
    4. client初始發送的SYN包等待ACK超時1s后,重發SYN => server
    5. client <= server 會發 SYN+ACK 進入正常三次握手連接過程...
    6. 新連接建立完成后,client/server若收到舊連接的歷史報文,通過timestamp可判斷出為舊報文直接丟棄
      整個過程中可以看到,client端可以正常復用發起新的連接,在server端依然處於LAST ACK狀態時也只是需要稍微延遲一小段時間而已。

tcp_tw_recycle作用

  1. 同時作用於client/server發起連接,即出、入向連接
  2. TW狀態維持3.5RTO(the retransmission timeout (RTO) interval which is computed from the RTT and its variance)之后就直接可以被過期回收,具體RTO取值是基於網絡RTT及其他相關因子綜合計算,一般在200ms~120s之間。
  3. TW狀態后2MSL會丟棄所有來自遠端相同四元組的timestamp小於上次記錄timestamp的任何數據包,因而需要保證數據包timestamp是單調遞增的
    1. NAT情況下,不同client從同一NAT ip請求,由於NAT不會更改包中的timestamp,而不同機器的時間不可能完全同步,因而不同機器從同一個NAT IP+port發出的包會存在timestamp非單調遞增的情況,問題場景舉例:
      1. 機器A時間比機器B快1s,機器A先通過NAT機器 ip1:port1 對服務器S ip2: port2 發起tcp連接socket1--使用conn_old(ip1, port1, ip2, port2)四元組表示
      2. 后S主動斷開連接進入TW狀態,由於開啟tcp_tw_recycle,經過3.5RTO后S即可復用conn_old這個連接
      3. NAT機器對應連接在進入LAST ACK並收到S回復的ACK之后關閉了conn_old
      4. 而后機器B通過NAT機器發起conn_new(ip1, port1, ip2, port2)
      5. 此時S收到SYN包發現timestamp 小於conn_old中記錄的最終timestamp,於是丟棄conn_new的SYN包
      6. 機器B超時未收到回復,重發SYN包,機器S收到后比較timestamp后繼續丟棄....如此往復,最終導致通過NAT機器發起的conn_new(ip1, port1, ip2, port2)在TW狀態終止的2MSl內都無法建立新的連接,對於機器B的用戶表現就是連接遲遲無法建立成功。
    2. 高版本內核由於新的時間戳生成算法tcp: randomize tcp timestamp offsets for each connection 即便未使用NAT也會導致同一台機器不同socket之間timestamp非單調遞增
  4. Linux從4.12版本內核開始已經移除了tcp_tw_recycle支持

文章開始時兩個問題的答案

  1. 遠端定義為ip+port,無論tcp_tw_reuse還是tcp_tw_recycle,針對回收TW連接對新連接的影響,都是指同一四元組代表的連接(src_ip, src_port, dst_ip, dst_port),在開啟tcp_tw_recycle情況下,連接進入TW狀態的2MSL時間內,所有收到的小於舊連接最終timestamp的包都會被直接丟棄。
  2. 客戶端是指主動發起連接的一方,即TCP三次握手中發出首個SYN包的一方。

轉載請注明出處,原文地址:https://www.cnblogs.com/AcAc-t/p/tcp_tw_reuse_and_tcp_tw_recycle_introduction.html

參考:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM