天天看點

如何排查網絡丢包問題

要明白一個知識點,首先要快速的對這個知識點建立一個概念模型,有了概念模型之後,再在這個模型上不斷的去填充一些細節的東西,會有助于我們把握知識的本質。

帶寬是什麼?

帶寬是網絡被發送的能力,它會受到網卡複制網絡包到核心緩沖區或者搬運核心緩沖區的網絡包到網卡緩沖區能力的影響,也會受到接收視窗或擁塞視窗的影響,也就是說如果對端接收能力變小,那麼帶寬是不能提升上去的。

當整個網絡的鍊路變長以後,網絡的情況是很複雜的。網絡包有可能會經過多個路由器或者不同營運商之間的線路去進行資料交換,而不同代理商之間的網絡流量是極其龐大的,它會導緻你的網絡包産生丢包或者重發的狀況,針對于這種情況,平時在部署服務節點時候,如果有能力在設計鍊路的時候最好能夠避免這種不同代理商之間的網絡交換,優化整個網絡傳輸的鍊路選擇能力,這也是cdn提供全局加速的一個原理。

cdn原理是能夠在世界各地部署很多個節點,然後每個節點之間的一個鍊路選擇是通過服務營運商精心編排過的,它能夠保證你的整個網絡的鍊路是經過優化的,能夠讓你的網絡包更少的産生丢包或者是重發的狀況。

網絡包的收發過程

我們得明白一個網絡包是如何經過應用程式的,

如何排查網絡丢包問題

一般應用程式發起一個網絡請求,這個網絡請求的資料會寫到核心的套接字緩沖區當中,然後核心會對這個套接字緩沖區的資料去加上tcp頭或udp頭,然後又經由ip層,再加上一個ip頭,中間會經過防火牆的一系列規則對這個網絡包進行過濾,看是丢棄還是繼續往網卡上面去發送,最終到達鍊路層之後,這個網絡包會經由鍊路層去發到網卡上的環形緩沖區上,最後由網卡發送到整個網絡當中,其中每一環都是有可能會發生丢包的。

了解了網絡包的收發過程,建立起了這樣一種概念模型之後,會有助于我們對丢包問題的排查。

相關視訊推薦

LinuxC++零拷貝的實作 使用者态協定棧 ntytcp

支撐網際網路的基石 tcpip,5個方面全面解析

TCP/IP協定棧深度解析丨實作單機百萬連接配接丨優化三次握手、四次揮手

LinuxC++背景伺服器開發架構師免費學習位址

【文章福利】:小編整理了一些個人覺得比較好的學習書籍、視訊資料共享在群檔案裡面,有需要的可以自行添加哦!~點選832218493加入(需要自取)

如何排查網絡丢包問題

如何去衡量網絡情況的好壞

對應用服務進行監控的時候,如何去衡量網絡情況的好壞,一般也用來衡量硬體資源的好壞。

一個通用套路,一般我們會先看一下,在系統層面上網絡名額的一個表現,再看下具體是哪個程序造成這種表現的異常,再去定位到問題代碼。

具體對網絡而言,如何從系統的層面或者是我們要使用哪些工具去看這個網絡的好壞?

從系統層面看網絡有幾個重要的名額,MBS 代表網卡每秒發送多少或者是接收多少個M位元組,Mbps是每秒多少M比特位。通常說的帶寬的機關就是Mbps,一般100M帶寬的話換算成MBS等于Mbps除以8。

平時選擇伺服器節點的時候,除了帶寬,還有pps就是每秒發送、接收包的數量,它也是有限制的。

當我們在遇到網絡性能問題的時候,首先可以去觀察你的機器節點上這兩個名額是否是已經達到了一個瓶頸的狀态。如果帶寬隻有100Mbps,然後通過工具檢視機器上面的節點帶寬,馬上就要超過這個值的時候,很有可能這個時候帶寬已經成為瓶頸,可能要對機器的配額去進行更新。

sar

# 使用sar每一秒統計一次網絡接口的活動狀況,連續顯示5次sar -n DEV 15
           
