0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線(xiàn)課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

分享一個(gè)比較常見(jiàn)的?絡(luò)問(wèn)題--丟包

Linux閱碼場(chǎng) ? 來(lái)源:Linuxer ? 作者:Linuxer ? 2021-03-11 11:26 ? 次閱讀

引言

本期分享一個(gè)比較常見(jiàn)的?絡(luò)問(wèn)題--丟包。例如我們?nèi)?a href="http://ttokpm.com/tags/pi/" target="_blank">ping?個(gè)?站,如果能ping通,且?站返回信息全?,則說(shuō)明與?站服務(wù)器的通信是暢通的,如果ping不通,或者?站返回的信息不全等,則很可能是數(shù)據(jù)被丟包了,類(lèi)似情況想必?家都不陌?。針對(duì)?絡(luò)丟包,本?提供?些常見(jiàn)的丟包故障定位?法,希望能夠幫助?家對(duì)?絡(luò)丟包有更多的認(rèn)識(shí),遇到丟包莫要慌,且跟著?起來(lái)漲姿(知)勢(shì)(識(shí))···

什么是丟包

數(shù)據(jù)在Internet上是以數(shù)據(jù)包為單位傳輸?shù)?,單位為字?jié),數(shù)據(jù)在?絡(luò)上傳輸,受?絡(luò)設(shè)備,?絡(luò)質(zhì)量等原因的影響,使得接收到的數(shù)據(jù)?于發(fā)送出去的數(shù)據(jù),造成丟包。

數(shù)據(jù)包接收、發(fā)送原理

發(fā)送數(shù)據(jù)包:

1.應(yīng)?程序的數(shù)據(jù)包,在TCP層增加TCP報(bào)?頭,形成可傳輸?shù)臄?shù)據(jù)包。
2.在IP層增加IP報(bào)頭,形成IP報(bào)?。
3.經(jīng)過(guò)數(shù)據(jù)?卡驅(qū)動(dòng)程序?qū)P包再添加14字節(jié)的MAC頭,構(gòu)成frame(暫?CRC),frame(暫?CRC)中含有發(fā)送端和接收端的MAC地址。
4.驅(qū)動(dòng)程序?qū)rame(暫?CRC)拷貝到?卡的緩沖區(qū),由?卡處理。
5.?卡為frame(暫?CRC)添加頭部同步信息和CRC校驗(yàn),將其封裝為可以發(fā)送的packet,然后再發(fā)送到?線(xiàn)上,這樣說(shuō)就完成了?個(gè)IP報(bào)?的發(fā)送了,所有連接到這個(gè)?線(xiàn)上的?卡都可以看到該packet。

接收數(shù)據(jù)包:

c0c9d134-7de1-11eb-8b86-12bb97331649.png

1.?卡收到?線(xiàn)上的packet,?先檢查packet的CRC校驗(yàn),保證完整性,然后將packet頭去掉,得到frame。(?卡會(huì)檢查MAC包內(nèi)的?的MAC地址是否和本?卡的MAC地址?樣,不?樣則會(huì)丟棄。)
2.?卡將frame拷貝到預(yù)分配的ring buffer緩沖。
3.?卡驅(qū)動(dòng)程序通知內(nèi)核處理,經(jīng)過(guò)TCP/IP協(xié)議棧層層解碼處理。
4.應(yīng)?程序從socket buffer 中讀取數(shù)據(jù)。

核心思路

了解了收發(fā)包的原理,可以了解到丟包原因主要會(huì)涉及?卡設(shè)備、?卡驅(qū)動(dòng)、內(nèi)核協(xié)議棧三?類(lèi)。以下我們將遵循“從下到上分層分析(各層可能性出現(xiàn)的丟包場(chǎng)景),然后查看關(guān)鍵信息,最終得出分析結(jié)果”的原則展開(kāi)介紹。

目錄--網(wǎng)絡(luò)丟包情形概覽

> 硬件網(wǎng)卡丟包

> 網(wǎng)卡驅(qū)動(dòng)丟包

> 以太網(wǎng)鏈路層丟包

> 網(wǎng)絡(luò)IP層丟包

> 傳輸層UDP/TCP丟包

> 應(yīng)用層socket丟包

針對(duì)以上6種情形,分別作出如下詳述~

硬件網(wǎng)卡丟包

Ring Buffer溢出

c2781194-7de1-11eb-8b86-12bb97331649.png

如圖所示,物理介質(zhì)上的數(shù)據(jù)幀到達(dá)后首先由NIC(網(wǎng)絡(luò)適配器)讀取,寫(xiě)入設(shè)備內(nèi)部緩沖區(qū)Ring Buffer中,再由中斷處理程序觸發(fā)Softirq從中消費(fèi),Ring Buffer的大小因網(wǎng)卡設(shè)備而異。當(dāng)網(wǎng)絡(luò)數(shù)據(jù)包到達(dá)(生產(chǎn))的速率快于內(nèi)核處理(消費(fèi))的速率時(shí),Ring Buffer很快會(huì)被填滿(mǎn),新來(lái)的數(shù)據(jù)包將被丟棄;

查看:

通過(guò)ethtool或/proc/net/dev可以查看因Ring Buffer滿(mǎn)而丟棄的包統(tǒng)計(jì),在統(tǒng)計(jì)項(xiàng)中以fifo標(biāo)識(shí):

$ ethtool -S eth0|grep rx_fiforx_fifo_errors: 0$ cat /proc/net/devInter-|Receive|Transmitface|bytespacketserrsdropfifoframecompressedmulticast|bytes packets errs drop fifo colls carrier compressedeth0: 17253386680731 42839525880 0 0 0 0 0 244182022 14879545018057 41657801805 0 0 0 0 0 0#查看eth0網(wǎng)卡RingBuffer最大值和當(dāng)前設(shè)置

$ ethtool -g eth0解決方案:修改網(wǎng)卡eth0接收與發(fā)送硬件緩存區(qū)大小

$ ethtool -G eth0 rx 4096 tx 4096

網(wǎng)卡端口協(xié)商丟包

1. 查看網(wǎng)卡丟包統(tǒng)計(jì):ethtool -S eth1/eth0

2. 查看網(wǎng)卡配置狀態(tài):ethtool eth1/eth0

主要查看網(wǎng)卡和上游網(wǎng)絡(luò)設(shè)備協(xié)商速率和模式是否符合預(yù)期;

解決方案:

1 重新自協(xié)商: ethtool -r eth1/eth0;

2 如果上游不支持自協(xié)商,可以強(qiáng)制設(shè)置端口速率:

ethtool -s eth1 speed 1000 duplex full autoneg off

網(wǎng)卡流控丟包

1. 查看流控統(tǒng)計(jì):

ethtool -S eth1 | grep control

rx_flow_control_xon是在網(wǎng)卡的RX Buffer滿(mǎn)或其他網(wǎng)卡內(nèi)部的資源受限時(shí),給交換機(jī)端口發(fā)送的開(kāi)啟流控的pause幀計(jì)數(shù)。對(duì)應(yīng)的,tx_flow_control_xoff是在資源可用之后發(fā)送的關(guān)閉流控的pause幀計(jì)數(shù)。

2 .查看網(wǎng)絡(luò)流控配置:ethtool -a eth1

解決方案:關(guān)閉網(wǎng)卡流控

ethtool -A ethx autoneg off //自協(xié)商關(guān)閉ethtool -A ethx tx off //發(fā)送模塊關(guān)閉ethtool -A ethx rx off //接收模塊關(guān)閉

報(bào)文mac地址丟包

一般計(jì)算機(jī)網(wǎng)卡都工作在非混雜模式下,此時(shí)網(wǎng)卡只接受來(lái)自網(wǎng)絡(luò)端口的目的地址指向自己的數(shù)據(jù),如果報(bào)文的目的mac地址不是對(duì)端的接口的mac地址,一般都會(huì)丟包,一般這種情況很有可能是源端設(shè)置靜態(tài)arp表項(xiàng)或者動(dòng)態(tài)學(xué)習(xí)的arp表項(xiàng)沒(méi)有及時(shí)更新,但目的端mac地址已發(fā)生變化(換了網(wǎng)卡),沒(méi)有更新通知到源端(比如更新報(bào)文被丟失,中間交換機(jī)異常等情況);

查看:

1.目的端抓包,tcpdump可以開(kāi)啟混雜模式,可以抓到對(duì)應(yīng)的報(bào)文,然后查看mac地址;

2.源端查看arp表或者抓包(上一跳設(shè)備),看發(fā)送的mac地址是否和下一跳目的端的mac地址一致;

解決方案:

