<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          如何使用 Wireshark 分析 TCP 吞吐瓶頸

          共 3574字,需瀏覽 8分鐘

           ·

          2022-08-26 11:49

          在公眾號后臺回復(fù):JGNB,可獲取杰哥原創(chuàng)的 PDF 手冊。

          Debug 網(wǎng)絡(luò)質(zhì)量的時候,我們一般會關(guān)注兩個因素:延遲和吞吐量(帶寬)。延遲比較好驗(yàn)證,Ping 一下或者 mtr[1]一下就能看出來。這篇文章分享一個 debug 吞吐量的辦法。

          看重吞吐量的場景一般是所謂的長肥管道(Long Fat Networks, LFN, rfc7323[2]). 比如下載大文件。吞吐量沒有達(dá)到網(wǎng)絡(luò)的上限,主要可能受 3 個方面的影響:

          • 發(fā)送端出現(xiàn)了瓶頸

          • 接收端出現(xiàn)了瓶頸

          • 中間的網(wǎng)絡(luò)層出現(xiàn)了瓶頸

          發(fā)送端出現(xiàn)瓶頸一般的情況是 buffer 不夠大,因?yàn)榘l(fā)送的過程是,應(yīng)用調(diào)用 syscall,將要發(fā)送的數(shù)據(jù)放到 buffer 里面,然后由系統(tǒng)負(fù)責(zé)發(fā)送出去。如果 buffer 滿了,那么應(yīng)用會阻塞住(如果使用 block 的 API 的話),直到 buffer 可用了再繼續(xù) write,生產(chǎn)者和消費(fèi)者模式。

          發(fā)送端出現(xiàn)瓶頸一般都比較好排查,甚至通過應(yīng)用的日志看何時阻塞住了即可。大部分情況都是第 2,3 種情況,比較難以排查。這種情況發(fā)生在,發(fā)送端的應(yīng)用已經(jīng)將內(nèi)容寫入到了系統(tǒng)的 buffer 中,但是系統(tǒng)并沒有很快的發(fā)送出去。

          TCP 為了優(yōu)化傳輸效率(注意這里的傳輸效率,并不是單純某一個 TCP 連接的傳輸效率,而是整體網(wǎng)絡(luò)的效率),會:

          • 保護(hù)接收端,發(fā)送的數(shù)據(jù)不會超過接收端的 buffer 大小 (Flow control)。數(shù)據(jù)發(fā)送到接受端,也是和上面介紹的過程類似,kernel 先負(fù)責(zé)收好包放到 buffer 中,然后上層應(yīng)用程序處理這個 buffer 中的內(nèi)容,如果接收端的 buffer 過小,那么很容易出現(xiàn)瓶頸,即應(yīng)用程序還沒來得及處理就被填滿了。那么如果數(shù)據(jù)繼續(xù)發(fā)過來,buffer 存不下,接收端只能丟棄。

          • 保護(hù)網(wǎng)絡(luò),發(fā)送的數(shù)據(jù)不會 overwhelming 網(wǎng)絡(luò) (Congestion Control, 擁塞控制), 如果中間的網(wǎng)絡(luò)出現(xiàn)瓶頸,會導(dǎo)致長肥管道的吞吐不理想;

          對于接收端的保護(hù),在兩邊連接建立的時候,會協(xié)商好接收端的 buffer 大小 (receiver window size, rwnd), 并且在后續(xù)的發(fā)送中,接收端也會在每一個 ack 回包中報告自己剩余和接受的 window 大小。這樣,發(fā)送端在發(fā)送的時候會保證不會發(fā)送超過接收端 buffer 大小的數(shù)據(jù)。(意思是,發(fā)送端需要負(fù)責(zé),receiver 沒有 ack 的總數(shù),不會超過 receiver 的 buffer.)

          對于網(wǎng)絡(luò)的保護(hù),原理也是維護(hù)一個 Window,叫做 Congestion window,擁塞窗口,cwnd, 這個窗口就是當(dāng)前網(wǎng)絡(luò)的限制,發(fā)送端不會發(fā)送超過這個窗口的容量(沒有 ack 的總數(shù)不會超過 cwnd)。

          怎么找到這個 cwnd 的值呢?

          這個就是關(guān)鍵了,默認(rèn)的算法是 cubic, 也有其他算法可以使用,比如 Google 的 BBR[3].

          主要的邏輯是,慢啟動(Slow start), 發(fā)送數(shù)據(jù)來測試,如果能正確收到 receiver 那邊的 ack,說明當(dāng)前網(wǎng)絡(luò)能容納這個吞吐,將 cwnd x 2,然后繼續(xù)測試。直到下面一種情況發(fā)生:

          • 發(fā)送的包沒有收到 ACK

          • cwnd 已經(jīng)等于 rwnd 了

          第 2 點(diǎn)很好理解,說明網(wǎng)絡(luò)吞吐并不是一個瓶頸,瓶頸是在接收端的 buffer 不夠大。cwnd 不能超過 rwnd,不然會 overload 接收端。

          對于第 1 點(diǎn),本質(zhì)上,發(fā)送端是用丟包來檢測網(wǎng)絡(luò)狀況的,如果沒有發(fā)生丟包,表示一切正常,如果發(fā)生丟包,說明網(wǎng)絡(luò)處理不了這個發(fā)送速度,這時候發(fā)送端會直接將 cwnd 減半。

          但實(shí)際造成第 1 點(diǎn)的情況并不一定是網(wǎng)絡(luò)吞吐瓶頸,而可能是以下幾種情況:

          • 網(wǎng)絡(luò)達(dá)到了瓶頸

          • 網(wǎng)絡(luò)質(zhì)量問題丟包

          • 中間網(wǎng)絡(luò)設(shè)備延遲了包的送達(dá),導(dǎo)致發(fā)送端沒有在預(yù)期時間內(nèi)收到 ACK

          2 和 3 原因都會造成 cwnd 下降,無法充分利用網(wǎng)絡(luò)吞吐。

          以上就是基本的原理,下面介紹如何定位這種問題。

          rwnd 查看方式

          這個 window size 直接就在 TCP header 里面,抓下來就能看這個字段。

          但是真正的 window size 需要乘以 factor, factor 是在 TCP 握手節(jié)點(diǎn)通過 TCP Options 協(xié)商的[4]。所以如果分析一條 TCP 連接的 window size,必須抓到握手階段的包,不然就不可以知道協(xié)商的 factor 是多少。

          cwnd 查看方式

          Congestion control 是發(fā)送端通過算法得到的一個動態(tài)變量,會實(shí)時調(diào)整,并不會體現(xiàn)在協(xié)議的傳輸數(shù)據(jù)中。所以要看這個,必須在發(fā)送端的機(jī)器上看。

          在 Linux 中可以使用 ss -i 選項(xiàng)將 TCP 連接的參數(shù)都打印出來。

          這里展示的單位是 TCP MSS[5]. 即實(shí)際大小是 1460bytes * 10.

          Wireshark 分析

          Wireshark 提供了非常實(shí)用的統(tǒng)計功能,可以讓你一眼就能看出當(dāng)前的瓶頸是發(fā)生在了哪里。但是第一次打開這個圖我不會看,一臉懵逼,也沒查到資料要怎么看。好在我同事[6]會,他把我教會了,我在這里記錄一下,把你也教會。

          首先,打開的方式如下:

          然后你會看到如下的圖。

          首先需要明確,tcptrace 的圖表示的是單方向的數(shù)據(jù)發(fā)送,因?yàn)?tcp 是雙工協(xié)議,兩邊都能發(fā)送數(shù)據(jù)。其中最上面寫了你當(dāng)前在看的圖數(shù)據(jù)是從 10.0.0.1 發(fā)送到 192.168.0.1 的,然后按右下角的按鈕可以切換看的方向。

          X 軸表示的是時間,很好理解。

          然后理解一下 Y 軸表示的 Sequence Number, 就是 TCP 包中的 Sequence Number,這個很關(guān)鍵。圖中所有的數(shù)據(jù),都是以 Sequence Number 為準(zhǔn)的。

          所以,你如果看到如上圖所示,那么說明你看反了,因?yàn)閿?shù)據(jù)的 Sequence Number 并沒有增加過,說明幾乎沒有發(fā)送過數(shù)據(jù),需要點(diǎn)擊 Switch Direction。

          這就對了,可以看到我們傳輸?shù)?Sequence Number 在隨著時間增加而增加。

          這里面有 3 條線,含義如下:

          除此之外,另外還有兩種線:

          需要始終記住的是 Y 軸是 Sequence Number,紅色的線表示 SACK 的線表示這一段 Sequence Number 我已經(jīng)收到了,然后配合黃色線表示 ACK 過的 Sequence Number,那么發(fā)送端就會知道,在中間這段空擋,包丟了,紅色線和黃色線縱向的空白,是沒有被 ACK 的包。所以,需要重新傳輸。而藍(lán)色的線就是表示又重新傳輸了一遍。

          學(xué)會了看這些圖,我們可以認(rèn)識幾種常見的 pattern:

          丟包

          很多紅色 SACK,說明接收端那邊重復(fù)在說:中間有一個包我沒有收到,中間有一個包我沒有收到。

          吞吐受到接收 window size 限制

          從這個圖可以看出,黃色的線(接收端一 ACK)一上升,藍(lán)色就跟著上升(發(fā)送端就開始發(fā)),直到填滿綠色的線(window size)。說明網(wǎng)絡(luò)并不是瓶頸,可以調(diào)大接收端的 buffer size.

          吞吐受到網(wǎng)絡(luò)質(zhì)量限制

          從這張圖中可以看出,接收端的 window size 遠(yuǎn)遠(yuǎn)不是瓶頸,還有很多空閑。

          放大可以看出,中間有很多丟包和重傳,并且每次只發(fā)送一點(diǎn)點(diǎn)數(shù)據(jù),這說明很有可能是 cwnd 太小了,受到了擁塞控制算法的限制。

          參考資料

          [1] mtr: https://www.kawabangga.com/posts/4275
          [2] rfc7323: https://datatracker.ietf.org/doc/html/rfc7323
          [3] BBR: https://www.kawabangga.com/posts/4086
          [4] TCP 握手節(jié)點(diǎn)通過 TCP Options 協(xié)商的: https://en.wikipedia.org/wiki/TCP_window_scale_option
          [5] TCP MSS.: https://www.cloudflare.com/learning/network-layer/what-is-mss/
          [6]spate: https://github.com/royzhr/spate

          作者:laixintao

          來源:https://www.kawabangga.com/posts/4794

          推薦閱讀:

          如何使用 tcpdump 抓包?如何用 tcpdump 和 wireshark 分析網(wǎng)絡(luò)流量?


          8 個常用的 Wireshark 使用技巧


          Wireshark 的抓包和分析,看這篇就夠了!


          tcpdump / wireshark 抓包及分析


          Wireshark 抓包,帶你快速入門

          瀏覽 56
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲欧美bt | 亚洲婷婷五月天 | 久久精品苍井空免费一区 | 韩日一级视频 | 最近中文字幕免费mv第一季歌词強上 |