如何排查網絡丢包問題
  • IFACE是網卡接口名稱
  • rxpck/s、txpck/s 每秒收或發的資料包數量
  • rxkB/s、txkB/s 每秒收或發的位元組數,以kB/s為機關
  • rxcmp/s、txcmp/s 每秒收或發的壓縮過的資料包數量
  • rxmcst/s 每秒收到的多點傳播(多點傳播是一點對多點的通信)資料包

看完了整個系統層面的網絡情況,可以再精細點的從程序的角度去看這個問題。

iftop

# https://www.tecmint.com/iftop-linux-network-bandwidth-monitoring-tool/yum  -y install libpcap libpcap-devel ncurses ncurses-develyum install epel-releaseyum install -y iftopiftop -P
           
如何排查網絡丢包問題
如何排查網絡丢包問題

能夠列出這個系統裡面每一條連結的一個Mbps,能夠找出哪個ip消耗流量最多。更多的時候其實不是系統網絡達到瓶頸,而是程序處理網絡包的能力跟不上。

nethogs

yum install nethogs# 檢視程序占用帶寬的情況nethogs ens33
           

列出每個程序的收發流量的資料,找出哪個程序是最消耗流量的,能夠更友善的讓我們去定位哪個程序出的問題。

go trace這個工具能夠去分析出網絡排程帶來的延遲問題,其實也能夠從側面去回報出你的程式在某一塊代碼上面可能是在進行頻繁的網絡排程,有可能是進行頻繁排程之後,比較消耗帶寬,進而可能間接的反映出延遲會略有提高,go trace也能夠從讓我們在網絡性能問題當中能夠比較間接去找出一塊問題的代碼。

如何排查網絡丢包問題

網絡性能當中比較重要的一個點就是如何查找你的一個丢包問題,對于上面的圖[網絡包傳輸過程],從上到下依次分析,先看應用層,通過listen這個方法去監聽套接字的時候,在三次握手的時候,會有兩個隊列,首先伺服器接收到用戶端的syn包的時候,會建立一個半連接配接隊列 ,這個半連接配接隊列會将那些還沒有完成三次握手但是卻發送了一個syn包的這種連接配接放到裡面,會回複用戶端一個syn+ack,用戶端收到了這個ack和syn包之後,會回複給服務端一個ack,這個時候核心就會将這個連接配接放到全連接配接隊列,當伺服器調用accept方法的時候,會将這條連接配接從全連接配接隊列裡取出來,是以這個時候涉及了兩個隊列,如果這兩個隊列滿了的話,就會可能會産生丢包的行為。

如何排查網絡丢包問題
如何排查網絡丢包問題

首先來看一下半連接配接隊列,它是由核心參數決定的,這個也是可以調整的。通過三次握手,才能夠去建立連接配接,但是由于這種隊列的機制很有可能在并發量大的時候,會産生隊列滿了,然後丢包的行為,是以核心提供了一個tcp_syncookies參數,它能夠去啟用tcp_syncookies這個機制,當半連接配接隊列溢出的時候,它能夠讓核心不直接去丢棄這個新包,而是回複帶有syncookie的包,這個時候用戶端再去向伺服器進行請求的時候,它會去驗證這個syncookie,這樣能夠防止半連接配接隊列溢出的時候造成服務不可用的一個情況。

如何去确定是由于半連接配接隊列溢出導緻的丢包?

通過dmesg去日志裡面去搜尋tcp drop,是能夠發現丢包的情況,dmesg是一個核心的日志記錄,我們能夠從裡面去找出一些核心的行為,

dmesg|grep"TCP: drop open erquest form"
           

然後看下全連接配接隊列該怎麼看,通過ss指令的話,能夠去看到你的服務在listen的時候,全連接配接隊列的大小

ss -lnt# -l 顯示正在監聽 # -n 不解析服務名稱# -t 隻顯示 tcp socket
           
如何排查網絡丢包問題

