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

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

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

常見的網(wǎng)絡(luò)丟包故障定位?法

Linux愛好者 ? 來源: 極客重生 ? 2023-12-07 09:48 ? 次閱讀

引言

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

什么是丟包

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

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

fea07f18-949e-11ee-939d-92fbcf53809c.jpg

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

fea6edee-949e-11ee-939d-92fbcf53809c.png

1.應(yīng)?程序的數(shù)據(jù)包,在TCP層增加TCP報(bào)?頭,形成可傳輸?shù)臄?shù)據(jù)包。
2.在IP層增加IP報(bào)頭,形成IP報(bào)?。
3.經(jīng)過數(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ā)送到?線上,這樣說就完成了?個(gè)IP報(bào)?的發(fā)送了,所有連接到這個(gè)?線上的?卡都可以看到該packet。

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

feae4f94-949e-11ee-939d-92fbcf53809c.png

1.?卡收到?線上的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)過TCP/IP協(xié)議棧層層解碼處理。
4.應(yīng)?程序從socket buffer 中讀取數(shù)據(jù)。

核心思路

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

目錄--網(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溢出

ff111980-949e-11ee-939d-92fbcf53809c.png

如圖所示,物理介質(zhì)上的數(shù)據(jù)幀到達(dá)后首先由NIC(網(wǎng)絡(luò)適配器)讀取,寫入設(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ì)被填滿,新來的數(shù)據(jù)包將被丟棄;

查看:

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

$ ethtool -S eth0|grep rx_fifo
rx_fifo_errors: 0
$ cat /proc/net/dev
Inter-|Receive|Transmitface|bytespacketserrsdropfifoframecompressed
multicast|bytes packets errs drop fifo colls carrier compressed
eth0: 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

ff1eec86-949e-11ee-939d-92fbcf53809c.png

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

ff2ef914-949e-11ee-939d-92fbcf53809c.png

主要查看網(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

ff3fc834-949e-11ee-939d-92fbcf53809c.png

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

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

ff4a56e6-949e-11ee-939d-92fbcf53809c.png

解決方案:關(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)卡只接受來自網(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)沒有及時(shí)更新,但目的端mac地址已發(fā)生變化(換了網(wǎng)卡),沒有更新通知到源端(比如更新報(bào)文被丟失,中間交換機(jī)異常等情況);

查看:

1.目的端抓包,tcpdump可以開啟混雜模式,可以抓到對(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)卡異常丟包

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

網(wǎng)卡firmware版本:

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

ff567e58-949e-11ee-939d-92fbcf53809c.png

和廠家提case詢問是不是已知問題,有沒有新版本等;

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

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

ethtool -S eth0

ff68a682-949e-11ee-939d-92fbcf53809c.png

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

報(bào)文長度丟包

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


查看:

ethtool-Seth1|greplength_errors

ff80197a-949e-11ee-939d-92fbcf53809c.png

解決方案:

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

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

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

ff86fd12-949e-11ee-939d-92fbcf53809c.png

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

查看:ifconfig eth1/eth0 等接口

ff9da026-949e-11ee-939d-92fbcf53809c.png

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)存的過程中被丟棄。

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ù)包沒到 Ring Buffer 就被網(wǎng)卡物理層給丟棄了,而 CPU 無法即使的處理中斷是造成 Ring Buffer 滿的原因之一,上面那臺(tái)有問題的機(jī)器就是因?yàn)?interruprs 分布的不均勻(都?jí)涸?core0),沒有做 affinity 而造成的丟包。

4. RX frame: 表示 misaligned 的 frames。

5. 對(duì)于 TX 的來說,出現(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ì)列不斷增長,當(dāng)達(dá)到設(shè)定的netdev_max_backlog值時(shí),數(shù)據(jù)包將被丟棄。

查看:

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

ffabcad4-949e-11ee-939d-92fbcf53809c.png

其中:每一行代表每個(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ì)中,并沒有因?yàn)閚etdev_max_backlog導(dǎo)致的丟包。

解決方案:

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

$ sysctl -w net.core.netdev_max_backlog=2000

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

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

查看:mpstat -P ALL 1

ffc90f2c-949e-11ee-939d-92fbcf53809c.png

單核軟中斷占有100%,導(dǎo)致應(yīng)用沒有機(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 stop
2) 中斷綁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é)議棧開啟RPS并設(shè)置RPS;

