一站式學習Wireshark(四):網路效能排查之TCP重傳與重複ACK

emc.com發表於2015-11-21

作為網路管理員,很多時間必然會耗費在修復慢速伺服器和其他終端。但使用者感到網路執行緩慢並不意味著就是網路問題。

解決網路效能問題,首先從TCP錯誤恢復功能(TCP重傳與重複ACK)和流控功能說起。之後闡述如何發現網路慢速之源。最後,對網路各組成部分上的資料流進行概況分析。這幾張內容將會幫助讀者識別,診斷,以及排查慢速網路。

更多資訊

接下來的內容,較多是黑白圖片了。雖然看起來有點不爽,但還是很值得一看。

TCP錯誤恢復功能:

TCP的錯誤恢復功能是定位,診斷及修復網路延時的最佳工具。延時可以在單程也可以往返方向測量。高延時是網路管理員的頭號大敵。本節我們討論TCP高延時是如何導致序列號和確認號亂序的。

TCP重傳:

主機報文重傳是TCP最基本的錯誤恢復功能,它的目的是防止報文丟失。

報文丟失的可能因素有很多種,包括應用故障,路由裝置過載,或暫時的服務當機。報文級別速度是很高的,而通常報文丟失是暫時的,因此TCP能夠發現和恢復報文丟失顯得尤為重要。

決定報文是否有必要重傳的主要機制是重傳計時器(retransmission timer),它的主要功能是維護重傳超時(RTO)值。當報文使用TCP傳輸時,重傳計時器啟動,收到ACK時計時器停止。報文傳送至接收到ACK的時間稱為往返時間(RTT)。對若干次時間取平均值,該值用於確定最終RTO值。在最終RTO值確定之前,確定每一次報文傳輸是否有丟包發生使用重傳計時器,下圖說明了TCP重傳過程。

當報文傳送之後,但接收方尚未傳送TCP ACK報文,傳送方假設源報文丟失並將其重傳。重傳之後,RTO值加倍;如果在2倍RTO值到達之前還是沒有收到ACK報文,就再次重傳。如果仍然沒有收到ACK,那麼RTO值再次加倍。如此持續下去,每次重傳RTO都翻倍,直到收到ACK報文或傳送方達到配置的最大重傳次數。

最大重傳次數取決於傳送作業系統的配置值。預設情況下,Windows主機預設重傳5次。大多數Linux系統預設最大15次。兩種作業系統都可配置。

示例如下圖:

TCP重傳過程傳送的第一個報文如下圖所示(圖片不很清楚,已經盡力了):

這是一個TCP PSH/ACK報文①,包含648位元組資料②,從10.3.30.1傳送至10.3.71.7。這是一個典型的資料包文。

在通常情況下,第一個報文傳送之後很快會收到TCP ACK報文。然而,在這個case裡,第二個是重傳報文。可以在Packet list皮膚裡看到。Info欄清楚的標明“TCP Retransmission”,報文以黑色背景紅色字型標出。下圖是Packet List皮膚中的重傳示例(仍然不清楚,但可參見上圖):

也可以在Packet Details和Packet Bytes皮膚中檢視來確定是否是重傳報文,如下圖所示:

注意此報文與源報文相同(除了IP標識和checksum欄位)。要驗證這一點,比較兩個報文的Packet Bytes①。

在Packet Details皮膚,注意到重傳報文在SEQ/ACK Analysis下面有些額外的資訊②。這些資訊是由Wireshark提供的而並非報文字身。SEQ/ACK Analysis告訴我們這確實是一個重傳報文,RTO值是0.206秒,此時的RTO是基於報文1的時間增量。

檢查剩下的報文會得到類似的結果,不同之處只有IP標識和checksum,以及RTO值。要使報文之間的時間間隔形象化,在Packet List皮膚中檢視Time欄,如下圖所示。這裡可以看到RTO值的翻倍增長關係。

TCP重複ACK以及快速重傳:

重複ACK是指在接收方收到亂序報文時,所發出的一類TCP報文。TCP使用報文頭的序列號和確認號以有效保證資料按照傳送的順序接收和重組。

當TCP連線建立以後,握手過程中交換的一個最重要的資訊是初始序列號(ISN)。一旦連線雙方設定了ISN之後,接下來傳送的報文所包含的序列號增加一個資料載荷值。

假設有個主機ISN是5000,傳送500位元組報文至接收方。一旦報文接收之後,接收端回覆一個ACK號為5500的TCP ACK報文,基於以下公式:

Sequence Number In + Bytes of Data Received = Acknowledgment Number Out

按照上述計算結果,返回傳送端的確認編號實際上是接收端希望收到的序列號。示例如下圖:

資料接收方通過序列號來檢查報文丟失。接收方通過追蹤接收到的序列號,能夠確認序列號是否亂序。當接收方收到一個不正常的序列號,它會假設傳輸過程中有報文丟失。為了正確重傳資料,接收方必須擁有丟失報文,所以它傳送包含有丟失報文正確序列號的ACK報文,以便傳送方重傳此報文。

當重傳主機從傳送端接收到3個重複ACK時,它會假設此報文確實在傳送中丟失,並且立即傳送一個快速重傳。一旦觸發了快速重傳,所有正在傳輸的其他報文都被放入佇列中,直到快速重傳報文傳送為止。過程如下圖所示:

承接上文的彩圖:

本例中第一個報文如下圖:

這是一個TCP ACK報文,從資料接收端(172.31.136.85)發給傳送端(195.81.202.68)①,確認前一個報文所傳送的資料。
此報文中的確認編號是1310973186②,應當是下一個接收報文的序列號,如下圖所示:

不幸的是接收端的序列號是1310984130①,並不是所期望的值。這意味著報文在傳送中丟失。接收端注意到報文亂序,並且在第三個報文中傳送重複ACK,如下圖所示:

可以通過以下兩種方式之一來確認這是一個重複ACK:

在Packet Detaisl皮膚中的Info欄。報文呈現黑色背景紅色字型。

SEQ/ACK Analysis下的Packet Deatails皮膚。擴充套件這一欄會發現報文顯示為duplicate ACK。接下來幾個報文重複此過程。如下圖所示:

此檔案中的第四個報文是傳送端所發出具有錯誤序列號①的另一個資料塊。因此,接收端傳送第二個重複ACK②。接收端又收到一個亂序報文③。從而觸發了第三以及最後一個重複ACK④.

一旦傳送方接收到接收方所發來的第三個重複ACK,它就會暫停所有傳輸報文並且重傳丟失報文,下圖顯示了快速重傳過程:

重傳報文同樣可以通過Packet List皮膚的Info欄觀察到。報文呈現黑色背景紅色字型。這個報文的SEQ/ACK Analysis截面告訴我們這可能是一個快速重傳幀。(標識報文為快速重傳的資訊不是報文字身所包含的內容,而是Wireshark的功能)。最後一個報文是接收到快速重傳的ACK。

本文系列目錄:

相關文章