對于你的那個監聽服務而言,它的一個Send-Q,就是代表目前全連接配接隊列長度,也就是目前已完成三次握手并等待服務端 accept() 的 TCP 連接配接。Recv-Q是指目前全連接配接隊列的大小,上面的輸出結果說明監聽 9000 端口的 TCP 服務,最大全連接配接長度為 128。Recv-Q一般都是為0,如果存在一種大于0的情況并且會持續一個較長時間的話,就說明你的服務處理連接配接的能力比較慢了,會導緻全連接配接隊列過滿或者丢棄,這個時候應該會加快你的服務處理連接配接的能力。

ss指令對于狀态為ESTAB的連接配接,它看的不是你這個監聽服務,而是去看一條已經建立好的連接配接相關名額,Recv-Q是代表收到但未被應用程式讀取的一個位元組數,Send-Q已發送但未收到确認的位元組數,通過這兩個名額,能夠去看到是應用程式對一個資料的處理能力慢,還是說是用戶端對接收的資料處理的比較慢的情況,一般這兩個值也都是為0,如果有其中一個不為0 ,你可能要去排查一下是用戶端的問題還是伺服器的問題。

當全連接配接隊列滿了之後,核心預設會将包丢棄,但是也已可指定核心的一個其他行為,如果是将tcp_abort_on_overflow這個值設為1的話,那會直接發一個reset的包給用戶端,直接将這個連接配接斷開掉,表示廢掉這個握手過程和這個連接配接。

經過應用層之後,網絡包會到達到傳輸層,傳輸層會有防火牆的存在,如果防火牆開啟的話,那和防火牆有關的連接配接跟蹤表:nf_conntrack這個是linux為每個經過核心網絡棧的資料包,會生成一個連接配接的記錄項,當伺服器處理過多時,這個連接配接記錄項所在的連接配接跟蹤表就會被打滿,然後伺服器就會丢棄建立連接配接的資料包,是以有時候丢包有可能是防火牆的連接配接跟蹤表設計的太小了。

那如何去看連接配接跟蹤表的大小呢

# 檢視nf_conntrack表最大連接配接數cat /proc/sys/net/netfilter/nf_conntrack_max# 檢視nf_conntrack表目前連接配接數cat /proc/sys/net/netfilter/nf_conntrack_count
           
如何排查網絡丢包問題

通過這個檔案看連接配接跟蹤表的一個最大連接配接數nf_conntrack_max,是以在丢包的時候,可以對這一部分去進行排查,看下連接配接跟蹤表是不是被打滿了。

網絡包經過傳輸層之後,再來看網絡層和實體層,提到網絡層和實體層,就要看網卡了,通過netstat指令,能夠去看整個機器上面網卡的丢包和收包的情況。

RX-DRP這個名額資料,如果它大于0,說明這個網卡是有丢包情況,這裡記錄的是從開機到目前為止的資料情況,是以在分析的時候,隔一定的時間去看這個名額是否有上漲。

RX-OVR名額說明這個網卡的環形緩沖區滿了之後産生的丢棄行為。

通過netstat能夠分析網卡丢包的情況,

# netstat可以統計網路丢包以及環形緩沖區溢出netstat -i
           
如何排查網絡丢包問題

netstat還能夠統計網絡協定層的丢包情況,

如何排查網絡丢包問題

MTU

應用層的網絡包通過網絡層的時候會根據資料包的大小去進行分包發送。

當tcp資料包的大小發送網絡層之後,網絡層發現這個包會大于它的mtu值,這個資料包會進行一個分包的操作。在進行網卡設定的時候,會設定為你的傳輸層包,如果大于了mtu這個值,那就可以直接将這個網絡包丢棄,這也是在現實生活中經常會碰到的一個丢包問題。

是以你在檢查鍊路的時候,通常鍊路長了可能不太好排查,鍊路短一點,可能會很容易看到整條鍊路當中mtu的情況,看一下是不是每條鍊路上對應的每個網卡的mtu名額是不一樣的,如果不一樣的話,有可能會造成你的丢包問題,因為一個包的轉發跟網絡上面設定的mtu值大小有關系,比如設定為大于mtu之後會把這個包給丢棄掉。如果發送的mtu包的大小超過網卡規定的大小,并且網卡不允許分片,那麼則會産生丢包。

繼續閱讀