1.刷新arp表然后發(fā)包觸發(fā)arp重新學(xué)習(xí)(可能影響其他報(bào)文,增加延時(shí),需要小心操作);

2.可以在源端手動(dòng)設(shè)置正確的靜態(tài)的arp表項(xiàng);

其他網(wǎng)卡異常丟包

這類(lèi)異常比少見(jiàn),但如果都不是上面哪些情況,但網(wǎng)卡統(tǒng)計(jì)里面任然有丟包計(jì)數(shù),可以試著排查一下:

網(wǎng)卡firmware版本:

排查一下網(wǎng)卡phy芯片firmware是不是有bug,安裝的版本是不是符合預(yù)期,查看 ethtool -i eth1:

和廠家提case詢(xún)問(wèn)是不是已知問(wèn)題,有沒(méi)有新版本等;

網(wǎng)線(xiàn)接觸不良:

如果網(wǎng)卡統(tǒng)計(jì)里面存在crc error 計(jì)數(shù)增長(zhǎng),很可能是網(wǎng)線(xiàn)接觸不良,可以通知網(wǎng)管排查一下:

ethtool -S eth0

解決方案:一般試著重新插拔一下網(wǎng)線(xiàn),或者換一根網(wǎng)線(xiàn),排查插口是否符合端口規(guī)格等;

報(bào)文長(zhǎng)度丟包

網(wǎng)卡有接收正確報(bào)文長(zhǎng)度范圍,一般正常以太網(wǎng)報(bào)文長(zhǎng)度范圍:64-1518,發(fā)送端正常情況會(huì)填充或者分片來(lái)適配,偶爾會(huì)發(fā)生一些異常情況導(dǎo)致發(fā)送報(bào)文不正常丟包;


查看:

ethtool-Seth1|greplength_errors

解決方案:

1 調(diào)整接口MTU配置,是否開(kāi)啟支持以太網(wǎng)巨幀;

2 發(fā)送端開(kāi)啟PATH MTU進(jìn)行合理分片;

簡(jiǎn)單總結(jié)一下網(wǎng)卡丟包:

c3f11660-7de1-11eb-8b86-12bb97331649.png

網(wǎng)卡驅(qū)動(dòng)丟包

查看:ifconfig eth1/eth0 等接口

1.RX errors: 表示總的收包的錯(cuò)誤數(shù)量,還包括too-long-frames錯(cuò)誤,Ring Buffer 溢出錯(cuò)誤,crc 校驗(yàn)錯(cuò)誤,幀同步錯(cuò)誤,fifo overruns 以及 missed pkg 等等。

2.RX dropped: 表示數(shù)據(jù)包已經(jīng)進(jìn)入了 Ring Buffer,但是由于內(nèi)存不夠等系統(tǒng)原因,導(dǎo)致在拷貝到內(nèi)存的過(guò)程中被丟棄。

3.RX overruns: 表示了 fifo 的 overruns,這是由于 Ring Buffer(aka Driver Queue) 傳輸?shù)?IO 大于 kernel 能夠處理的 IO 導(dǎo)致的,而 Ring Buffer 則是指在發(fā)起 IRQ 請(qǐng)求之前的那塊 buffer。很明顯,overruns 的增大意味著數(shù)據(jù)包沒(méi)到 Ring Buffer 就被網(wǎng)卡物理層給丟棄了,而 CPU 無(wú)法即使的處理中斷是造成 Ring Buffer 滿(mǎn)的原因之一,上面那臺(tái)有問(wèn)題的機(jī)器就是因?yàn)?interruprs 分布的不均勻(都?jí)涸?core0),沒(méi)有做 affinity 而造成的丟包。

4. RX frame: 表示 misaligned 的 frames。

5. 對(duì)于 TX 的來(lái)說(shuō),出現(xiàn)上述 counter 增大的原因主要包括 aborted transmission, errors due to carrirer, fifo error, heartbeat erros 以及 windown error,而 collisions 則表示由于 CSMA/CD 造成的傳輸中斷。

驅(qū)動(dòng)溢出丟包

netdev_max_backlog是內(nèi)核從NIC收到包后,交由協(xié)議棧(如IP、TCP)處理之前的緩沖隊(duì)列。每個(gè)CPU核都有一個(gè)backlog隊(duì)列,與Ring Buffer同理,當(dāng)接收包的速率大于內(nèi)核協(xié)議棧處理的速率時(shí),CPU的backlog隊(duì)列不斷增長(zhǎng),當(dāng)達(dá)到設(shè)定的netdev_max_backlog值時(shí),數(shù)據(jù)包將被丟棄。

查看:

通過(guò)查看/proc/net/softnet_stat可以確定是否發(fā)生了netdev backlog隊(duì)列溢出:

其中:每一行代表每個(gè)CPU核的狀態(tài)統(tǒng)計(jì),從CPU0依次往下;每一列代表一個(gè)CPU核的各項(xiàng)統(tǒng)計(jì):第一列代表中斷處理程序收到的包總數(shù);第二列即代表由于netdev_max_backlog隊(duì)列溢出而被丟棄的包總數(shù)。從上面的輸出可以看出,這臺(tái)服務(wù)器統(tǒng)計(jì)中,并沒(méi)有因?yàn)閚etdev_max_backlog導(dǎo)致的丟包。

解決方案:

netdev_max_backlog的默認(rèn)值是1000,在高速鏈路上,可能會(huì)出現(xiàn)上述第二統(tǒng)計(jì)不為0的情況,可以通過(guò)修改內(nèi)核參數(shù)net.core.netdev_max_backlog來(lái)解決:

$ sysctl -w net.core.netdev_max_backlog=2000

單核負(fù)載高導(dǎo)致丟包

單核CPU軟中斷占有高, 導(dǎo)致應(yīng)用沒(méi)有機(jī)會(huì)收發(fā)或者收包比較慢,即使調(diào)整netdev_max_backlog隊(duì)列大小仍然會(huì)一段時(shí)間后丟包,處理速度跟不上網(wǎng)卡接收的速度;

查看:mpstat -P ALL 1

單核軟中斷占有100%,導(dǎo)致應(yīng)用沒(méi)有機(jī)會(huì)收發(fā)或者收包比較慢而丟包;

解決方案:

1.調(diào)整網(wǎng)卡RSS隊(duì)列配置:

查看:ethtool -x ethx;

調(diào)整:ethtool -X ethx xxxx;

2.看一下網(wǎng)卡中斷配置是否均衡 cat /proc/interrupts

調(diào)整:

1) irqbalance 調(diào)整;# 查看當(dāng)前運(yùn)行情況serviceirqbalancestatus# 終止服務(wù)service irqbalance stop2) 中斷綁CPU核 echo mask > /proc/irq/xxx/smp_affinity

3.根據(jù)CPU和網(wǎng)卡隊(duì)列個(gè)數(shù)調(diào)整網(wǎng)卡多隊(duì)列和RPS配置

-CPU大于網(wǎng)卡隊(duì)列個(gè)數(shù):

查看網(wǎng)卡隊(duì)列 ethtool -x ethx;

協(xié)議棧開(kāi)啟RPS并設(shè)置RPS;

echo $mask(CPU配置)> /sys/class/net/$eth/queues/rx-$i/rps_cpusecho 4096(網(wǎng)卡buff)> /sys/class/net/$eth/queues/rx-$i/rps_flow_cnt2)CPU小于網(wǎng)卡隊(duì)列個(gè)數(shù),綁中斷就可以,可以試著關(guān)閉RPS看一下效果:echo 0 > /sys/class/net//queues/rx-/rps_cpus

4.numa CPU調(diào)整,對(duì)齊網(wǎng)卡位置,可以提高內(nèi)核處理速度,從而給更多CPU給應(yīng)用收包,減緩丟包概率;

查看網(wǎng)卡numa位置:

ethtool -i eth1|grep bus-infolspci -s bus-info -vv|grep node

上面中斷和RPS設(shè)置里面mask需要重新按numa CPU分配重新設(shè)置;

5.可以試著開(kāi)啟中斷聚合(看網(wǎng)卡是否支持)

查看 :

ethtool -c ethxCoalesceparametersforeth1:Adaptive RX: on TX: onstats-block-usecs: 0sample-interval: 0pkt-rate-low: 0pkt-rate-high: 0 rx-usecs: 25rx-frames: 0rx-usecs-irq: 0rx-frames-irq: 256 tx-usecs: 25tx-frames: 0tx-usecs-irq: 0tx-frames-irq: 256 rx-usecs-low: 0rx-frame-low: 0tx-usecs-low: 0tx-frame-low: 0 rx-usecs-high: 0rx-frame-high: 0tx-usecs-high: 0tx-frame-high: 0