echo $mask(CPU配置)> /sys/class/net/$eth/queues/rx-$i/rps_cpus
echo 4096(網(wǎng)卡buff)> /sys/class/net/$eth/queues/rx-$i/rps_flow_cnt
2)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-info
lspci -s bus-info -vv|grep node

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

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

查看 :

 ethtool -c ethx
Coalesceparametersforeth1:
Adaptive RX: on  TX: on
stats-block-usecs: 0
sample-interval: 0
pkt-rate-low: 0
pkt-rate-high: 0


rx-usecs: 25
rx-frames: 0
rx-usecs-irq: 0
rx-frames-irq: 256


tx-usecs: 25
tx-frames: 0
tx-usecs-irq: 0
tx-frames-irq: 256


rx-usecs-low: 0
rx-frame-low: 0
tx-usecs-low: 0
tx-frame-low: 0


rx-usecs-high: 0
rx-frame-high: 0
tx-usecs-high: 0
tx-frame-high: 0

調(diào)整:

ethtool -C ethx adaptive-rx on

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

ffe19178-949e-11ee-939d-92fbcf53809c.png

內(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

fffb0d74-949e-11ee-939d-92fbcf53809c.png

解決方案:根據(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ù)包。

00023d88-949f-11ee-939d-92fbcf53809c.png0015635e-949f-11ee-939d-92fbcf53809c.png

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主要是用來適配這種場(chǎng)景;

查看:

sysctl -a | grep arp_filter

001dd246-949f-11ee-939d-92fbcf53809c.png

解決方案:

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

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

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

0025aca0-949f-11ee-939d-92fbcf53809c.png

查看:

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

003cbd3c-949f-11ee-939d-92fbcf53809c.png

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

dmesg|grep neighbour
neighbour:arp_cache:neighbortableoverflow!

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

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

sysctl -a |grep net.ipv4.neigh.default.gc_thresh
gc_thresh1:存在于ARP高速緩存中的最少層數(shù),如果少于這個(gè)數(shù),垃圾收集器將不會(huì)運(yùn)行。缺省值是128。


gc_thresh2 :保存在 ARP 高速緩存中的最多的記錄軟限制。垃圾收集器在開始收集前,允許記錄數(shù)超過這個(gè)數(shù)字 5 秒。缺省值是 512。
gc_thresh3 :保存在 ARP 高速緩存中的最多記錄的硬限制,一旦高速緩存中的數(shù)目高于此,垃圾收集器將馬上運(yùn)行。缺省值是1024。

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

005b5bc0-949f-11ee-939d-92fbcf53809c.png

解決方案:根據(jù)實(shí)際arp最大值情況(比如訪問其他子機(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ù)客戶需求調(diào)整緩存隊(duì)列大小unres_qlen_bytes:

006e0144-949f-11ee-939d-92fbcf53809c.png

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

接口ip地址配置丟包

1. 本機(jī)服務(wù)不通,檢查lo接口有沒有配置地址是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收不到包而丟包;

007e85a0-949f-11ee-939d-92fbcf53809c.png

解決方案:

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

2.如果發(fā)現(xiàn)接口有地址還丟包,可能是local路由表沒有對(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:

0082e15e-949f-11ee-939d-92fbcf53809c.png

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

008a1fa0-949f-11ee-939d-92fbcf53809c.png

或者直接用 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"

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

反向路由過濾丟包

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

查看:

rp_filter提供三種模式供配置:

0 - 不驗(yàn)證

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

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

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

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

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

從原理來看這個(gè)機(jī)制工作在網(wǎng)絡(luò)層,因此,如果客戶端能夠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

防火墻丟包

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

查看:

  iptables -nvL |grep DROP ;

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

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

連接跟蹤表溢出丟包

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

00a19c66-949f-11ee-939d-92fbcf53809c.png

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

傳輸層UDP/TCP丟包

tcp 連接跟蹤安全檢查丟包

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

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

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

查看:

查看配置:

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

查看log:

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

modprobe ipt_LOG11
sysctl-wnet.netfilter.nf_log.2=ipt_LOG

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

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

分片重組丟包

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

查看:

netstat -s|grep timeout
601 fragments dropped after timeout

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

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

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

查看:

netstat -s|grep reassembles
8094 packet reassembles failed

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

net.ipv4.ipfrag_high_thresh 
net.ipv4.ipfrag_low_thresh

分片安全距檢查離丟包

查看:

netstat -s|grep reassembles
8094 packet reassembles failed

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

00ab95ae-949f-11ee-939d-92fbcf53809c.png

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

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

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

分片hash bucket沖突鏈太長超過系統(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大?。?/p>

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

查看方法:

netstat-s|grepreassembles
8094 packet reassembles failed

dropwatch查看丟包位置 :

00c60736-949f-11ee-939d-92fbcf53809c.png

解決方案:

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_caches
To free dentries and inodes:
# echo 2 > /proc/sys/vm/drop_caches
To free pagecache, dentries and inodes:
echo 3 > /proc/sys/vm/drop_caches

MTU丟包

00e1ae96-949f-11ee-939d-92fbcf53809c.png

查看:

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 detected
2 - Always enabled, use initial MSS of tcp_base_mss.

tcp層丟包

TIME_WAIT過多丟包

大量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)。如果客戶端的并發(fā)量持續(xù)很高,此時(shí)部分客戶端就會(huì)顯示連接不上;

查看:

查看系統(tǒng)log :

dmsg
TCP: time wait bucket table overflow;

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

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

解決方案:

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

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

3. tw_recycle對(duì)客戶端和服務(wù)器同時(shí)起作用,開啟后在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)過NAT節(jié)點(diǎn),不要啟用net.ipv4.tcp_tw_recycle,會(huì)導(dǎo)致時(shí)間戳混亂,引起其他丟包問題;

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

sysctl -w net.ipv4.tcp_max_tw_buckets=163840;

時(shí)間戳異常丟包

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

檢查:

netstat -s | grep rejects

解決方案:

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

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

原理:

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

00f2ffde-949f-11ee-939d-92fbcf53809c.png

協(xié)議處理:

00fd8378-949f-11ee-939d-92fbcf53809c.jpg

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

在三次握手協(xié)議中,服務(wù)器維護(hù)一個(gè)半連接隊(duì)列,該隊(duì)列為每個(gè)客戶端的SYN包開設(shè)一個(gè)條目(服務(wù)端在接收到SYN包的時(shí)候,就已經(jīng)創(chuàng)建了request_sock結(jié)構(gòu),存儲(chǔ)在半連接隊(duì)列中),該條目表明服務(wù)器已收到SYN包,并向客戶發(fā)出確認(rèn),正在等待客戶的確認(rèn)包(會(huì)進(jìn)行第二次握手發(fā)送SYN+ACK的包加以確認(rèn))。這些條目所標(biāo)識(shí)的連接在服務(wù)器處于Syn_RECV狀態(tài),當(dāng)服務(wù)器收到客戶的確認(rèn)包時(shí),刪除該條目,服務(wù)器進(jìn)入ESTABLISHED狀態(tài)。該隊(duì)列為SYN隊(duì)列,長度為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ì)列的長度為 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 listen
SYNs to LISTEN sockets dropped

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

解決方案:增加大小 tcp_max_syn_backlog

連接滿丟包

-xxx times the listen queue of a socket overflowed

查看:

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

ss -lnt查詢socket隊(duì)列 :LISTEN 狀態(tài): Recv-Q 表示的當(dāng)前等待服務(wù)端調(diào)用 accept 完成三次握手的 listen backlog 數(shù)值,也就是說,當(dāng)客戶端通過 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è)置問題,通知客戶程序修改;

