1. 程式人生 > >timestamp和recycle同時開啟,導致連線成功率降低【學習方法論】

timestamp和recycle同時開啟,導致連線成功率降低【學習方法論】

現象簡介

若同時開啟timestamp和recycle引數,會由於引發per-host的PAWS機制,導致連線成功率降低。
【產生問題】
1、什麼是timestamp和recycle?
2、什麼是PAWS機制?
3、為什麼成功率會降低?

什麼是timestamp和recycle?

(1)什麼是timestamp
tcp_timestamps的本質是記錄資料包的傳送時間。
基本步驟如下:
1. 傳送方在傳送資料時,將一個timestamp(表示傳送時間)放在包裡面
2. 接收方在收到資料包後,在對應的ACK包中將收到的timestamp返回給傳送方(echo back)
3. 傳送發收到ACK包後,用當前時刻now - ACK包中的timestamp就能得到準確的RTT

RTT(Round Trip Time)由三部分組成:鏈路的傳播時間(propagation delay)、末端系統的處理時間、路由器快取中的排隊和處理時間(queuing delay)。
簡單來說就是我傳送一個數據包,然後對端回一個ack,那麼當我接到ack之後,就能計算出從我傳送出包到接到過了多久,這個時間就是RTT,所以RTT的變化在一定程度上反應了網路的擁塞程度。
RTO就是tcp在傳送一個數據包之後,會啟動一個重傳定時器,而RTO就是這個定時器的重傳時間。 在通俗的講就是,我一開始預先算個定時器時間,如果你回覆了ack那正好,如果沒有回覆給我ack,然後RTO定時器的時間又到了,那麼我就重傳。
【產生問題】
1、為什麼需要timestamp?
2、timestamp存在什麼負面影響?
為什麼需要timestamp?
若沒有timestamp就會採用SKB->when的方式計算RTT,基本步驟如下:
1. TCP層在傳送出一個SKB時,使用skb->when記錄傳送出去的時間
2. TCP層在收到SKB資料包的確認時,使用now - skb->when來計算RTT
這時會存在一個缺陷,如當進行如下操作:
1、tcp層首次傳送SKB時間是send_time1,然後丟包發生重傳,重傳一個數據包的時間是send_time2
2、tcp層收到SKB的確認包的時間是recv_time
這樣無法判斷recv_time對應ACK是確認第一次資料包的傳送還是確認第二次重傳的資料包。
timestamp存在什麼負面影響?
會產生10位元組的TCP header開銷
(2)什麼是recycle
表示開啟TCP連線中TIME-WAIT sockets的快速回收,預設為0,表示關閉
對客戶端和伺服器同時起作用,開啟後在 3.5*RTO 內回收,RTO 200ms~ 120s 具體時間視網路狀況。

什麼是Per-host PAWS機制?

在高頻寬下,TCP序列號可能在較短的時間內就被重複使用(recycle/wrapped),就可能導致同一條TCP流在短時間內出現序號一樣的兩個合法的資料包及其確認包!
PAWS機制就是為了應對這一現象設計的,這種機制要求所有來個同一個host IP的TCP資料包的
timestamp值是遞增的。當收到一個timestamp值,小於服務端記錄的對應值後,則會認為這是一個過期的資料包,然後會將其丟棄。

為什麼成功率會降低?

  1. 同時開啟tcp_timestamp和tcp_tw_recycle會啟用TCP/IP協議棧的per-host的PAWS機制
  2. 經過同一NAT轉換後的來自不同真實client的資料流,在服務端看來是於同一host打交道
  3. 雖然經過同一NAT轉化,但由於不同真實client會攜帶各自的timestamp值
    因而無法保證整過NAT轉化後的資料包攜帶的timestamp值嚴格遞增
  4. 當伺服器的per-host PAWS機制被觸發後,會丟棄timestamp值不符合遞增條件的資料包