調(diào)整:

ethtool -C ethx adaptive-rx on

簡(jiǎn)單總結(jié)一下網(wǎng)卡驅(qū)動(dòng)丟包處理:

內(nèi)核協(xié)議棧丟包

以太網(wǎng)鏈路層丟包

neighbor系統(tǒng)arp丟包

arp_ignore配置丟包

arp_ignore參數(shù)的作用是控制系統(tǒng)在收到外部的arp請(qǐng)求時(shí),是否要返回arp響應(yīng)。arp_ignore參數(shù)常用的取值主要有0,1,2,3~8較少用到;

查看:sysctl -a|grep arp_ignore

解決方案:根據(jù)實(shí)際場(chǎng)景設(shè)置對(duì)應(yīng)值;

0:響應(yīng)任意網(wǎng)卡上接收到的對(duì)本機(jī)IP地址的arp請(qǐng)求(包括環(huán)回網(wǎng)卡上的地址),而不管該目的IP是否在接收網(wǎng)卡上。

1:只響應(yīng)目的IP地址為接收網(wǎng)卡上的本地地址的arp請(qǐng)求。

2:只響應(yīng)目的IP地址為接收網(wǎng)卡上的本地地址的arp請(qǐng)求,并且arp請(qǐng)求的源IP必須和接收網(wǎng)卡同網(wǎng)段。

3:如果ARP請(qǐng)求數(shù)據(jù)包所請(qǐng)求的IP地址對(duì)應(yīng)的本地地址其作用域(scope)為主機(jī)(host),則不回應(yīng)ARP響應(yīng)數(shù)據(jù)包,如果作用域?yàn)槿郑╣lobal)或鏈路(link),則回應(yīng)ARP響應(yīng)數(shù)據(jù)包。

arp_filter配置丟包

在多接口系統(tǒng)里面(比如騰訊云的彈性網(wǎng)卡場(chǎng)景),這些接口都可以回應(yīng)arp請(qǐng)求,導(dǎo)致對(duì)端有可能學(xué)到不同的mac地址,后續(xù)報(bào)文發(fā)送可能由于mac地址和接收?qǐng)?bào)文接口mac地址不一樣而導(dǎo)致丟包,arp_filter主要是用來(lái)適配這種場(chǎng)景;

查看:

sysctl -a | grep arp_filter

解決方案:

根據(jù)實(shí)際場(chǎng)景設(shè)置對(duì)應(yīng)的值,一般默認(rèn)是關(guān)掉此過(guò)濾規(guī)則,特殊情況可以打開(kāi);0:默認(rèn)值,表示回應(yīng)arp請(qǐng)求的時(shí)候不檢查接口情況;1:表示回應(yīng)arp請(qǐng)求時(shí)會(huì)檢查接口是否和接收請(qǐng)求接口一致,不一致就不回應(yīng);

arp表滿(mǎn)導(dǎo)致丟包

比如下面這種情況,由于突發(fā)arp表項(xiàng)很多 超過(guò)協(xié)議棧默認(rèn)配置,發(fā)送報(bào)文的時(shí)候部分arp創(chuàng)建失敗,導(dǎo)致發(fā)送失敗,從而丟包:

查看:

查看arp狀態(tài):cat /proc/net/stat/arp_cache ,table_fulls統(tǒng)計(jì):