syn flood攻擊丟包

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

查看: 查看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ì)列滿了,server發(fā)送一個(gè)reset包給client,表示廢掉這個(gè)握手過程和這個(gè)連接(本來在server端這個(gè)連接就還沒建立起來);

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"passiveconnectionsrejectedbecauseoftime
stamp" -e "packets rejects in established connections because of 
timestamp” 
387158 passive connections rejected because of time stamp
825313 packets rejects in established connections because of timestamp

通過sysctl查看是否啟用了tcp_tw_recycle及tcp_timestamp:

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

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

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

解決方案:

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

TLP問題丟包

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

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

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

查看:

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

netstat -s |grep TCPLossProbes

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

 sysctl -a | grep tcp_early_retrans

010910f8-949f-11ee-939d-92fbcf53809c.png

解決方案:

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

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

3.打開快速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_mem
cat /proc/sys/net/ipv4/tcp_rmem
cat /proc/sys/net/ipv4/tcp_wmem

解決方案:

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

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:

011c1ff4-949f-11ee-939d-92fbcf53809c.png

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

# hping -S 9.199.10.104 -A
HPING 9.199.10.104 (bond1 9.199.10.104): SA set, 40 headers + 0 data bytes
len=46 ip=9.199.10.104 ttl=53 DF id=47617 sport=0 flags=R seq=0 win=0 rtt=38.3 ms
len=46 ip=9.199.10.104 ttl=53 DF id=47658 sport=0 flags=R seq=1 win=0 rtt=38.3 ms
len=46 ip=9.199.10.104 ttl=53 DF id=47739 sport=0 flags=R seq=2 win=0 rtt=30.4 ms
len=46 ip=9.199.10.104 ttl=53 DF id=47842 sport=0 flags=R seq=3 win=0 rtt=30.4 ms
len=46 ip=9.199.10.104 ttl=53 DF id=48485 sport=0 flags=R seq=4 win=0 rtt=38.7 ms
len=46 ip=9.199.10.104 ttl=53 DF id=49274 sport=0 flags=R seq=5 win=0 rtt=34.1 ms
len=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ì)無法判斷是數(shù)據(jù)包丟失還是亂序,因?yàn)閬G包和亂序都會(huì)導(dǎo)致接收端收到次序混亂的數(shù)據(jù)包,造成接收端的數(shù)據(jù)空洞。TCP會(huì)將這種情況暫定為數(shù)據(jù)包的亂序,因?yàn)閬y序是時(shí)間問題(可能是數(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í)間延長。這對(duì)TCP來說無疑是有益的,因?yàn)門CP有充分的時(shí)間判斷數(shù)據(jù)包到底是失序還是丟了來防止不必要的數(shù)據(jù)重傳。當(dāng)然嚴(yán)重的亂序則會(huì)讓發(fā)送端以為是丟包一旦重復(fù)的ACK超過TCP的閾值,便會(huì)觸發(fā)超時(shí)重傳機(jī)制,以及時(shí)解決這種問題;詳細(xì)請(qǐng)參考博客:

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

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

