[TOC]算法
性能分析三板斧之一:緩存
【統計->捕獲文件屬性】 Statistics -> Summary,查看文件屬性信息,如平均速度、包大小、包數等等安全
判斷流量高低峯、是否過載bash
性能分析三板斧之二:服務器
【分析->專家信息】 Wireshark ->Analyze -> Expert Infos -> Notes,查看抓包的統計信息微信
查看是否有Notes、Warnings、errors之類的信息,看看是否有相關警告和錯誤,判斷網絡質量、重傳亂序等網絡
性能分析三板斧之三:tcp
【統計->服務響應時間】 statistics -> Service Response Time -> xxxxx(如:ONC-RPC -> Program:NFS)工具
查看各項操做的服務響應時間,判斷是否過載性能
Edit->Preferences->Protocols->TCP,勾選 Relative Sequence Numbers
啓用以前就是相對值了。
Statistics -> TCP StreamGraph -> TCP Sequence Graph(Stevens)
查看數據傳輸狀況,如傳輸的是否均勻、是否有TCP Zero Windows之類的
字段含義就是wireshark的一些提示信息,也就是wireshark抓包的一些info信息,這些提示信息都是Info這一欄中體現。
若是某個包被標記提示[Packer size limited during caputre]
,說明這個包沒有抓全,能夠進一步查看下面的frame信息。通常這個狀況是抓包的姿式不對。某些操做系統中,tcpdump默認只抓取每一個幀的前96個字節,所以tcpdump抓包的時候,能夠經過 -s參數指定要抓取的字節數
若是wireshark發現被Ack的那個包沒有抓到,就會提示[TCP ACKed unseen segment]
,不過這個提示大部分狀況均可以忽略。由於大都狀況下,剛開始抓包的時候,都是隻抓到了後面的Ack而沒有抓到前面的ACK
TCP數據傳輸中,除了三次握手和四次握手以外,同一臺機器發出的數據段應該是連續的,即後一個包的Seq等於前一個包的Seq+Len,正確狀況都應該是這樣;若是發現後一個包的Seq大於前一個包的Seq+Len,那麼就說明中間丟了一段數據,若是丟失的數據在整個網絡包中都找不到,wireshark就會提示[TCP Previous segment not captured]
,
出現這種狀況的兩個可能性:
TCP數據傳輸中,除了三次握手和四次握手以外,同一臺機器發出的數據段應該是連續的,即後一個包的Seq等於前一個包的Seq+Len,正確狀況都應該是這樣;或者說後一個包的Seq應該會大於等於前一個包的Seq+Len,若是wireshark發現後一個包的Seq小於前一個包的Seq+Len,那麼就認爲是亂序了,就會提示[TCP Out-of-Order]
。
通常而言,小跨度的亂序影響不大,若是是大跨度的亂序則會致使快速重傳。舉例以下,若是一個包的順序是一、二、三、四、5被打亂成二、一、三、四、5則屬於小跨度亂序,影響不大;若是被打亂成二、三、四、五、1,則會觸發足夠多的Dup ACK,從而致使1號包的重傳。
當亂序或者丟包發生時,接收方就會收到一些Seq號比指望值大的包,TCP協議每收到一個這種包就會ACK一次指望的Seq值,經過這個方式告知發送方,所以就產生了一些重複的Ack。Wireshark抓到這些重複的Ack就會提示[TCP Dup ACK]
.
當發送方連續收到3個或者以上[TCP Dup ACK]
時,就意識到以前發的包可能丟了,因而根據RFC的規定就會開始快速重傳。[TCP Dup ACK]
是接收方迴應給發送方的,所以發送方就可以感知到並當連續收到3個以上的時候就開啓快速重傳。
快重傳算法規定,發送方只要一連收到3個重複確認就應當當即重傳對方還沒有收到的報文段,而沒必要繼續等待設置的重傳計數器時間到期。
若是一個包真的丟了,又沒有後續包能夠在接收方觸發[Dup Ack],那麼就不會開啓快速重傳,這種狀況發送方只能等到超時後再發送重傳,超時重傳的包就會被wireshark標記並提示[TCP Retransmission]
TCP 超時與重傳應該是 TCP 最複雜的部分之一,超時重傳是 TCP 保證可靠傳輸的基礎。當 TCP 在發送數據時,數據和 ack 都有可能會丟失,所以,TCP 經過在發送時設置一個定時器來解決這種問題。若是定時器溢出尚未收到確認,它就重傳數據。關鍵之處就在於超時和重傳的策略,須要考慮兩方面:
在 Linux 較高的內核版本中,好比 3.15 中,已經有了至少 9 個定時器:超時重傳定時器,持續定時器,ER延遲定時器,PTO定時器,ACK延遲定時器,SYNACK定時器,保活定時器,FIN_WAIT2定時器,TIME_WAIT定時器。
TCP包中「win=xxx」表明接收窗口的大小,表示這個包的發送方當前還有多少緩衝區能夠接受數據。當wireshark發行一個包中的「win=0」時,就會標記提示[TCP zerowindow]
,表示緩衝區已經滿了,沒法再接收數據了。
通常的,在緩衝區滿以前,窗口大小應該是逐漸減少的過程。
若是一個包的發送方已經把對方所聲明的接收窗口大小耗盡了,就會被wireshark標記爲[TCP window Full]
。好比某一端在握手時聲明本身的接收窗口只有65535,也就意味着對端最多隻能給他發送65535字節的數據而無需確認,即「在途字節數」最多隻能是65535,當wireshark計算出對端已經有65535字節未被確認時,就會發生這個提示。
[TCP window Full]和上面的[TCP zerowindow]比較容易混淆,前者表示這個包的發送方暫時沒有辦法再發送數據了;後者表示這個包的發送方沒有辦法再接收數據了;二者都會意味着要暫停數據傳輸
只有在Edit->Preferences->Protocols->TCP菜單裏啓用了Allow sub dissector to reassemble TCP streams
後,纔有可能收到這個提示。這個表示能夠把屬於同一個應用層PDU的TCP包虛擬的集中起來
只有在Edit->Preferences->Protocols->TCP菜單裏關閉了Allow sub dissector to reassemble TCP streams
後,纔有可能收到這個提示。
(Fragment reasembly time execeeded)表示這個包的發送方以前收到了一些分片,可是因爲某些緣由致使遲遲沒法組裝起來。
好比傳輸過程當中有一些分片被丟包了,那麼接收方就沒法組裝起來,而後就經過這個ICMP的方式告知發送方
ICMP是(Internet Control Message Protocol)Internet控制報文協議。它是TCP/IP協議族的一個子協議,用於在IP主機、路由器之間傳遞控制消息。控制消息是指網絡通不通、主機是否可達、路由是否可用等網絡自己的消息。這些控制消息雖然並不傳輸用戶數據,可是對於用戶數據的傳遞起着重要的做用。
在TCP層,有個FLAGS字段,這個字段有如下幾個標識:SYN, FIN, ACK, PSH, RST, URG.
抓包顯示的控制字段形態以下:
[SYN] : 創建鏈接、發起包 [FIN] : 關閉鏈接、結束包 [PSH] : DATA數據傳輸 [ACK] : ACK迴應 [RST] : RESET、鏈接重置
另外兩個經常使用字段:
[Len] :數據包長度 [Seq] :數據包序列號
ACK是可能與SYN,FIN等同時使用的,好比SYN和ACK可能同時爲1,它表示的就是創建鏈接以後的響應,若是隻是單個的一個SYN,它表 示的只是創建鏈接
當出現FIN包或RST包時,咱們便認爲客戶端與服務器端斷開了鏈接 當出現SYN和SYN+ACK包時,咱們認爲客戶端與服務器創建了一個鏈接
對應http而言,通常就是request->reponse,一問一答。但對應TCP而言,並不必定每一個包都會ACK。TCP的ACK是一種累積的ACK,也就是表示在我這個ACK以前的全部其餘ACK都已經確認收到了。
好比,97號包的ACK=65701,96號包的Seq+Len=64273+1428=65701,那麼就是表示97號的ACK是對96號的迴應,也就是96號以前的其餘沒有被顯示ACK的包,其實都已經經過97號包ACK了,這樣發送方也就知道了在96號以前發出去的全部包對方都已經收到並ACK了。
MSL(Maximum Segment Lifetime),表示「報文最大生存時間」,是全部報文都遵循的在網絡上存在的最長時間,超過這個時間報文將被丟棄
TTL(Time to live),表示生存時間,是ip頭的一個域,生存時間是由源主機來設置一個初始值,但TTL不是存的具體時間,而是表示能夠通過的最大路由數。
Time to live: 62
RTT(round-trip time),表示客戶到服務器往返所花時間,TCP含有動態估算RTT的算法
Protocol = ARP Source 和 Destination 都是MAC地址格式如 00:60:48:ff:12:31
抓包分析中,若是網絡不通,發出去收不到ACK等等之類的,要再進一步看看每一個包的MAC地址是否正確,反之有多個MAC地址致使的一些問題
三次握手協議
抓包數據,如何判斷一個包是上一個包的回包呢?根據TCP協議,下一個包的Ack的值若是等於上一個包的Seq + Len,則表示是其回包
三次握手的時候會相互聲明各自的MSS
TCP四次揮手協議
正常而言,都會有這樣的四次揮手,可是若是有延遲確認,那麼四次揮手就變成了3次揮手,省掉了四次揮手中的第二個包
一些實戰經驗告訴咱們,Wireshark ->Analyze -> Expert Info -> Notes
統計中的重傳率若是超過了0.1%,就須要採起一些措施了。可是現實網絡環境下,要低於0.01%的重傳是基本不可能的。
是爲了減小廣域網的小分組數目,從而減少網絡擁塞的出現;
該算法要求一個tcp鏈接上最多隻能有一個未被確認的未完成的小分組,在該分組ack到達以前不能發送其餘的小分組,tcp須要收集這些少許的分組,並在ack到來時以一個分組的方式發送出去;其中小分組的定義是小於MSS的任何分組;
該算法的優越之處在於它是自適應的,確認到達的越快,數據也就發哦送的越快;而在但願減小微小分組數目的低速廣域網上,則會發送更少的分組;
if there is new data to send
if the window size >= MSS and available data is >= MSS
send complete MSS segment now
else
if there is unconfirmed data still in the pipe
enqueue data in the buffer until an acknowledge is received
else
send data immediately
end if
end if
end if
複製代碼
若是tcp對每一個數據包都發送一個ack確認,那麼只是一個單獨的數據包爲了發送一個ack代價比較高,因此tcp會延遲一段時間,若是這段時間內有數據發送到對端,則捎帶發送ack,若是在延遲ack定時器觸發時候,發現ack還沒有發送,則當即單獨發送;
延遲ACK好處:
(1) 避免糊塗窗口綜合症; (2) 發送數據的時候將ack捎帶發送,沒必要單獨發送ack; (3) 若是延遲時間內有多個數據段到達,那麼容許協議棧發送一個ack確認多個報文段;
試想以下典型操做,寫-寫-讀,即經過多個寫小片數據向對端發送單個邏輯的操做,兩次寫數據長度小於MSS,當第一次寫數據到達對端後,對端延遲ack,不發送ack,而本端由於要發送的數據長度小於MSS,因此nagle算法起做用,數據並不會當即發送,而是等待對端發送的第一次數據確認ack;這樣的狀況下,須要等待對端超時發送ack,而後本段才能發送第二次寫的數據,從而形成延遲;
使用TCP套接字選項TCP_NODELAY能夠關閉套接字選項;
以下場景考慮關閉Nagle算法:
(1) 對端不向本端發送數據,而且對延時比較敏感的操做;這種操做無法捎帶ack; (2) 如上寫-寫-讀操做;對於此種狀況,優先使用其餘方式,而不是關閉Nagle算法:
TCP和UDP的區別如TCP是可靠的、UDP是不可靠的,可是實際中的表現是何爲可靠?何爲不可靠?具體協議的ACK有何區別?
無論對於TCP仍是UDP,均可能會被分片,這是因爲以太網的MSS決定的;不一樣在於分片傳輸的處理:
語音通話的場景在於不能接受延遲,可是能夠接受音質稍差。這樣的話,UDP傳輸的時候,若是有些包丟失,應用層能夠選擇忽略並繼續傳輸其餘包,丟到一些包只會影響到音質,可是保證了流暢性。TCP而言,會重傳每一個包,只要丟包就重傳,這樣就會致使有必定的延遲,在語音中若是有延遲則並不可取。
所以,TCP和UDP,各自有各自的適合場景。 語音、視頻中,UDP更合適,像聲網、linphone等都是UDP去處理音視頻。 基礎、核心協議交互中必須採用TCP。
TCP在傳輸過程都須要往返時間來確認也就是ACK,而UDP則無需確認,那麼UDP的效率必定比TCP高嗎?這個是不必定的,雖然UDP能夠一直往外不停的發包,不用等待ACK;可是TCP有發送窗口的存在,若是發送窗口小,並無佔滿帶寬,那麼確定受到往返時間的約束使得效率稍低,可是若是隻要窗口足夠大而且合適,跑滿帶寬,那麼TCP也是能夠不受往返時間的約束而源源不斷的傳輸數據。
舉例:馬路上只有一輛車來回跑去拉貨,回程過程至關於空跑(回程至關於TCP的ACK),這樣TCP的效率固然低。可是若是在不擁塞的狀況下,儘可能提升車輛數量,是的馬路上的車被恰好充滿,這樣整體的傳輸效率提升了,而且回程的ACK也不受影響。
分組交換,把大的數據分割成小包,這樣能夠實現鏈路共享,而不至於由於某一方阻塞全部。既然要分割成小包,那麼必然要肯定一個最大的包大小,這個就是MTU(Maximum Transmission Unit)最大傳輸單位,值爲1500字節。若是除去20個字節的包頭結構,那麼一個IP包最大的包大小爲1500-20=1480字節。若是要傳輸的數據塊超過1480字節,那麼網絡層就會將其分片處理,封裝爲多個網絡包傳輸。對於TCP而言,TCP協議層會主動把數據分紅小段後再交給網絡層,TCP的最大分段大小稱之爲MSS(Maximum Segment Size),這個MSS被設置爲MTU減去IP頭和TCP頭以後的大小,這樣恰好能夠知足一個MTU。由於UDP沒有MSS的概念,所以就只能交給網絡層去處理分片了。
可是須要注意的是,目前有些網絡是Jumbo Frame(巨幀)或者PPPOE這樣的設備,那麼他們的MTU則不是1500字節。目前發送方並無一個好的機制來肯定最佳分片大小,應該儘可能使得網絡中的設備的MTU保持一致。若是網絡中的設備的MTU不一致,那麼TCP協議如何適配MTU呢?咱們知道TCP建連的時候必需要先進行三次握手,TCP在前兩個握手包中會相互聲明本身的MSS。若是client端聲明本身的MSS=8960(巨幀),server端申明本身的MSS=1460,那麼client在三次握手後就知道了server端的MSS,所以當client想要發送大於server端MSS的包的時候就會主動將本身的MSS下降爲server端的MSS大小,從而適配接收方的MTU,可見,TCP協議層作了很是多的優化和處理
既然有分片,那麼接收方必然要進行分片重組,經過抓包工具能夠得知,分片的每一個包都包含了off=xxx,ID=xxx
這樣的信息,接收方會把ID相同的分片按照off偏移量進行重組。那麼接收方又如何得知那個包纔是最後的分片呢?而後何時開始重組呢?這裏就在於最後一個分片包有一個特殊的Flag,叫More fragment = 0
,抓包中的表現形式是..0. ... = More fragment: Not set
,這個就表示它是最後一個分片,而後能夠開始重組包了。若是是其餘分片包,形如..1. ... = More fragment: set
則表示接收方須要緩存,等待其餘分片傳輸完成
若是client端的MTU=9000,server端的MTU=1500,那麼當client請求server端的時候,client的包通過路由器時候,要麼就被丟包,要麼就被分片。若是這個巨幀包在網絡層攜帶了DF(Don't fragment)標誌則被丟棄(設置則表示不容許分片),若是沒有設置則進行分片傳輸。須要注意的是,這種狀況下若是丟包了重傳仍是會被丟棄,就成了黑洞了。
測試中,能夠經過ping命令模擬這樣的狀況:
成功:
ping xxx.xxx.xxx.xxx -l 1472 -f -n 1
失敗:
ping xxx.xxx.xxx.xxx -l 1473 -f -n 1
複製代碼
-f 參數表示設置DF標誌 -l 參數表示請求字節
當請求字節設置爲1472的時候,由於ICMP頭部爲8字節、IP頭爲20字節,所以1472+8+20=1500,恰好是一個MTU,所以能夠ping成功。可是第二個1473+8+20=1501字節超過MTU了,又由於設置了DF標誌表示不容許分片,所以傳輸失敗,通常這樣的狀況下,路由器會回覆Packet needs to be fragmented but DF set
。
抓包的時候,若是發現一直重傳,某個某些相對較大的包(查看Len值)才重傳,那麼能夠經過ping xxx.xxx.xxx.xxx -l [Len] -f
值進行測試驗證,經過這個ping指定的[Len]的大小變化來尋得規律,可能就會發現網絡上某個設備的MTU並不是1500,這樣致使了超過這個就重傳的現象。
client 和 server端直接必定有交換機、路由器等設備,若是server端是萬兆網卡,client端是千兆網卡,就有可能使得server端發送過快致使數據堵在交換機上,從而交換機在堵滿以後發生丟包。 可是通常而言,server端的帶寬本應該要大於client端纔算合理,爲了不擁塞,所以須要有一種流控機制,容許交換機在過載時告知server端放慢速度或者暫停傳輸。
有一種「暫停幀」,就可以知足這樣的需求:當交換機的緩衝區即將被填滿時發送給server端一個暫停幀,當server端等待一下子再發,這樣就能夠避免溢出丟包,也避免丟包後的重傳。server端等待多久則由暫停幀中的pause_time指定,這樣server端在等待pause_time後纔會開始繼續發送。固然交換機還能夠給server端發送一個pause_time=0的暫停幀,告知server端,我已經消化完了,能夠當即發送了。
注意,這的流控和TCP的流控是不同的
經過wireshark排查問題,須要分析網絡包,在網絡包中尋找一些線索,而後根據網絡協議做出推斷,接着就是一個一個去否認,而後最終找到問題所在
須要可以理解底層TCP協議,要可以清楚每個字段表示的含義
要善用Wireshark的一些統計、分析工具;過濾器等
發送發抓包和接收抓包是有極大區別的
要善用「三板斧「的操做流程和步驟去分析問題
【"歡迎關注個人微信公衆號:Linux 服務端系統研發,後面會大力經過微信公衆號發送優質文章"】