查看dmesg消息(內(nèi)核打?。?/p>

dmesg|grep neighbourneighbour:arp_cache:neighbortableoverflow!

查看當(dāng)前arp表大?。篿p n|wc -l

查看系統(tǒng)配額:

sysctl -a |grep net.ipv4.neigh.default.gc_threshgc_thresh1:存在于ARP高速緩存中的最少層數(shù),如果少于這個(gè)數(shù),垃圾收集器將不會(huì)運(yùn)行。缺省值是128。 gc_thresh2 :保存在 ARP 高速緩存中的最多的記錄軟限制。垃圾收集器在開(kāi)始收集前,允許記錄數(shù)超過(guò)這個(gè)數(shù)字 5 秒。缺省值是 512。gc_thresh3 :保存在 ARP 高速緩存中的最多記錄的硬限制,一旦高速緩存中的數(shù)目高于此,垃圾收集器將馬上運(yùn)行。缺省值是1024。

一般在內(nèi)存足夠情況下,可以認(rèn)為gc_thresh3 值是arp 表總大?。?/p>

解決方案:根據(jù)實(shí)際arp最大值情況(比如訪問(wèn)其他子機(jī)最大個(gè)數(shù)),調(diào)整arp表大小

$ sudo sysctl -w net.ipv4.neigh.default.gc_thresh1=1024$ sudo sysctl -w net.ipv4.neigh.default.gc_thresh2=2048$ sudo sysctl -w net.ipv4.neigh.default.gc_thresh3=4096$ sudo sysctl -p

arp請(qǐng)求緩存隊(duì)列溢出丟包

查看:

cat /proc/net/stat/arp_cache ,unresolved_discards是否有新增計(jì)數(shù)

解決方案:根據(jù)客戶(hù)需求調(diào)整緩存隊(duì)列大小unres_qlen_bytes:

網(wǎng)絡(luò)IP層丟包

接口ip地址配置丟包

1. 本機(jī)服務(wù)不通,檢查lo接口有沒(méi)有配置地址是127.0.0.1;

2 .本機(jī)接收失敗, 查看local路由表:ip r show table local|grep 子機(jī)ip地址;這種丟包一般會(huì)出現(xiàn)在多IP場(chǎng)景,子機(jī)底層配置多ip失敗,導(dǎo)致對(duì)應(yīng)ip收不到包而丟包;

解決方案:

1.配置正確接口ip地址;比如ip a add 1.1.1.1 dev eth0

2.如果發(fā)現(xiàn)接口有地址還丟包,可能是local路由表沒(méi)有對(duì)應(yīng)條目,緊急情況下,可以用手工補(bǔ)上:

比如ip r add local 本機(jī)ip地址 dev eth0 table local ;

路由丟包

路由配置丟包

查看:

1.查看配置 路由是否設(shè)置正確(是否可達(dá)),是否配置策略路由(在彈性網(wǎng)卡場(chǎng)景會(huì)出現(xiàn)此配置)ip rule:

然后找到對(duì)應(yīng)路由表。查看路由表:

或者直接用 ip r get x.x.x.x,讓系統(tǒng)幫你查找是否存在可達(dá)路由,接口是否符合預(yù)期;

2.查看系統(tǒng)統(tǒng)計(jì)信息:

netstat -s|grep "dropped because of missing route"

解決方案:重新配置正確的路由;

反向路由過(guò)濾丟包

反向路由過(guò)濾機(jī)制是Linux通過(guò)反向路由查詢(xún),檢查收到的數(shù)據(jù)包源IP是否可路由(Loose mode)、是否最佳路由(Strict mode),如果沒(méi)有通過(guò)驗(yàn)證,則丟棄數(shù)據(jù)包,設(shè)計(jì)的目的是防范IP地址欺騙攻擊。

查看:

rp_filter提供三種模式供配置:

0 - 不驗(yàn)證

1 - RFC3704定義的嚴(yán)格模式:對(duì)每個(gè)收到的數(shù)據(jù)包,查詢(xún)反向路由,如果數(shù)據(jù)包入口和反向路由出口不一致,則不通過(guò)

2 - RFC3704定義的松散模式:對(duì)每個(gè)收到的數(shù)據(jù)包,查詢(xún)反向路由,如果任何接口都不可達(dá),則不通過(guò)

查看當(dāng)前rp_filter策略配置:

$cat /proc/sys/net/ipv4/conf/eth0/rp_filter

如果這里設(shè)置為1,就需要查看主機(jī)的網(wǎng)絡(luò)環(huán)境和路由策略是否可能會(huì)導(dǎo)致客戶(hù)端的入包無(wú)法通過(guò)反向路由驗(yàn)證了。

從原理來(lái)看這個(gè)機(jī)制工作在網(wǎng)絡(luò)層,因此,如果客戶(hù)端能夠Ping通服務(wù)器,就能夠排除這個(gè)因素了。

解決方案:

根據(jù)實(shí)際網(wǎng)絡(luò)環(huán)境將rp_filter設(shè)置為0或2:

$sysctl-wnet.ipv4.conf.all.rp_filter=2或$ sysctl -w net.ipv4.conf.eth0.rp_filter=2

防火墻丟包

客戶(hù)設(shè)置規(guī)則導(dǎo)致丟包

查看:

iptables -nvL |grep DROP ;

解決方案: 修改防火墻規(guī)則;

連接跟蹤導(dǎo)致丟包

連接跟蹤表溢出丟包

kernel 用 ip_conntrack 模塊來(lái)記錄 iptables 網(wǎng)絡(luò)包的狀態(tài),并把每條記錄保存到 table 里(這個(gè) table 在內(nèi)存里,可以通過(guò)/proc/net/ip_conntrack 查看當(dāng)前已經(jīng)記錄的總數(shù)),如果網(wǎng)絡(luò)狀況繁忙,比如高連接,高并發(fā)連接等會(huì)導(dǎo)致逐步占用這個(gè) table 可用空間,一般這個(gè) table 很大不容易占滿(mǎn)并且可以自己清理,table 的記錄會(huì)一直呆在 table 里占用空間直到源 IP 發(fā)一個(gè) RST 包,但是如果出現(xiàn)被攻擊、錯(cuò)誤的網(wǎng)絡(luò)配置、有問(wèn)題的路由/路由器、有問(wèn)題的網(wǎng)卡等情況的時(shí)候,就會(huì)導(dǎo)致源 IP 發(fā)的這個(gè) RST 包收不到,這樣就積累在 table 里,越積累越多直到占滿(mǎn)。無(wú)論,哪種情況導(dǎo)致table變滿(mǎn),滿(mǎn)了以后就會(huì)丟包,出現(xiàn)外部無(wú)法連接服務(wù)器的情況。內(nèi)核會(huì)報(bào)如下錯(cuò)誤信息:kernel: ip_conntrack: table full, dropping packet;

查看當(dāng)前連接跟蹤數(shù) :

cat /proc/sys/net/netfilter/nf_conntrack_max

解決方案:

增大跟蹤的最大條數(shù)net.netfilter.nf_conntrack_max = 3276800減少跟蹤連接的最大有效時(shí)間net.netfilter.nf_conntrack_tcp_timeout_established = 1200net.netfilter.nf_conntrack_udp_timeout_stream = 180net.netfilter.nf_conntrack_icmp_timeout = 30

ct創(chuàng)建沖突失導(dǎo)致丟包

查看:當(dāng)前連接跟蹤統(tǒng)計(jì):cat /proc/net/stat/nf_conntrack,可以查各種ct異常丟包統(tǒng)計(jì)

解決方案:內(nèi)核熱補(bǔ)丁修復(fù)或者更新內(nèi)核版本(合入補(bǔ)丁修改);

傳輸層UDP/TCP丟包

tcp 連接跟蹤安全檢查丟包

丟包原因:由于連接沒(méi)有斷開(kāi),但服務(wù)端或者client之前出現(xiàn)過(guò)發(fā)包異常等情況(報(bào)文沒(méi)有經(jīng)過(guò)連接跟蹤模塊更新窗口計(jì)數(shù)),沒(méi)有更新合法的window范圍,導(dǎo)致后續(xù)報(bào)文安全檢查被丟包;協(xié)議棧用nf_conntrack_tcp_be_liberal 來(lái)控制這個(gè)選項(xiàng):

1:關(guān)閉,只有不在tcp窗口內(nèi)的rst包被標(biāo)志為無(wú)效;

0:開(kāi)啟; 所有不在tcp窗口中的包都被標(biāo)志為無(wú)效;

查看:

查看配置:

sysctl -a|grep nf_conntrack_tcp_be_liberal net.netfilter.nf_conntrack_tcp_be_liberal = 1

查看log:

一般情況下netfiler模塊默認(rèn)沒(méi)有加載log,需要手動(dòng)加載;

modprobe ipt_LOG11sysctl-wnet.netfilter.nf_log.2=ipt_LOG

然后發(fā)包后在查看syslog;

解決方案:根據(jù)實(shí)際抓包分析情況判斷是不是此機(jī)制導(dǎo)致的丟包,可以試著關(guān)閉試一下;

分片重組丟包

情況總結(jié):超時(shí)

查看:

netstat -s|grep timeout601 fragments dropped after timeout

解決方法:調(diào)整超時(shí)時(shí)間

net.ipv4.ipfrag_time = 30sysctl -w net.ipv4.ipfrag_time=60

frag_high_thresh, 分片的內(nèi)存超過(guò)一定閾值會(huì)導(dǎo)致系統(tǒng)安全檢查丟包

查看:

netstat -s|grep reassembles8094 packet reassembles failed

解決方案:調(diào)整大小

net.ipv4.ipfrag_high_thresh net.ipv4.ipfrag_low_thresh

分片安全距檢查離丟包

查看:

netstat -s|grep reassembles8094 packet reassembles failed

解決方案:把ipfrag_max_dist設(shè)置為0,就關(guān)掉此安全檢查

pfrag_max_dist特性,在一些場(chǎng)景下其實(shí)并不適用:

1.有大量的網(wǎng)絡(luò)報(bào)文交互

2.發(fā)送端的并發(fā)度很高,同時(shí)SMP架構(gòu),導(dǎo)致很容易造成這種亂序情況;

分片hash bucket沖突鏈太長(zhǎng)超過(guò)系統(tǒng)默認(rèn)值128

查看:

dmesg|grep“Droppingfragment”inet_frag_find: Fragment hash bucket 128 list length grew over limit. Dropping fragment.

解決方案:熱補(bǔ)丁調(diào)整hash大??;

系統(tǒng)內(nèi)存不足,創(chuàng)建新分片隊(duì)列失敗

查看方法:

netstat-s|grepreassembles8094 packet reassembles failed

dropwatch查看丟包位置 :

解決方案:

a.增大系統(tǒng)網(wǎng)絡(luò)內(nèi)存:

net.core.rmem_default net.core.rmem_max net.core.wmem_default

b.系統(tǒng)回收內(nèi)存:

緊急情況下,可以用/proc/sys/vm/drop_caches, 去釋放一下虛擬內(nèi)存;

To free pagecache:# echo 1 > /proc/sys/vm/drop_cachesTo free dentries and inodes:# echo 2 > /proc/sys/vm/drop_cachesTo free pagecache, dentries and inodes:echo 3 > /proc/sys/vm/drop_caches

MTU丟包

查看:

1.檢查接口MTU配置,ifconfig eth1/eth0,默認(rèn)是1500;

2.進(jìn)行MTU探測(cè),然后設(shè)置接口對(duì)應(yīng)的MTU值;

解決方案:

1. 根據(jù)實(shí)際情況,設(shè)置正確MTU值;

2. 設(shè)置合理的tcp mss,啟用TCP MTU Probe:

cat /proc/sys/net/ipv4/tcp_mtu_probing:tcp_mtu_probing - INTEGER Controls TCP Packetization-Layer Path MTU Discovery.Takes three values:0 - Disabled 1 - Disabled by default, enabled when an ICMP black hole detected2 - Always enabled, use initial MSS of tcp_base_mss.

tcp層丟包

TIME_WAIT過(guò)多丟包

大量TIMEWAIT出現(xiàn),并且需要解決的場(chǎng)景,在高并發(fā)短連接的TCP服務(wù)器上,當(dāng)服務(wù)器處理完請(qǐng)求后立刻按照主動(dòng)正常關(guān)閉連接。。。這個(gè)場(chǎng)景下,會(huì)出現(xiàn)大量socket處于TIMEWAIT狀態(tài)。如果客戶(hù)端的并發(fā)量持續(xù)很高,此時(shí)部分客戶(hù)端就會(huì)顯示連接不上;

查看:

查看系統(tǒng)log :

dmsgTCP: time wait bucket table overflow;

查看系統(tǒng)配置:

sysctl -a|grep tcp_max_tw_bucketsnet.ipv4.tcp_max_tw_buckets = 16384

解決方案:

1. tw_reuse,tw_recycle 必須在客戶(hù)端和服務(wù)端timestamps 開(kāi)啟時(shí)才管用(默認(rèn)打開(kāi))

2. tw_reuse 只對(duì)客戶(hù)端起作用,開(kāi)啟后客戶(hù)端在1s內(nèi)回收;

3. tw_recycle對(duì)客戶(hù)端和服務(wù)器同時(shí)起作用,開(kāi)啟后在3.5*RTO 內(nèi)回收,RTO 200ms~ 120s具體時(shí)間視網(wǎng)絡(luò)狀況。內(nèi)網(wǎng)狀況比tw_reuse稍快,公網(wǎng)尤其移動(dòng)網(wǎng)絡(luò)大多要比tw_reuse 慢,優(yōu)點(diǎn)就是能夠回收服務(wù)端的TIME_WAIT數(shù)量;

在服務(wù)端,如果網(wǎng)絡(luò)路徑會(huì)經(jīng)過(guò)NAT節(jié)點(diǎn),不要啟用net.ipv4.tcp_tw_recycle,會(huì)導(dǎo)致時(shí)間戳混亂,引起其他丟包問(wèn)題;

4. 調(diào)整tcp_max_tw_buckets大小,如果內(nèi)存足夠:

sysctl -w net.ipv4.tcp_max_tw_buckets=163840;

時(shí)間戳異常丟包

當(dāng)多個(gè)客戶(hù)端處于同一個(gè)NAT環(huán)境時(shí),同時(shí)訪問(wèn)服務(wù)器,不同客戶(hù)端的時(shí)間可能不一致,此時(shí)服務(wù)端接收到同一個(gè)NAT發(fā)送的請(qǐng)求,就會(huì)出現(xiàn)時(shí)間戳錯(cuò)亂的現(xiàn)象,于是后面的數(shù)據(jù)包就被丟棄了,具體的表現(xiàn)通常是是客戶(hù)端明明發(fā)送的SYN,但服務(wù)端就是不響應(yīng)ACK。在服務(wù)器借助下面的命令可以來(lái)確認(rèn)數(shù)據(jù)包是否有不斷被丟棄的現(xiàn)象。

檢查:

netstat -s | grep rejects

解決方案:

如果網(wǎng)絡(luò)路徑會(huì)經(jīng)過(guò)NAT節(jié)點(diǎn),不要啟用net.ipv4.tcp_tw_recycle;

TCP隊(duì)列問(wèn)題導(dǎo)致丟包

原理:

tcp狀態(tài)機(jī)(三次握手)

協(xié)議處理:

一個(gè)是半連接隊(duì)列(syn queue):

在三次握手協(xié)議中,服務(wù)器維護(hù)一個(gè)半連接隊(duì)列,該隊(duì)列為每個(gè)客戶(hù)端的SYN包開(kāi)設(shè)一個(gè)條目(服務(wù)端在接收到SYN包的時(shí)候,就已經(jīng)創(chuàng)建了request_sock結(jié)構(gòu),存儲(chǔ)在半連接隊(duì)列中),該條目表明服務(wù)器已收到SYN包,并向客戶(hù)發(fā)出確認(rèn),正在等待客戶(hù)的確認(rèn)包(會(huì)進(jìn)行第二次握手發(fā)送SYN+ACK的包加以確認(rèn))。這些條目所標(biāo)識(shí)的連接在服務(wù)器處于Syn_RECV狀態(tài),當(dāng)服務(wù)器收到客戶(hù)的確認(rèn)包時(shí),刪除該條目,服務(wù)器進(jìn)入ESTABLISHED狀態(tài)。該隊(duì)列為SYN隊(duì)列,長(zhǎng)度為max(64,/proc/sys/net/ipv4/tcp_max_syn_backlog), 機(jī)器的tcp_max_syn_backlog值在/proc/sys/net/ipv4/tcp_max_syn_backlog下配置;

一個(gè)是全連接隊(duì)列(accept queue):

第三次握手時(shí),當(dāng)server接收到ACK 報(bào)之后, 會(huì)進(jìn)入一個(gè)新的叫 accept 的隊(duì)列,該隊(duì)列的長(zhǎng)度為 min(backlog, somaxconn),默認(rèn)情況下,somaxconn 的值為 128,表示最多有 129 的 ESTAB 的連接等待 accept(),而 backlog 的值則應(yīng)該是由 int listen(int sockfd, int backlog) 中的第二個(gè)參數(shù)指定,listen 里面的 backlog 可以有我們的應(yīng)用程序去定義的;

查看:

連接建立失敗,syn丟包:

netstat -s |grep -i listenSYNs to LISTEN sockets dropped

也會(huì)受到連接滿(mǎn)丟包影響

解決方案:增加大小 tcp_max_syn_backlog

連接滿(mǎn)丟包

-xxx times the listen queue of a socket overflowed

查看:

查看accept隊(duì)列大小 :net.core.somaxconn

ss -lnt查詢(xún)socket隊(duì)列 :LISTEN 狀態(tài): Recv-Q 表示的當(dāng)前等待服務(wù)端調(diào)用 accept 完成三次握手的 listen backlog 數(shù)值,也就是說(shuō),當(dāng)客戶(hù)端通過(guò) connect() 去連接正在 listen() 的服務(wù)端時(shí),這些連接會(huì)一直處于這個(gè) queue 里面直到被服務(wù)端 accept();Send-Q 表示的則是最大的 listen backlog 數(shù)值,這就就是上面提到的 min(backlog, somaxconn) 的值,

看一下是不是應(yīng)用程序設(shè)置限制, int listen(int sockfd, int backlog);

解決方案:

Linux內(nèi)核參進(jìn)行優(yōu)化,可以緩解壓力 tcp_abort_on_overflow=1

調(diào)整net.core.somaxconn大小;

應(yīng)用程序設(shè)置問(wèn)題,通知客戶(hù)程序修改;

syn flood攻擊丟包

目前,Linux下默認(rèn)會(huì)進(jìn)行5次重發(fā)SYN-ACK包,重試的間隔時(shí)間從1s開(kāi)始,下次的重試間隔時(shí)間是前一次的雙倍,5次的重試時(shí)間間隔為1s, 2s, 4s, 8s, 16s,總共31s,第5次發(fā)出后還要等32s都知道第5次也超時(shí)了,所以,總共需要 1s + 2s + 4s+ 8s+ 16s + 32s = 63s,TCP才會(huì)把斷開(kāi)這個(gè)連接。由于,SYN超時(shí)需要63秒,那么就給攻擊者一個(gè)攻擊服務(wù)器的機(jī)會(huì),攻擊者在短時(shí)間內(nèi)發(fā)送大量的SYN包給Server(俗稱(chēng) SYN flood 攻擊),用于耗盡Server的SYN隊(duì)列。對(duì)于應(yīng)對(duì)SYN 過(guò)多的問(wèn)題;

查看: 查看syslog: kernel: [3649830.269068] TCP: Possible SYN flooding on port xxx. Sending cookies. Check SNMP counters.

解決方案:

增大tcp_max_syn_backlog

減少tcp_synack_retries

啟用tcp_syncookies

啟用tcp_abort_on_overflow,tcp_abort_on_overflow修改成 1,1表示第三步的時(shí)候如果全連接隊(duì)列滿(mǎn)了,server發(fā)送一個(gè)reset包給client,表示廢掉這個(gè)握手過(guò)程和這個(gè)連接(本來(lái)在server端這個(gè)連接就還沒(méi)建立起來(lái));

PAWS機(jī)制丟包

原理:PAWS(Protect Against Wrapped Sequence numbers),高帶寬下,TCP序列號(hào)可能在較短的時(shí)間內(nèi)就被重復(fù)使用(recycle/wrapped)
就可能導(dǎo)致同一條TCP流在短時(shí)間內(nèi)出現(xiàn)序號(hào)一樣的兩個(gè)合法的數(shù)據(jù)包及其確認(rèn)包。

查看:

$netstat-s|grep-e"passiveconnectionsrejectedbecauseoftimestamp" -e "packets rejects in established connections because of timestamp” 387158 passive connections rejected because of time stamp825313 packets rejects in established connections because of timestamp

通過(guò)sysctl查看是否啟用了tcp_tw_recycle及tcp_timestamp:

$ sysctl net.ipv4.tcp_tw_recyclenet.ipv4.tcp_tw_recycle = 1 $ sysctl net.ipv4.tcp_timestampsnet.ipv4.tcp_timestamps = 1

1. tcp_tw_recycle參數(shù)。它用來(lái)快速回收TIME_WAIT連接,不過(guò)如果在NAT環(huán)境下會(huì)引發(fā)問(wèn)題;

2. 當(dāng)多個(gè)客戶(hù)端通過(guò)NAT方式聯(lián)網(wǎng)并與服務(wù)端交互時(shí),服務(wù)端看到的是同一個(gè)IP,也就是說(shuō)對(duì)服務(wù)端而言這些客戶(hù)端實(shí)際上等同于一個(gè),可惜由于這些客戶(hù)端的時(shí)間戳可能存在差異,于是乎從服務(wù)端的視角看,便可能出現(xiàn)時(shí)間戳錯(cuò)亂的現(xiàn)象,進(jìn)而直接導(dǎo)致時(shí)間戳小的數(shù)據(jù)包被丟棄。如果發(fā)生了此類(lèi)問(wèn)題,具體的表現(xiàn)通常是是客戶(hù)端明明發(fā)送的SYN,但服務(wù)端就是不響應(yīng)ACK。

解決方案:

在NAT環(huán)境下,清除tcp時(shí)間戳選項(xiàng),或者不開(kāi)啟tcp_tw_recycle參數(shù);

TLP問(wèn)題丟包

TLP主要是為了解決尾丟包重傳效率的問(wèn)題,TLP能夠有效的避免較長(zhǎng)的RTO超時(shí),進(jìn)而提高TCP性能,詳細(xì)參考文章:

http://perthcharles.github.io/2015/10/31/wiki-network-tcp-tlp/;

但在低時(shí)延場(chǎng)景下(短連接小包量),TLP與延遲ACK組合可能會(huì)造成無(wú)效重傳,導(dǎo)致客戶(hù)端感發(fā)現(xiàn)大量假重傳包,加大了響應(yīng)延遲;

查看:

查看協(xié)議棧統(tǒng)計(jì):

netstat -s |grep TCPLossProbes

查看系統(tǒng)配置:

sysctl -a | grep tcp_early_retrans

解決方案:

1.關(guān)掉延遲ack,打開(kāi)快速ack;

2.linux實(shí)現(xiàn)nodelay語(yǔ)意不是快速ack,只是關(guān)閉nagle算法;

3.打開(kāi)快速ack選項(xiàng),socket里面有個(gè) TCP_QUICKACK 選項(xiàng),需要每次recv后再設(shè)置一次。

內(nèi)存不足導(dǎo)致丟包

查看:

查看log:

dmesg|grep“outofmemory”

查看系統(tǒng)配置:

cat /proc/sys/net/ipv4/tcp_memcat /proc/sys/net/ipv4/tcp_rmemcat /proc/sys/net/ipv4/tcp_wmem

解決方案:

根據(jù)TCP業(yè)務(wù)并發(fā)流量,調(diào)整系統(tǒng)參數(shù),一般試著增大2倍或者其他倍數(shù)來(lái)看是否緩解;

sysclt -w net.ipv4.tcp_mem=sysclt -w net.ipv4.tcp_wmem=sysclt -w net.ipv4.tcp_rmem=sysctl -p

TCP超時(shí)丟包

查看:

抓包分析一下網(wǎng)絡(luò)RTT:

用其他工具測(cè)試一下當(dāng)前端到端網(wǎng)絡(luò)質(zhì)量(hping等);

# hping -S 9.199.10.104 -AHPING 9.199.10.104 (bond1 9.199.10.104): SA set, 40 headers + 0 data byteslen=46 ip=9.199.10.104 ttl=53 DF id=47617 sport=0 flags=R seq=0 win=0 rtt=38.3 mslen=46 ip=9.199.10.104 ttl=53 DF id=47658 sport=0 flags=R seq=1 win=0 rtt=38.3 mslen=46 ip=9.199.10.104 ttl=53 DF id=47739 sport=0 flags=R seq=2 win=0 rtt=30.4 mslen=46 ip=9.199.10.104 ttl=53 DF id=47842 sport=0 flags=R seq=3 win=0 rtt=30.4 mslen=46 ip=9.199.10.104 ttl=53 DF id=48485 sport=0 flags=R seq=4 win=0 rtt=38.7 mslen=46 ip=9.199.10.104 ttl=53 DF id=49274 sport=0 flags=R seq=5 win=0 rtt=34.1 mslen=46 ip=9.199.10.104 ttl=53 DF id=49491 sport=0 flags=R seq=6 win=0 rtt=30.3 ms

解決方案:

關(guān)閉Nagle算法,減少小包延遲;

關(guān)閉延遲ack:

sysctl -w net.ipv4.tcp_no_delay_ack=1

TCP亂序丟包

此時(shí)TCP會(huì)無(wú)法判斷是數(shù)據(jù)包丟失還是亂序,因?yàn)閬G包和亂序都會(huì)導(dǎo)致接收端收到次序混亂的數(shù)據(jù)包,造成接收端的數(shù)據(jù)空洞。TCP會(huì)將這種情況暫定為數(shù)據(jù)包的亂序,因?yàn)閬y序是時(shí)間問(wèn)題(可能是數(shù)據(jù)包的遲到),而丟包則意味著重傳。當(dāng)TCP意識(shí)到包出現(xiàn)亂序的情況時(shí),會(huì)立即ACK,該ACK的TSER部分包含的TSEV值會(huì)記錄當(dāng)前接收端收到有序報(bào)文段的時(shí)刻。這會(huì)使得數(shù)據(jù)包的RTT樣本值增大,進(jìn)一步導(dǎo)致RTO時(shí)間延長(zhǎng)。這對(duì)TCP來(lái)說(shuō)無(wú)疑是有益的,因?yàn)門(mén)CP有充分的時(shí)間判斷數(shù)據(jù)包到底是失序還是丟了來(lái)防止不必要的數(shù)據(jù)重傳。當(dāng)然嚴(yán)重的亂序則會(huì)讓發(fā)送端以為是丟包一旦重復(fù)的ACK超過(guò)TCP的閾值,便會(huì)觸發(fā)超時(shí)重傳機(jī)制,以及時(shí)解決這種問(wèn)題;詳細(xì)請(qǐng)參考博客:

