要明白一個知識點(diǎn),首先要快速的對這個知識點(diǎn)建立一個概念模型,有了概念模型之后,再在這個模型上不斷的去填充一些細(xì)節(jié)的東西,會有助于我們把握知識的本質(zhì)。
帶寬是什么?
帶寬是網(wǎng)絡(luò)被發(fā)送的能力,它會受到網(wǎng)卡復(fù)制網(wǎng)絡(luò)包到內(nèi)核緩沖區(qū)或者搬運(yùn)內(nèi)核緩沖區(qū)的網(wǎng)絡(luò)包到網(wǎng)卡緩沖區(qū)能力的影響,也會受到接收窗口或擁塞窗口的影響,也就是說如果對端接收能力變小,那么帶寬是不能提升上去的。
當(dāng)整個網(wǎng)絡(luò)的鏈路變長以后,網(wǎng)絡(luò)的情況是很復(fù)雜的。網(wǎng)絡(luò)包有可能會經(jīng)過多個路由器或者不同運(yùn)營商之間的線路去進(jìn)行數(shù)據(jù)交換,而不同代理商之間的網(wǎng)絡(luò)流量是極其龐大的,它會導(dǎo)致你的網(wǎng)絡(luò)包產(chǎn)生丟包或者重發(fā)的狀況,針對于這種情況,平時在部署服務(wù)節(jié)點(diǎn)時候,如果有能力在設(shè)計鏈路的時候最好能夠避免這種不同代理商之間的網(wǎng)絡(luò)交換,優(yōu)化整個網(wǎng)絡(luò)傳輸?shù)逆溌愤x擇能力,這也是cdn提供全局加速的一個原理。
cdn原理是能夠在世界各地部署很多個節(jié)點(diǎn),然后每個節(jié)點(diǎn)之間的一個鏈路選擇是通過服務(wù)運(yùn)營商精心編排過的,它能夠保證你的整個網(wǎng)絡(luò)的鏈路是經(jīng)過優(yōu)化的,能夠讓你的網(wǎng)絡(luò)包更少的產(chǎn)生丟包或者是重發(fā)的狀況。
網(wǎng)絡(luò)包的收發(fā)過程
我們得明白一個網(wǎng)絡(luò)包是如何經(jīng)過應(yīng)用程序的,
一般應(yīng)用程序發(fā)起一個網(wǎng)絡(luò)請求,這個網(wǎng)絡(luò)請求的數(shù)據(jù)會寫到內(nèi)核的套接字緩沖區(qū)當(dāng)中,然后內(nèi)核會對這個套接字緩沖區(qū)的數(shù)據(jù)去加上tcp頭或udp頭,然后又經(jīng)由ip層,再加上一個ip頭,中間會經(jīng)過防火墻的一系列規(guī)則對這個網(wǎng)絡(luò)包進(jìn)行過濾,看是丟棄還是繼續(xù)往網(wǎng)卡上面去發(fā)送,最終到達(dá)鏈路層之后,這個網(wǎng)絡(luò)包會經(jīng)由鏈路層去發(fā)到網(wǎng)卡上的環(huán)形緩沖區(qū)上,最后由網(wǎng)卡發(fā)送到整個網(wǎng)絡(luò)當(dāng)中,其中每一環(huán)都是有可能會發(fā)生丟包的。
理解了網(wǎng)絡(luò)包的收發(fā)過程,建立起了這樣一種概念模型之后,會有助于我們對丟包問題的排查。
如何去衡量網(wǎng)絡(luò)情況的好壞
對應(yīng)用服務(wù)進(jìn)行監(jiān)控的時候,如何去衡量網(wǎng)絡(luò)情況的好壞,一般也用來衡量硬件資源的好壞。
一個通用套路,一般我們會先看一下,在系統(tǒng)層面上網(wǎng)絡(luò)指標(biāo)的一個表現(xiàn),再看下具體是哪個進(jìn)程造成這種表現(xiàn)的異常,再去定位到問題代碼。
具體對網(wǎng)絡(luò)而言,如何從系統(tǒng)的層面或者是我們要使用哪些工具去看這個網(wǎng)絡(luò)的好壞?
從系統(tǒng)層面看網(wǎng)絡(luò)有幾個重要的指標(biāo),MBS 代表網(wǎng)卡每秒發(fā)送多少或者是接收多少個M字節(jié),Mbps是每秒多少M(fèi)比特位。通常說的帶寬的單位就是Mbps,一般100M帶寬的話換算成MBS等于Mbps除以8。
平時選擇服務(wù)器節(jié)點(diǎn)的時候,除了帶寬,還有pps就是每秒發(fā)送、接收包的數(shù)量,它也是有限制的。
當(dāng)我們在遇到網(wǎng)絡(luò)性能問題的時候,首先可以去觀察你的機(jī)器節(jié)點(diǎn)上這兩個指標(biāo)是否是已經(jīng)達(dá)到了一個瓶頸的狀態(tài)。如果帶寬只有100Mbps,然后通過工具查看機(jī)器上面的節(jié)點(diǎn)帶寬,馬上就要超過這個值的時候,很有可能這個時候帶寬已經(jīng)成為瓶頸,可能要對機(jī)器的配額去進(jìn)行升級。
sar
# 使用sar每一秒統(tǒng)計一次網(wǎng)絡(luò)接口的活動狀況,連續(xù)顯示5次 sar -n DEV 1 5
IFACE是網(wǎng)卡接口名稱
rxpck/s、txpck/s 每秒收或發(fā)的數(shù)據(jù)包數(shù)量
rxkB/s、txkB/s 每秒收或發(fā)的字節(jié)數(shù),以kB/s為單位
rxcmp/s、txcmp/s 每秒收或發(fā)的壓縮過的數(shù)據(jù)包數(shù)量
rxmcst/s 每秒收到的多播(多播是一點(diǎn)對多點(diǎn)的通信)數(shù)據(jù)包
看完了整個系統(tǒng)層面的網(wǎng)絡(luò)情況,可以再精細(xì)點(diǎn)的從進(jìn)程的角度去看這個問題。
iftop
# yum -y install libpcap libpcap-devel ncurses ncurses-devel yum install epel-release yum install -y iftop iftop -P
能夠列出這個系統(tǒng)里面每一條鏈接的一個Mbps,能夠找出哪個ip消耗流量最多。更多的時候其實不是系統(tǒng)網(wǎng)絡(luò)達(dá)到瓶頸,而是進(jìn)程處理網(wǎng)絡(luò)包的能力跟不上。
nethogs
yum install nethogs # 查看進(jìn)程占用帶寬的情況 nethogs ens33
列出每個進(jìn)程的收發(fā)流量的數(shù)據(jù),找出哪個進(jìn)程是最消耗流量的,能夠更方便的讓我們?nèi)ザㄎ荒膫€進(jìn)程出的問題。
go trace這個工具能夠去分析出網(wǎng)絡(luò)調(diào)度帶來的延遲問題,其實也能夠從側(cè)面去反饋出你的程序在某一塊代碼上面可能是在進(jìn)行頻繁的網(wǎng)絡(luò)調(diào)度,有可能是進(jìn)行頻繁調(diào)度之后,比較消耗帶寬,從而可能間接的反映出延遲會略有提高,go trace也能夠從讓我們在網(wǎng)絡(luò)性能問題當(dāng)中能夠比較間接去找出一塊問題的代碼。
網(wǎng)絡(luò)性能當(dāng)中比較重要的一個點(diǎn)就是如何查找你的一個丟包問題,對于上面的圖[網(wǎng)絡(luò)包傳輸過程],從上到下依次分析,先看應(yīng)用層,通過listen這個方法去監(jiān)聽套接字的時候,在三次握手的時候,會有兩個隊列,首先服務(wù)器接收到客戶端的syn包的時候,會創(chuàng)建一個半連接隊列 ,這個半連接隊列會將那些還沒有完成三次握手但是卻發(fā)送了一個syn包的這種連接放到里面,會回復(fù)客戶端一個syn+ack,客戶端收到了這個ack和syn包之后,會回復(fù)給服務(wù)端一個ack,這個時候內(nèi)核就會將這個連接放到全連接隊列,當(dāng)服務(wù)器調(diào)用accept方法的時候,會將這條連接從全連接隊列里取出來,所以這個時候涉及了兩個隊列,如果這兩個隊列滿了的話,就會可能會產(chǎn)生丟包的行為。
首先來看一下半連接隊列,它是由內(nèi)核參數(shù)決定的,這個也是可以調(diào)整的。通過三次握手,才能夠去建立連接,但是由于這種隊列的機(jī)制很有可能在并發(fā)量大的時候,會產(chǎn)生隊列滿了,然后丟包的行為,所以內(nèi)核提供了一個tcp_syncookies參數(shù),它能夠去啟用tcp_syncookies這個機(jī)制,當(dāng)半連接隊列溢出的時候,它能夠讓內(nèi)核不直接去丟棄這個新包,而是回復(fù)帶有syncookie的包,這個時候客戶端再去向服務(wù)器進(jìn)行請求的時候,它會去驗證這個syncookie,這樣能夠防止半連接隊列溢出的時候造成服務(wù)不可用的一個情況。
如何去確定是由于半連接隊列溢出導(dǎo)致的丟包?
通過dmesg去日志里面去搜尋tcp drop,是能夠發(fā)現(xiàn)丟包的情況,dmesg是一個內(nèi)核的日志記錄,我們能夠從里面去找出一些內(nèi)核的行為,
dmesg|grep "TCP: drop open erquest form"
然后看下全連接隊列該怎么看,通過ss命令的話,能夠去看到你的服務(wù)在listen的時候,全連接隊列的大小
ss -lnt # -l 顯示正在監(jiān)聽 # -n 不解析服務(wù)名稱 # -t 只顯示 tcp socket
對于你的那個監(jiān)聽服務(wù)而言,它的一個Send-Q,就是代表當(dāng)前全連接隊列長度,也就是當(dāng)前已完成三次握手并等待服務(wù)端 accept() 的 TCP 連接。Recv-Q是指當(dāng)前全連接隊列的大小,上面的輸出結(jié)果說明監(jiān)聽 9000 端口的 TCP 服務(wù),最大全連接長度為 128。Recv-Q一般都是為0,如果存在一種大于0的情況并且會持續(xù)一個較長時間的話,就說明你的服務(wù)處理連接的能力比較慢了,會導(dǎo)致全連接隊列過滿或者丟棄,這個時候應(yīng)該會加快你的服務(wù)處理連接的能力。
ss命令對于狀態(tài)為ESTAB的連接,它看的不是你這個監(jiān)聽服務(wù),而是去看一條已經(jīng)建立好的連接相關(guān)指標(biāo),Recv-Q是代表收到但未被應(yīng)用程序讀取的一個字節(jié)數(shù),Send-Q已發(fā)送但未收到確認(rèn)的字節(jié)數(shù),通過這兩個指標(biāo),能夠去看到是應(yīng)用程序?qū)σ粋€數(shù)據(jù)的處理能力慢,還是說是客戶端對接收的數(shù)據(jù)處理的比較慢的情況,一般這兩個值也都是為0,如果有其中一個不為0 ,你可能要去排查一下是客戶端的問題還是服務(wù)器的問題。
當(dāng)全連接隊列滿了之后,內(nèi)核默認(rèn)會將包丟棄,但是也已可指定內(nèi)核的一個其他行為,如果是將tcp_abort_on_overflow這個值設(shè)為1的話,那會直接發(fā)一個reset的包給客戶端,直接將這個連接斷開掉,表示廢掉這個握手過程和這個連接。
經(jīng)過應(yīng)用層之后,網(wǎng)絡(luò)包會到達(dá)到傳輸層,傳輸層會有防火墻的存在,如果防火墻開啟的話,那和防火墻有關(guān)的連接跟蹤表:nf_conntrack這個是linux為每個經(jīng)過內(nèi)核網(wǎng)絡(luò)棧的數(shù)據(jù)包,會生成一個連接的記錄項,當(dāng)服務(wù)器處理過多時,這個連接記錄項所在的連接跟蹤表就會被打滿,然后服務(wù)器就會丟棄新建連接的數(shù)據(jù)包,所以有時候丟包有可能是防火墻的連接跟蹤表設(shè)計的太小了。
那如何去看連接跟蹤表的大小呢
# 查看nf_conntrack表最大連接數(shù) cat /proc/sys/net/netfilter/nf_conntrack_max # 查看nf_conntrack表當(dāng)前連接數(shù) cat /proc/sys/net/netfilter/nf_conntrack_count
通過這個文件看連接跟蹤表的一個最大連接數(shù)nf_conntrack_max,所以在丟包的時候,可以對這一部分去進(jìn)行排查,看下連接跟蹤表是不是被打滿了。
網(wǎng)絡(luò)包經(jīng)過傳輸層之后,再來看網(wǎng)絡(luò)層和物理層,提到網(wǎng)絡(luò)層和物理層,就要看網(wǎng)卡了,通過netstat命令,能夠去看整個機(jī)器上面網(wǎng)卡的丟包和收包的情況。
RX-DRP這個指標(biāo)數(shù)據(jù),如果它大于0,說明這個網(wǎng)卡是有丟包情況,這里記錄的是從開機(jī)到目前為止的數(shù)據(jù)情況,所以在分析的時候,隔一定的時間去看這個指標(biāo)是否有上漲。
RX-OVR指標(biāo)說明這個網(wǎng)卡的環(huán)形緩沖區(qū)滿了之后產(chǎn)生的丟棄行為。
通過netstat能夠分析網(wǎng)卡丟包的情況,
# netstat可以統(tǒng)計網(wǎng)路丟包以及環(huán)形緩沖區(qū)溢出 netstat -i
netstat還能夠統(tǒng)計網(wǎng)絡(luò)協(xié)議層的丟包情況,
MTU
應(yīng)用層的網(wǎng)絡(luò)包通過網(wǎng)絡(luò)層的時候會根據(jù)數(shù)據(jù)包的大小去進(jìn)行分包發(fā)送。
當(dāng)tcp數(shù)據(jù)包的大小發(fā)送網(wǎng)絡(luò)層之后,網(wǎng)絡(luò)層發(fā)現(xiàn)這個包會大于它的mtu值,這個數(shù)據(jù)包會進(jìn)行一個分包的操作。在進(jìn)行網(wǎng)卡設(shè)置的時候,會設(shè)置為你的傳輸層包,如果大于了mtu這個值,那就可以直接將這個網(wǎng)絡(luò)包丟棄,這也是在現(xiàn)實生活中經(jīng)常會碰到的一個丟包問題。
所以你在檢查鏈路的時候,通常鏈路長了可能不太好排查,鏈路短一點(diǎn),可能會很容易看到整條鏈路當(dāng)中mtu的情況,看一下是不是每條鏈路上對應(yīng)的每個網(wǎng)卡的mtu指標(biāo)是不一樣的,如果不一樣的話,有可能會造成你的丟包問題,因為一個包的轉(zhuǎn)發(fā)跟網(wǎng)絡(luò)上面設(shè)置的mtu值大小有關(guān)系,比如設(shè)置為大于mtu之后會把這個包給丟棄掉。如果發(fā)送的mtu包的大小超過網(wǎng)卡規(guī)定的大小,并且網(wǎng)卡不允許分片,那么則會產(chǎn)生丟包。
審核編輯:劉清
-
網(wǎng)絡(luò)協(xié)議
+關(guān)注
關(guān)注
3文章
273瀏覽量
21949 -
路由器
+關(guān)注
關(guān)注
22文章
3790瀏覽量
115640 -
UDP協(xié)議
+關(guān)注
關(guān)注
0文章
70瀏覽量
13000 -
MBS
+關(guān)注
關(guān)注
0文章
6瀏覽量
8361 -
TCP通信
+關(guān)注
關(guān)注
0文章
146瀏覽量
4420
原文標(biāo)題:如何排查網(wǎng)絡(luò)丟包問題
文章出處:【微信號:LinuxHub,微信公眾號:Linux愛好者】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
基于UDP協(xié)議的網(wǎng)絡(luò)通信應(yīng)用程序
基于TCP/IP的網(wǎng)絡(luò)通信應(yīng)用程序分享
OpenHarmony應(yīng)用程序包整體說明
proteus8.6應(yīng)用程序安裝包免費(fèi)下載

Protel DXP軟件安裝包應(yīng)用程序免費(fèi)下載

演示一個基本的藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)照明應(yīng)用程序
嵌入式Linux應(yīng)用程序開發(fā)-(1)第一個嵌入式QT應(yīng)用程序

嵌入式Linux應(yīng)用程序開發(fā)-(9)UDP網(wǎng)絡(luò)通信應(yīng)用程序(UDP-Socket)

構(gòu)建一個移動應(yīng)用程序

OneInstall Windows驅(qū)動程序和應(yīng)用程序工具包

OneInstall Windows驅(qū)動程序和應(yīng)用程序工具包分享

OneInstall驅(qū)動程序和應(yīng)用程序工具包為Windows

OneInstall Windows驅(qū)動和應(yīng)用程序工具包

如何使用Tokio 和 Tracing模塊構(gòu)建異步的網(wǎng)絡(luò)應(yīng)用程序
網(wǎng)絡(luò)丟包問題解析

評論