01276a62-949f-11ee-939d-92fbcf53809c.png

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

0138cbf4-949f-11ee-939d-92fbcf53809c.png

擁塞控制丟包

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

Reno、NewReno、Cubic和Vegas,這些改進(jìn)算法大體可以分為基于丟包和基于延時(shí)的擁塞控制算法?;趤G包的擁塞控制算法以Reno、NewReno為代表,它的主要問題有Buffer bloat和長肥管道兩種,基于丟包的協(xié)議擁塞控制機(jī)制是被動(dòng)式的,其依據(jù)網(wǎng)絡(luò)中的丟包事件來做網(wǎng)絡(luò)擁塞判斷。即使網(wǎng)絡(luò)中的負(fù)載很高,只要沒有產(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都很高的長肥管道問題來說,管道中隨機(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提出之前,擁塞控制都是基于事件的算法,需要通過丟包或延時(shí)事件驅(qū)動(dòng);BBR提出之后,擁塞控制是基于反饋的自主自動(dòng)控制算法,對(duì)于速率的控制是由算法決定,而不由網(wǎng)絡(luò)事件決定,BBR算法的核心是找到最大帶寬(Max BW)和最小延時(shí)(Min RTT)這兩個(gè)參數(shù),最大帶寬和最小延時(shí)的乘積可以得到BDP(Bandwidth Delay Product), 而BDP就是網(wǎng)絡(luò)鏈路中可以存放數(shù)據(jù)的最大容量。BDP驅(qū)動(dòng)Probing State Machine得到Rate quantum和cwnd,分別設(shè)置到發(fā)送引擎中就可以解決發(fā)送速度和數(shù)據(jù)量的問題。

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

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

查看:

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

01438dc8-949f-11ee-939d-92fbcf53809c.png

0153e01a-949f-11ee-939d-92fbcf53809c.png

解決方案:

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

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

UDP層丟包

收發(fā)包失敗丟包

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

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

015eed66-949f-11ee-939d-92fbcf53809c.png

解決方案:

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

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

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

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

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

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

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

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

應(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 Buffer
net.core.rmem_default = 31457280
# Maximum Socket Receive Buffer
net.core.rmem_max = 67108864

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

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

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

BDP = 帶寬 * RTT

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

016a24f6-949f-11ee-939d-92fbcf53809c.png

參考: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ì)列的長度為 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沒有流控機(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é)議棧丟包

018116de-949f-11ee-939d-92fbcf53809c.png

相關(guān)工具介紹

1.dropwatch工具

原理:監(jiān)聽 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í)丟包的話,可以使用 dropwatch 工具,它監(jiān)聽系統(tǒng)丟包信息,并打印出丟包發(fā)生的函數(shù):

05e30c5a-949f-11ee-939d-92fbcf53809c.png

2. linux perf 工具監(jiān)聽 kfree_skb:

sudo perf record -g -a -eskb:kfree_skb
sudoperf script

05f85c90-949f-11ee-939d-92fbcf53809c.png

3. tcpdump工具

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

061e7b46-949f-11ee-939d-92fbcf53809c.png

063fb590-949f-11ee-939d-92fbcf53809c.png

抓包命令參考:

數(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)行分析:

4.報(bào)文重放復(fù)現(xiàn)

有些時(shí)候需要通過報(bào)文重放去復(fù)現(xiàn)丟包的場(chǎng)景(或者其他問題的場(chǎng)景)

修改報(bào)文為正確地址:

tcpprep --port --pcap=eth1.pcap --cachefile=in.cache

tcprewrite --cachefile=in.cache -e 10.53.72.134:9.30.231.31 --enet-dmac=504b9c:e7,889e4c:4c --infile=eth1.pcap --outfile=out.pcap

重放:

tcpreplay -i eth1 -t out.pcap

這個(gè)時(shí)候方便在測(cè)試母機(jī)上再進(jìn)一步分析,對(duì)現(xiàn)網(wǎng)影響比較?。?

總結(jié)

本文只是分析大部分可能會(huì)丟包節(jié)點(diǎn),提供了單個(gè)節(jié)點(diǎn)丟包排查和相關(guān)的解決方案, 丟包問題牽扯網(wǎng)絡(luò)鏈路各個(gè)組件,尤其是在云網(wǎng)絡(luò)時(shí)代,網(wǎng)絡(luò)拓?fù)鋸?fù)雜多變,涉及運(yùn)營商網(wǎng)絡(luò),IDC網(wǎng)絡(luò),專線等underlay網(wǎng)絡(luò),邊界網(wǎng)關(guān),VPC網(wǎng)絡(luò),CLB負(fù)載均衡等云上overlay網(wǎng)絡(luò),各種丟包問題排障起來非常復(fù)雜且困難,但掌握網(wǎng)絡(luò)通信基本原理后,可以分解網(wǎng)絡(luò)拓?fù)洌瑢?duì)通信節(jié)點(diǎn)進(jìn)行逐一排查,也可以找到丟包位置。

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

    關(guān)注

    0

    文章

    293

    瀏覽量

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

    關(guān)注

    0

    文章

    238

    瀏覽量

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

    關(guān)注

    1

    文章

    12

    瀏覽量

    8115

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

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

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    網(wǎng)絡(luò)常見故障分析及處理方式

    令:ping -t 192.168.16.1或者ping 192.168.16.1  網(wǎng)絡(luò)網(wǎng)絡(luò)常見
    發(fā)表于 12-01 16:04

    網(wǎng)絡(luò)數(shù)據(jù)及攝像機(jī)的原因

    故障  設(shè)備故障主要是指設(shè)備硬件方面的故障,不包含軟件配置不當(dāng)造成的。如網(wǎng)卡是壞的,交換機(jī)的某個(gè)端口出現(xiàn)了物理
    發(fā)表于 02-19 17:30

    網(wǎng)卡

    網(wǎng)卡率(Loss Tolerance或packet loss rate)是指測(cè)試中
    發(fā)表于 12-26 12:09 ?1274次閱讀

    網(wǎng)絡(luò)數(shù)據(jù)的原因及攝像機(jī)的原因

    不少人在使用網(wǎng)絡(luò)和監(jiān)控?cái)z像系統(tǒng)的時(shí)候都有遇到過數(shù)據(jù)的情況,數(shù)據(jù)的原因是多種多樣的,以下就為大家介紹一下
    的頭像 發(fā)表于 01-11 09:27 ?1.3w次閱讀

    常見的云網(wǎng)絡(luò)故障定位?

    包了,類似情況想必?家都不陌?。針對(duì)?絡(luò),本?提供?些常見
    的頭像 發(fā)表于 02-23 11:30 ?4297次閱讀
    <b class='flag-5'>常見</b>的云<b class='flag-5'>網(wǎng)絡(luò)</b><b class='flag-5'>丟</b><b class='flag-5'>包</b><b class='flag-5'>故障</b><b class='flag-5'>定位</b>?<b class='flag-5'>法</b>

    網(wǎng)絡(luò)怎么辦,常見故障分析及處理方式

    關(guān)于監(jiān)控出現(xiàn)網(wǎng)絡(luò)比較卡、監(jiān)控有幾路畫面不顯示、網(wǎng)絡(luò)時(shí)正常,時(shí)不正常等問題的解決方法,其中這些故障在很多情況下是跟網(wǎng)絡(luò)
    的頭像 發(fā)表于 03-21 11:28 ?1.9w次閱讀

    網(wǎng)絡(luò)時(shí)常用的排錯(cuò)思路

    今天浩道跟大家分享硬核網(wǎng)絡(luò)故障排錯(cuò)干貨,主要針對(duì)網(wǎng)絡(luò)時(shí)常用的排錯(cuò)思路。讓你遇到網(wǎng)絡(luò)
    的頭像 發(fā)表于 10-24 09:20 ?1480次閱讀

    Linux優(yōu)化實(shí)戰(zhàn):如何分析網(wǎng)絡(luò)的問題

    所謂,是指在網(wǎng)絡(luò)數(shù)據(jù)的收發(fā)過程中,由于種種原因,數(shù)據(jù)還沒傳輸?shù)綉?yīng)用程序中,就被丟棄了。
    發(fā)表于 01-13 13:57 ?887次閱讀

    深入分析Linux網(wǎng)絡(luò)問題!

    那到底是哪里發(fā)生了呢?排查之前,我們可以回憶一下 Linux 的網(wǎng)絡(luò)收發(fā)流程,先從理論上分析,哪里有可能會(huì)發(fā)生。你不妨拿出手邊的筆和
    的頭像 發(fā)表于 04-21 09:09 ?997次閱讀

    深入分析Linux網(wǎng)絡(luò)問題

    所謂,是指在網(wǎng)絡(luò)數(shù)據(jù)的收發(fā)過程中,由于種種原因,數(shù)據(jù)還沒傳輸?shù)綉?yīng)用程序中,就被丟棄了。這些被丟棄的數(shù)量,除以總的傳輸
    的頭像 發(fā)表于 05-04 15:08 ?1253次閱讀
    深入分析Linux<b class='flag-5'>網(wǎng)絡(luò)</b><b class='flag-5'>丟</b><b class='flag-5'>包</b>問題

    基于V682-SONiC交換機(jī)的實(shí)現(xiàn)網(wǎng)絡(luò)檢測(cè)的可視化

    網(wǎng)絡(luò)網(wǎng)絡(luò)通信中較為常見故障,越早獲取到
    發(fā)表于 11-09 09:27 ?977次閱讀
    基于V682-SONiC交換機(jī)的實(shí)現(xiàn)<b class='flag-5'>網(wǎng)絡(luò)</b><b class='flag-5'>丟</b><b class='flag-5'>包</b>檢測(cè)的可視化

    網(wǎng)絡(luò)問題解析

    什么是 數(shù)據(jù)在Internet上是以數(shù)據(jù)為單位傳輸?shù)?,單位為字?jié),數(shù)據(jù)在網(wǎng)絡(luò)上傳輸,受網(wǎng)絡(luò)設(shè)備,網(wǎng)
    的頭像 發(fā)表于 11-09 15:10 ?760次閱讀
    <b class='flag-5'>網(wǎng)絡(luò)</b><b class='flag-5'>丟</b><b class='flag-5'>包</b>問題解析

    網(wǎng)絡(luò)故障如何定位

    是數(shù)據(jù)被包了,類似情況想必大家都不陌生。針對(duì)網(wǎng)絡(luò),本人提供一些常見
    的頭像 發(fā)表于 11-10 11:27 ?1022次閱讀
    <b class='flag-5'>網(wǎng)絡(luò)</b><b class='flag-5'>丟</b><b class='flag-5'>包</b><b class='flag-5'>故障</b>如何<b class='flag-5'>定位</b>

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

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

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

    網(wǎng)絡(luò)率正常范圍及其影響因素 網(wǎng)絡(luò)率是評(píng)估網(wǎng)絡(luò)
    的頭像 發(fā)表于 12-29 14:45 ?4429次閱讀