https://blog.csdn.net/dog250/article/details/78692585

查看:抓包分析是否存在很多亂序報(bào)文:

解決方案:如果在多徑傳輸場(chǎng)景或者網(wǎng)絡(luò)質(zhì)量不好,可以通過(guò)修改下面值來(lái)提供系統(tǒng)對(duì)TCP無(wú)序傳送的容錯(cuò)率:

擁塞控制丟包

在互聯(lián)網(wǎng)發(fā)展的過(guò)程當(dāng)中,TCP算法也做出了一定改變,先后演進(jìn)了

Reno、NewReno、Cubic和Vegas,這些改進(jìn)算法大體可以分為基于丟包和基于延時(shí)的擁塞控制算法?;趤G包的擁塞控制算法以Reno、NewReno為代表,它的主要問(wèn)題有Buffer bloat和長(zhǎng)肥管道兩種,基于丟包的協(xié)議擁塞控制機(jī)制是被動(dòng)式的,其依據(jù)網(wǎng)絡(luò)中的丟包事件來(lái)做網(wǎng)絡(luò)擁塞判斷。即使網(wǎng)絡(luò)中的負(fù)載很高,只要沒(méi)有產(chǎn)生擁塞丟包,協(xié)議就不會(huì)主動(dòng)降低自己的發(fā)送速度。最初路由器轉(zhuǎn)發(fā)出口的Buffer 是比較小的,TCP在利用時(shí)容易造成全局同步,降低帶寬利用率,隨后路由器廠家由于硬件成本下降不斷地增加Buffer,基于丟包反饋的協(xié)議在不丟包的情況下持續(xù)占用路由器buffer,雖然提高了網(wǎng)絡(luò)帶寬的利用率,但同時(shí)也意味著發(fā)生擁塞丟包后,網(wǎng)絡(luò)抖動(dòng)性加大。另外對(duì)于帶寬和RTT都很高的長(zhǎng)肥管道問(wèn)題來(lái)說(shuō),管道中隨機(jī)丟包的可能性很大,TCP的默認(rèn)buffer設(shè)置比較小加上隨機(jī)丟包造成的cwnd經(jīng)常下折,導(dǎo)致帶寬利用率依舊很低; BBR(Bottleneck Bandwidth and Round-trip propagation time)是一種基于帶寬和延遲反饋的擁塞控制算法。目前已經(jīng)演化到第二版,是一個(gè)典型的封閉反饋系統(tǒng),發(fā)送多少報(bào)文和用多快的速度發(fā)送這些報(bào)文都是在每次反饋中不斷調(diào)節(jié)。在BBR提出之前,擁塞控制都是基于事件的算法,需要通過(guò)丟包或延時(shí)事件驅(qū)動(dòng);BBR提出之后,擁塞控制是基于反饋的自主自動(dòng)控制算法,對(duì)于速率的控制是由算法決定,而不由網(wǎng)絡(luò)事件決定,BBR算法的核心是找到最大帶寬(Max BW)和最小延時(shí)(Min RTT)這兩個(gè)參數(shù),最大帶寬和最小延時(shí)的乘積可以得到BDP(Bandwidth Delay Product), 而B(niǎo)DP就是網(wǎng)絡(luò)鏈路中可以存放數(shù)據(jù)的最大容量。BDP驅(qū)動(dòng)Probing State Machine得到Rate quantum和cwnd,分別設(shè)置到發(fā)送引擎中就可以解決發(fā)送速度和數(shù)據(jù)量的問(wèn)題。

Linux 4.9內(nèi)核首次采用BBR擁塞控制算法第一個(gè)版本,BBR抗丟包能力比其他算法要強(qiáng),但這個(gè)版本在某些場(chǎng)景下面有問(wèn)題(缺點(diǎn)),BBR在實(shí)時(shí)音視頻領(lǐng)域存在的問(wèn)題,深隊(duì)列競(jìng)爭(zhēng)不過(guò)Cubic。

問(wèn)題現(xiàn)象就是:在深隊(duì)列場(chǎng)景,BBR的ProbeRTT階段只發(fā)4個(gè)包,發(fā)送速率下降太多會(huì)引發(fā)延遲加大和卡頓問(wèn)題。

查看:

ss -sti //在源端 ss -sti|grep 10.125.42.49:47699 -A 3 ( 10.125.42.49:47699 是目的端地址和端口號(hào))

d1efb6b8-7de1-11eb-8b86-12bb97331649.png

d213a0dc-7de1-11eb-8b86-12bb97331649.png

解決方案:

ProbeRTT并不適用實(shí)時(shí)音視頻領(lǐng)域,因此可以選擇直接去除,或者像BBRV2把probe RTT縮短到2.5s一次,使用0.5xBDP發(fā)送;

如果沒(méi)有特殊需求,切換成穩(wěn)定的cubic算法;

UDP層丟包

收發(fā)包失敗丟包

查看:netstat 統(tǒng)計(jì)

如果有持續(xù)的 receive buffer errors/send buffer errors 計(jì)數(shù);

解決方案:

CPU負(fù)載(多核綁核配置),網(wǎng)絡(luò)負(fù)載(軟中斷優(yōu)化,調(diào)整驅(qū)動(dòng)隊(duì)列netdev_max_backlog),內(nèi)存配置(協(xié)議棧內(nèi)存);

按峰值在來(lái),增大buffer緩存區(qū)大?。?/p>

net.ipv4.udp_mem = xxxnet.ipv4.udp_rmem_min = xxxnet.ipv4.udp_wmem_min = xxx

3. 調(diào)整應(yīng)用設(shè)計(jì):

UDP本身就是無(wú)連接不可靠的協(xié)議,適用于報(bào)文偶爾丟失也不影響程序狀態(tài)的場(chǎng)景,比如視頻音頻、游戲、監(jiān)控等。對(duì)報(bào)文可靠性要求比較高的應(yīng)用不要使用 UDP,推薦直接使用 TCP。當(dāng)然,也可以在應(yīng)用層做重試、去重保證可靠性

如果發(fā)現(xiàn)服務(wù)器丟包,首先通過(guò)監(jiān)控查看系統(tǒng)負(fù)載是否過(guò)高,先想辦法把負(fù)載降低再看丟包問(wèn)題是否消失

如果系統(tǒng)負(fù)載過(guò)高,UDP丟包是沒(méi)有有效解決方案的。如果是應(yīng)用異常導(dǎo)致CPU、memory、IO 過(guò)高,請(qǐng)及時(shí)定位異常應(yīng)用并修復(fù);如果是資源不夠,監(jiān)控應(yīng)該能及時(shí)發(fā)現(xiàn)并快速擴(kuò)容

對(duì)于系統(tǒng)大量接收或者發(fā)送UDP報(bào)文的,可以通過(guò)調(diào)節(jié)系統(tǒng)和程序的 socket buffer size 來(lái)降低丟包的概率

應(yīng)用程序在處理UDP報(bào)文時(shí),要采用異步方式,在兩次接收?qǐng)?bào)文之間不要有太多的處理邏輯

應(yīng)用層socket丟包

socket緩存區(qū)接收丟包

查看:

1. 抓包分析是否存在丟包情況;

2. 查看統(tǒng)計(jì):

netstat -s|grep "packet receive errors"

解決方案:

調(diào)整socket緩沖區(qū)大小:

socket配置(所有協(xié)議socket):# Default Socket Receive Buffernet.core.rmem_default = 31457280# Maximum Socket Receive Buffernet.core.rmem_max = 67108864

具體大小調(diào)整原理:

緩沖區(qū)大小沒(méi)有任何設(shè)置值是最佳的,因?yàn)樽罴汛笮‰S具體情況而不同

緩沖區(qū)估算原理:在數(shù)據(jù)通信中,帶寬時(shí)延乘積(英語(yǔ):bandwidth-delay product;或稱(chēng)帶寬延時(shí)乘積、帶寬延時(shí)積等)指的是一個(gè)數(shù)據(jù)鏈路的能力(每秒比特)與來(lái)回通信延遲(單位秒)的乘積。[1][2]其結(jié)果是以比特(或字節(jié))為單位的一個(gè)數(shù)據(jù)總量,等同在任何特定時(shí)間該網(wǎng)絡(luò)線(xiàn)路上的最大數(shù)據(jù)量——已發(fā)送但尚未確認(rèn)的數(shù)據(jù)。

BDP = 帶寬 * RTT

可以通過(guò)計(jì)算當(dāng)面節(jié)點(diǎn)帶寬和統(tǒng)計(jì)平均時(shí)延來(lái)估算BDP,即緩沖區(qū)的大小,可以參考下面常見(jiàn)場(chǎng)景估計(jì):

參考:https://docs.oracle.com/cd/E56344_01/html/E53803/gnkor.html

應(yīng)用設(shè)置tcp連接數(shù)大小丟包

查看:

請(qǐng)參考上面TCP連接隊(duì)列分析;

解決方案:

設(shè)置合理的連接隊(duì)列大小,當(dāng)?shù)谌挝帐謺r(shí),當(dāng)server接收到ACK 報(bào)之后, 會(huì)進(jìn)入一個(gè)新的叫 accept 的隊(duì)列,該隊(duì)列的長(zhǎng)度為 min(backlog, somaxconn),默認(rèn)情況下,somaxconn 的值為 128,表示最多有 129 的 ESTAB 的連接等待 accept(),而 backlog 的值則應(yīng)該是由 int listen(int sockfd, int backlog) 中的第二個(gè)參數(shù)指定,listen 里面的 backlog 可以有我們的應(yīng)用程序去定義的;

應(yīng)用發(fā)送太快導(dǎo)致丟包

查看統(tǒng)計(jì):

netstat-s|grep"sendbuffererrors

解決方案:

ICMP/UDP沒(méi)有流控機(jī)制,需要應(yīng)用設(shè)計(jì)合理發(fā)送方式和速度,照顧到底層buff大小和CPU負(fù)載以及網(wǎng)絡(luò)帶寬質(zhì)量;

設(shè)置合理的sock緩沖區(qū)大?。?/p>

setsockopt(s,SOL_SOCKET,SO_SNDBUF, i(const char*)&nSendBuf,sizeof(int));

調(diào)整系統(tǒng)socket緩沖區(qū)大?。?/p>

# Default Socket Send Buffer net.core.wmem_default = 31457280 # Maximum Socket Send Buffer net.core.wmem_max = 33554432

附:簡(jiǎn)單總結(jié)一下內(nèi)核協(xié)議棧丟包:

相關(guān)工具介紹

1.dropwatch工具

原理:監(jiān)聽(tīng) kfree_skb(把網(wǎng)絡(luò)報(bào)文丟棄時(shí)會(huì)調(diào)用該函數(shù))函數(shù)或者事件嗎,然后打印對(duì)應(yīng)調(diào)用堆棧;想要詳細(xì)了解 linux 系統(tǒng)在執(zhí)行哪個(gè)函數(shù)時(shí)丟包的話(huà),可以使用 dropwatch 工具,它監(jiān)聽(tīng)系統(tǒng)丟包信息,并打印出丟包發(fā)生的函數(shù):

2. tcpdump工具

原理: tcpdump 是一個(gè)Unix下一個(gè)功能強(qiáng)大的網(wǎng)絡(luò)抓包工具,它允許用戶(hù)攔截和顯示發(fā)送或收到過(guò)網(wǎng)絡(luò)連接到該計(jì)算機(jī)的TCP/IP和其他數(shù)據(jù)包

抓包命令參考:

https://www.tcpdump.org/manpages/tcpdump.1.html

數(shù)據(jù)包分析:

1.用wireshark工具分析 參考:Wireshark數(shù)據(jù)包分析實(shí)戰(zhàn).pdf

2.可以轉(zhuǎn)化生成CSV數(shù)據(jù),用Excel或者shell去分析特定場(chǎng)景報(bào)文;

3.可以在linux上用tshark命令行工具進(jìn)行分析:

https://www.wireshark.org/docs/man-pages/tshark.html

總結(jié)

本文只是分析大部分可能會(huì)丟包節(jié)點(diǎn),提供了單個(gè)節(jié)點(diǎn)丟包排查和相關(guān)的解決方案, 丟包問(wèn)題牽扯網(wǎng)絡(luò)鏈路各個(gè)組件,尤其是在云網(wǎng)絡(luò)時(shí)代,網(wǎng)絡(luò)拓?fù)鋸?fù)雜多變,涉及運(yùn)營(yíng)商網(wǎng)絡(luò),IDC網(wǎng)絡(luò),專(zhuān)線(xiàn)等underlay網(wǎng)絡(luò),邊界網(wǎng)關(guān),VPC網(wǎng)絡(luò),CLB負(fù)載均衡等云上overlay網(wǎng)絡(luò),各種丟包問(wèn)題排障起來(lái)非常復(fù)雜且困難,但掌握網(wǎng)絡(luò)通信基本原理后,可以分解網(wǎng)絡(luò)拓?fù)?,?duì)通信節(jié)點(diǎn)進(jìn)行逐一排查,也可以找到丟包位置,后續(xù)會(huì)更加深入介紹云計(jì)算時(shí)代,云上網(wǎng)絡(luò)丟包排查方法,網(wǎng)絡(luò)架構(gòu)解析等,達(dá)到任何丟包問(wèn)題都可以快速排查和定位解決,幫助客戶(hù)快速恢復(fù)業(yè)務(wù),下期再會(huì)。

責(zé)任編輯:lq

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Mac
    Mac
    +關(guān)注

    關(guān)注

    0

    文章

    1095

    瀏覽量

    51341
  • 數(shù)據(jù)包
    +關(guān)注

    關(guān)注

    0

    文章

    248

    瀏覽量

    24345
  • 丟包
    +關(guān)注

    關(guān)注

    1

    文章

    12

    瀏覽量

    8133

原文標(biāo)題:云網(wǎng)絡(luò)丟包故障定位全景指南

文章出處:【微信號(hào):LinuxDev,微信公眾號(hào):Linux閱碼場(chǎng)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    ubuntu ping 開(kāi)發(fā)板存在嚴(yán)重的情況,請(qǐng)問(wèn)該怎么解決?

    我現(xiàn)在在學(xué)習(xí)個(gè)嵌入式Linux的項(xiàng)目,要實(shí)現(xiàn)主機(jī),虛擬機(jī),開(kāi)發(fā)板三者的通信,我的系列設(shè)置應(yīng)該是沒(méi)問(wèn)題的。但是在ubuntu上ping開(kāi)發(fā)板時(shí)總是會(huì)出現(xiàn)很?chē)?yán)重的
    發(fā)表于 11-01 16:50

    工業(yè)交換機(jī)的零延遲和零

    據(jù)傳輸中常常面臨延遲和的問(wèn)題,這對(duì)于實(shí)時(shí)監(jiān)控、數(shù)據(jù)反饋及其他關(guān)鍵應(yīng)用而言,是無(wú)法容忍的。因此,工業(yè)交換機(jī)的設(shè)計(jì)理念從開(kāi)始就必須將這兩個(gè)目標(biāo)放在首位。
    的頭像 發(fā)表于 09-24 15:52 ?164次閱讀

    使用SPI連接MCU和ESP8266,頻繁出現(xiàn)問(wèn)題是什么原因呢?

    您好; 我司使用SPI 連接MCU和ESP8266,同一個(gè)局域網(wǎng)內(nèi) 8臺(tái)左右機(jī)器同時(shí)上傳10MB 大小的文件到后臺(tái),頻繁出現(xiàn)問(wèn)題;設(shè)備信號(hào)沒(méi)有問(wèn)題,緊挨著路由器;另外換過(guò)不同型號(hào)路由器也沒(méi)有改善;大概會(huì)是什么原因呢
    發(fā)表于 07-19 08:12

    為什么ESP8266 TCP透?jìng)鬟^(guò)程會(huì)

    為什么ESP8266 TCP透?jìng)鬟^(guò)程會(huì)?
    發(fā)表于 07-09 07:55

    ESP8266_RTOS3.0串口0傳輸大量數(shù)據(jù)的原因?

    多個(gè)分段進(jìn)入處理函數(shù),后來(lái)使用example示例中的uart_echo,發(fā)現(xiàn)接收可以完整接收,但是當(dāng)把數(shù)據(jù)原樣從串口0的tx輸出時(shí),數(shù)據(jù)中間出現(xiàn)多次中斷。 我發(fā)現(xiàn)用系統(tǒng)自帶的打印log的函數(shù)打印數(shù)據(jù)時(shí),并不會(huì)出現(xiàn)
    發(fā)表于 07-09 06:32

    cy7c68013a-56ltxc搭載fpga傳輸數(shù)據(jù)是哪里出了問(wèn)題?

    1.8m的個(gè)圖像數(shù)據(jù)由fpga傳輸給usb芯片,再由cy7c68013-56ltxc芯片把數(shù)據(jù)傳輸給電腦,然后由軟件排列起來(lái),發(fā)現(xiàn)數(shù)據(jù)出現(xiàn)了,數(shù)據(jù)卻行,大家有什么看法?
    發(fā)表于 07-03 08:26

    串口通信的時(shí)候怎么避免的情況?

    1.如何避免在中斷里面執(zhí)行長(zhǎng)時(shí)間的操作 2.串口通信的時(shí)候怎么避免的情況 3.串口通信為什么不可以次發(fā)送1000bit或者10000bit 也就是說(shuō)幀數(shù)據(jù)為
    發(fā)表于 07-03 07:00

    例程simple_sniffer接收wifi數(shù)據(jù)時(shí)老是,有什么改進(jìn)辦法?

    您好! 在用例程simple_sniffer接收wifi數(shù)據(jù)時(shí)老是,是否有什么改進(jìn)辦法? 謝謝
    發(fā)表于 06-26 07:41

    udp數(shù)據(jù)的原因?

    編譯sdk/examples/protocols/sockets/udp_server 例子程序,修改了代碼,把發(fā)送回去的代碼注釋?zhuān)皇怯涗浬洗谓邮諗?shù)據(jù)的時(shí)間和當(dāng)前接收數(shù)據(jù)的時(shí)間間隔,運(yùn)行
    發(fā)表于 06-25 07:03

    esp32 udp broadcast怎么避免?

    esp32 udp broadcast
    發(fā)表于 06-17 06:05

    CC2640R2L使用BLE的Notify功能,通過(guò)定時(shí)器每隔10ms向手機(jī)發(fā)送一包數(shù)據(jù),會(huì)出現(xiàn)的原因?

    使用BLE的Notify功能,通過(guò)定時(shí)器每隔10ms向手機(jī)發(fā)送一包數(shù)據(jù),每包數(shù)據(jù)20字節(jié),發(fā)送大約4000后出現(xiàn)情況,每次1
    發(fā)表于 05-30 07:43

    網(wǎng)絡(luò)率正常范圍及其影響因素

    網(wǎng)絡(luò)中,數(shù)據(jù)是以IP分組的形式傳輸?shù)?,每個(gè)數(shù)據(jù)都有個(gè)的標(biāo)識(shí)符。當(dāng)接收方未能收到發(fā)送方發(fā)送的數(shù)據(jù)
    的頭像 發(fā)表于 12-29 14:45 ?5478次閱讀

    連接相機(jī)怎么辦?如何設(shè)置網(wǎng)卡屬性?

    連接相機(jī)怎么辦?如何設(shè)置網(wǎng)卡屬性?
    的頭像 發(fā)表于 12-12 16:26 ?617次閱讀
    連接相機(jī)<b class='flag-5'>丟</b><b class='flag-5'>包</b>怎么辦?如何設(shè)置網(wǎng)卡屬性?

    常見(jiàn)的網(wǎng)絡(luò)故障定位?法

    本期分享個(gè)比較常見(jiàn)的?絡(luò)問(wèn)題--。例如我們?nèi)
    的頭像 發(fā)表于 12-07 09:48 ?1617次閱讀
    <b class='flag-5'>常見(jiàn)</b>的網(wǎng)絡(luò)<b class='flag-5'>丟</b><b class='flag-5'>包</b>故障定位?法

    網(wǎng)絡(luò)問(wèn)題分析

    所謂,是指在網(wǎng)絡(luò)數(shù)據(jù)的收發(fā)過(guò)程中,由于種種原因,數(shù)據(jù)還沒(méi)傳輸?shù)綉?yīng)用程序中,就被丟棄了。這些被丟棄的數(shù)量,除以總的傳輸數(shù),也就是我們
    的頭像 發(fā)表于 11-13 11:24 ?926次閱讀
    網(wǎng)絡(luò)<b class='flag-5'>丟</b><b class='flag-5'>包</b>問(wèn)題分析