在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

網絡丟包故障如何定位

科技綠洲 ? 來源:Linux開發架構之路 ? 作者:Linux開發架構之路 ? 2023-11-10 11:27 ? 次閱讀

引言

本期分享一個比較常見的網絡問題--丟包。例如我們去ping一個網站,如果能ping通,且網站返回信息全面,則說明與網站服務器的通信是暢通的,如果ping不通,或者網站返回的信息不全等,則很可能是數據被丟包了,類似情況想必大家都不陌生。針對網絡丟包,本人提供一些常見的丟包故障定位方法,希望能夠幫助大家對網絡丟包有更多的認識,遇到丟包莫要慌,且跟著一起來漲姿(知)勢(識)···

什么是丟包

數據在Internet上是以數據包為單位傳輸的,單位為字節,數據在網絡上傳輸,受網絡設備,網絡質量等原因的影響,使得接收到的數據少于發送出去的數據,造成丟包。

數據包接收、發送原理

圖片

發送數據包:

1.應用程序的數據包,在TCP層增加TCP報文頭,形成可傳輸的數據包。2.在IP層增加IP報頭,形成IP報文。3.經過數據網卡驅動程序將IP包再添加14字節的MAC頭,構成frame(暫?CRC),frame(暫?CRC)中含有發送端和接收端的MAC地址。4.驅動程序將frame(暫?CRC)拷貝到網卡的緩沖區,由網卡處理。5.?卡為frame(暫?CRC)添加頭部同步信息和CRC校驗,將其封裝為可以發送的packet,然后再發送到網線上,這樣說就完成了一個IP報文的發送了,所有連接到這個網線上的網卡都可以看到該packet。

接收數據包:

圖片

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

核心思路

了解了收發包的原理,可以了解到丟包原因主要會涉及?卡設備、?卡驅動、內核協議棧三?類。以下我們將遵循“從下到上分層分析(各層可能性出現的丟包場景),然后查看關鍵信息,最終得出分析結果”的原則展開介紹。

目錄--網絡丟包情形概覽

硬件網卡丟包

網卡驅動丟包

以太網鏈路層丟包

網絡IP層丟包

傳輸層UDP/TCP丟包

應用層socket丟包

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

硬件網卡丟包

Ring Buffer溢出

圖片

如圖所示,物理介質上的數據幀到達后首先由NIC(網絡適配器)讀取,寫入設備內部緩沖區Ring Buffer中,再由中斷處理程序觸發Softirq從中消費,Ring Buffer的大小因網卡設備而異。當網絡數據包到達(生產)的速率快于內核處理(消費)的速率時,Ring Buffer很快會被填滿,新來的數據包將被丟棄;

查看:

通過ethtool或/proc/net/dev可以查看因Ring Buffer滿而丟棄的包統計,在統計項中以fifo標識:

$ ethtool -S eth0|grep rx_fifo
rx_fifo_errors: 0
$ cat /proc/net/dev
Inter-|Receive | Transmitface |bytes packets errs drop fifo frame compressed
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網卡Ring Buffer最大值和當前設置

$ ethtool -g eth0

解決方案:修改網卡eth0接收與發送硬件緩存區大小

$ ethtool -G eth0 rx 4096 tx 4096

網卡端口協商丟包

  1. 查看網卡丟包統計:ethtool -S eth1/eth0

圖片

  1. 查看網卡配置狀態:ethtool eth1/eth0

圖片

主要查看網卡和上游網絡設備協商速率和模式是否符合預期;

解決方案:

1 重新自協商:ethtool -r eth1/eth0;

2 如果上游不支持自協商,可以強制設置端口速率:

ethtool -s eth1 speed 1000 duplex full autoneg off

網卡流控丟包

  1. 查看流控統計:
ethtool -S eth1 | grep control

圖片

rx_flow_control_xon是在網卡的RX Buffer滿或其他網卡內部的資源受限時,給交換機端口發送的開啟流控的pause幀計數。對應的,tx_flow_control_xoff是在資源可用之后發送的關閉流控的pause幀計數。

2 .查看網絡流控配置:ethtool -a eth1

圖片

解決方案:關閉網卡流控

ethtool -A ethx autoneg off //自協商關閉
ethtool -A ethx tx off //發送模塊關閉
ethtool -A ethx rx off //接收模塊關閉

報文mac地址丟包

一般計算機網卡都工作在非混雜模式下,此時網卡只接受來自網絡端口的目的地址指向自己的數據,如果報文的目的mac地址不是對端的接口的mac地址,一般都會丟包,一般這種情況很有可能是源端設置靜態arp表項或者動態學習的arp表項沒有及時更新,但目的端mac地址已發生變化(換了網卡),沒有更新通知到源端(比如更新報文被丟失,中間交換機異常等情況);

查看:

1.目的端抓包,tcpdump可以開啟混雜模式,可以抓到對應的報文,然后查看mac地址;

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

解決方案:

1.刷新arp表然后發包觸發arp重新學習(可能影響其他報文,增加延時,需要小心操作);

2.可以在源端手動設置正確的靜態的arp表項;

其他網卡異常丟包

這類異常比少見,但如果都不是上面哪些情況,但網卡統計里面任然有丟包計數,可以試著排查一下:

網卡firmware版本:

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

圖片

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

網線接觸不良:

如果網卡統計里面存在crc error 計數增長,很可能是網線接觸不良,可以通知網管排查一下:

ethtool -S eth0

圖片

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

報文長度丟包

網卡有接收正確報文長度范圍,一般正常以太網報文長度范圍:64-1518,發送端正常情況會填充或者分片來適配,偶爾會發生一些異常情況導致發送報文不正常丟包;

查看:

ethtool -S eth1|grep length_errors

圖片

解決方案:

1 調整接口MTU配置,是否開啟支持以太網巨幀;

2 發送端開啟PATH MTU進行合理分片;

簡單總結一下網卡丟包:

圖片

網卡驅動丟包

查看:ifconfig eth1/eth0 等接口

圖片

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

2.RX dropped: 表示數據包已經進入了 Ring Buffer,但是由于內存不夠等系統原因,導致在拷貝到內存的過程中被丟棄。

3.RX overruns: 表示了 fifo 的 overruns,這是由于 Ring Buffer(aka Driver Queue) 傳輸的 IO 大于 kernel 能夠處理的 IO 導致的,而 Ring Buffer 則是指在發起 IRQ 請求之前的那塊 buffer。很明顯,overruns 的增大意味著數據包沒到 Ring Buffer 就被網卡物理層給丟棄了,而 CPU 無法即使的處理中斷是造成 Ring Buffer 滿的原因之一,上面那臺有問題的機器就是因為 interruprs 分布的不均勻(都壓在 core0),沒有做 affinity 而造成的丟包。

  1. RX frame: 表示 misaligned 的 frames。
  2. 對于 TX 的來說,出現上述 counter 增大的原因主要包括 aborted transmission, errors due to carrirer, fifo error, heartbeat erros 以及 windown error,而 collisions 則表示由于 CSMA/CD 造成的傳輸中斷。

驅動溢出丟包

netdev_max_backlog是內核從NIC收到包后,交由協議棧(如IP、TCP)處理之前的緩沖隊列。每個CPU核都有一個backlog隊列,與Ring Buffer同理,當接收包的速率大于內核協議棧處理的速率時,CPU的backlog隊列不斷增長,當達到設定的netdev_max_backlog值時,數據包將被丟棄。

查看:

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

圖片

其中:每一行代表每個CPU核的狀態統計,從CPU0依次往下;每一列代表一個CPU核的各項統計:第一列代表中斷處理程序收到的包總數;第二列即代表由于netdev_max_backlog隊列溢出而被丟棄的包總數。從上面的輸出可以看出,這臺服務器統計中,并沒有因為netdev_max_backlog導致的丟包。

解決方案:

netdev_max_backlog的默認值是1000,在高速鏈路上,可能會出現上述第二統計不為0的情況,可以通過修改內核參數 net.core.netdev_max_backlog來解決:

$ sysctl -w net.core.netdev_max_backlog=2000

單核負載高導致丟包

單核CPU軟中斷占有高, 導致應用沒有機會收發或者收包比較慢,即使調整netdev_max_backlog隊列大小仍然會一段時間后丟包,處理速度跟不上網卡接收的速度;

查看:mpstat -P ALL 1

單核軟中斷占有100%,導致應用沒有機會收發或者收包比較慢而丟包;

解決方案:

1.調整網卡RSS隊列配置:

查看:ethtool -x ethx;

調整:ethtool -X ethx xxxx;

2.看一下網卡中斷配置是否均衡 cat /proc/interrupts

調整:

1) irqbalance 調整;
# 查看當前運行情況
service irqbalance status
# 終止服務
service irqbalance stop
2) 中斷綁CPU核 echo mask > /proc/irq/xxx/smp_affinity

3.根據CPU和網卡隊列個數調整網卡多隊列和RPS配置

-CPU大于網卡隊列個數:

查看網卡隊列 ethtool -x ethx;

協議棧開啟RPS并設置RPS;

echo $mask(CPU配置)> /sys/class/net/$eth/queues/rx-$i/rps_cpus
echo 4096(網卡buff)> /sys/class/net/$eth/queues/rx-$i/rps_flow_cnt
2)CPU小于網卡隊列個數,綁中斷就可以,可以試著關閉RPS看一下效果:
echo 0 > /sys/class/net//queues/rx-/rps_cpus

4.numa CPU調整,對齊網卡位置,可以提高內核處理速度,從而給更多CPU給應用收包,減緩丟包概率;

查看網卡numa位置:

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

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

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

查看 :

ethtool -c ethx
Coalesce parameters for eth1:
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

調整:

ethtool -C ethx adaptive-rx on

簡單總結一下網卡驅動丟包處理:

圖片

內核協議棧丟包

以太網鏈路層丟包

neighbor系統arp丟包

arp_ignore配置丟包

arp_ignore參數的作用是控制系統在收到外部的arp請求時,是否要返回arp響應。arp_ignore參數常用的取值主要有0,1,2,3~8較少用到;

查看:sysctl -a|grep arp_ignore

圖片

解決方案:根據實際場景設置對應值;

0:響應任意網卡上接收到的對本機IP地址的arp請求(包括環回網卡上的地址),而不管該目的IP是否在接收網卡上。

1:只響應目的IP地址為接收網卡上的本地地址的arp請求。

2:只響應目的IP地址為接收網卡上的本地地址的arp請求,并且arp請求的源IP必須和接收網卡同網段。

3:如果ARP請求數據包所請求的IP地址對應的本地地址其作用域(scope)為主機(host),則不回應ARP響應數據包,如果作用域為全局(global)或鏈路(link),則回應ARP響應數據包。

圖片

圖片

arp_filter配置丟包

在多接口系統里面(比如騰訊云的彈性網卡場景),這些接口都可以回應arp請求,導致對端有可能學到不同的mac地址,后續報文發送可能由于mac地址和接收報文接口mac地址不一樣而導致丟包,arp_filter主要是用來適配這種場景;

查看:

sysctl -a | grep arp_filter

圖片

解決方案:

根據實際場景設置對應的值,一般默認是關掉此過濾規則,特殊情況可以打開;
0:默認值,表示回應arp請求的時候不檢查接口情況;
1:表示回應arp請求時會檢查接口是否和接收請求接口一致,不一致就不回應;

arp表滿導致丟包

比如下面這種情況,由于突發arp表項很多 超過協議棧默認配置,發送報文的時候部分arp創建失敗,導致發送失敗,從而丟包:

圖片

查看:

  • 查看arp狀態:cat /proc/net/stat/arp_cache ,table_fulls統計:
  • 查看dmesg消息(內核打印):

圖片

dmesg|grep neighbour
neighbour: arp_cache: neighbor table overflow!
  • 查看當前arp表大小:ip n|wc -l

查看系統配額:

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


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

一般在內存足夠情況下,可以認為gc_thresh3 值是arp 表總大小;

解決方案:根據實際arp最大值情況(比如訪問其他子機最大個數),調整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請求緩存隊列溢出丟包

查看:

cat /proc/net/stat/arp_cache ,unresolved_discards是否有新增計數

解決方案:根據客戶需求調整緩存隊列大小unres_qlen_bytes:

圖片

網絡IP層丟包

接口ip地址配置丟包

  1. 本機服務不通,檢查lo接口有沒有配置地址是127.0.0.1;

2 .本機接收失敗, 查看local路由表:ip r show table local|grep 子機ip地址;這種丟包一般會出現在多IP場景,子機底層配置多ip失敗,導致對應ip收不到包而丟包;

圖片

解決方案:

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

2.如果發現接口有地址還丟包,可能是local路由表沒有對應條目,緊急情況下,可以用手工補上:

比如ip r add local 本機ip地址 dev eth0 table local ;

路由丟包

路由配置丟包

查看:

1.查看配置 路由是否設置正確(是否可達),是否配置策略路由(在彈性網卡場景會出現此配置)ip rule:

圖片

然后找到對應路由表。查看路由表:

圖片

或者直接用 ip r get x.x.x.x,讓系統幫你查找是否存在可達路由,接口是否符合預期;

2.查看系統統計信息:

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

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

反向路由過濾丟包

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

查看:

rp_filter提供三種模式供配置:

0 - 不驗證

1 - RFC3704定義的嚴格模式:對每個收到的數據包,查詢反向路由,如果數據包入口和反向路由出口不一致,則不通過

2 - RFC3704定義的松散模式:對每個收到的數據包,查詢反向路由,如果任何接口都不可達,則不通過

查看當前rp_filter策略配置:

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

如果這里設置為1,就需要查看主機的網絡環境和路由策略是否可能會導致客戶端的入包無法通過反向路由驗證了。

從原理來看這個機制工作在網絡層,因此,如果客戶端能夠Ping通服務器,就能夠排除這個因素了。

解決方案:

根據實際網絡環境將rp_filter設置為0或2:

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

防火墻丟包

客戶設置規則導致丟包

查看:

iptables -nvL |grep DROP ;

解決方案:修改防火墻規則;

連接跟蹤導致丟包

連接跟蹤表溢出丟包

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

查看當前連接跟蹤數 :

cat /proc/sys/net/netfilter/nf_conntrack_max

解決方案:

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

ct創建沖突失導致丟包

查看:當前連接跟蹤統計:cat /proc/net/stat/nf_conntrack,可以查各種ct異常丟包統計

圖片

解決方案:內核熱補丁修復或者更新內核版本(合入補丁修改);

傳輸層UDP/TCP丟包

tcp 連接跟蹤安全檢查丟包

丟包原因:由于連接沒有斷開,但服務端或者client之前出現過發包異常等情況(報文沒有經過連接跟蹤模塊更新窗口計數),沒有更新合法的window范圍,導致后續報文安全檢查被丟包;協議棧用 nf_conntrack_tcp_be_liberal 來控制這個選項:

1:關閉,只有不在tcp窗口內的rst包被標志為無效;

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

查看:

查看配置 :

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

查看log:

一般情況下netfiler模塊默認沒有加載log,需要手動加載;

modprobe ipt_LOG11
sysctl -w net.netfilter.nf_log.2=ipt_LOG

然后發包后在查看syslog;

解決方案:根據實際抓包分析情況判斷是不是此機制導致的丟包,可以試著關閉試一下;

分片重組丟包

情況總結:超時

查看:

netstat -s|grep timeout
601 fragments dropped after timeout

解決方法:調整超時時間

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

frag_high_thresh, 分片的內存超過一定閾值會導致系統安全檢查丟包

查看:

netstat -s|grep reassembles
8094 packet reassembles failed

解決方案:調整大小

net.ipv4.ipfrag_high_thresh
net.ipv4.ipfrag_low_thresh

分片安全距檢查離丟包

查看:

netstat -s|grep reassembles
8094 packet reassembles failed

解決方案:把ipfrag_max_dist設置為0,就關掉此安全檢查

圖片

pfrag_max_dist特性,在一些場景下其實并不適用:

1.有大量的網絡報文交互

2.發送端的并發度很高,同時SMP架構,導致很容易造成這種亂序情況;

分片hash bucket沖突鏈太長超過系統默認值128

查看:

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

解決方案:熱補丁調整hash大小;

系統內存不足,創建新分片隊列失敗

查看方法:

netstat -s|grep reassembles
8094 packet reassembles failed

dropwatch查看丟包位置 :

圖片

解決方案:

a.增大系統網絡內存:

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

b.系統回收內存:

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

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丟包

圖片

查看:

1.檢查接口MTU配置,ifconfig eth1/eth0,默認是1500;

2.進行MTU探測,然后設置接口對應的MTU值;

解決方案:

  1. 根據實際情況,設置正確MTU值;
  2. 設置合理的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出現,并且需要解決的場景,在高并發短連接的TCP服務器上,當服務器處理完請求后立刻按照主動正常關閉連接。。。這個場景下,會出現大量socket處于TIMEWAIT狀態。如果客戶端的并發量持續很高,此時部分客戶端就會顯示連接不上;

查看:

查看系統log :

dmsg
TCP: time wait bucket table overflow;

查看系統配置:

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

解決方案:

  1. tw_reuse,tw_recycle 必須在客戶端和服務端timestamps 開啟時才管用(默認打開)
  2. tw_reuse 只對客戶端起作用,開啟后客戶端在1s內回收;
  3. tw_recycle對客戶端和服務器同時起作用,開啟后在3.5*RTO 內回收,RTO 200ms~ 120s具體時間視網絡狀況。內網狀況比tw_reuse稍快,公網尤其移動網絡大多要比tw_reuse 慢,優點就是能夠回收服務端的TIME_WAIT數量;

在服務端,如果網絡路徑會經過NAT節點,不要啟用net.ipv4.tcp_tw_recycle,會導致時間戳混亂,引起其他丟包問題;

  1. 調整tcp_max_tw_buckets大小,如果內存足夠:
sysctl -w net.ipv4.tcp_max_tw_buckets=163840;

時間戳異常丟包

當多個客戶端處于同一個NAT環境時,同時訪問服務器,不同客戶端的時間可能不一致,此時服務端接收到同一個NAT發送的請求,就會出現時間戳錯亂的現象,于是后面的數據包就被丟棄了,具體的表現通常是是客戶端明明發送的SYN,但服務端就是不響應ACK。在服務器借助下面的命令可以來確認數據包是否有不斷被丟棄的現象。

檢查:

netstat -s | grep rejects

解決方案:

如果網絡路徑會經過NAT節點,不要啟用net.ipv4.tcp_tw_recycle;

TCP隊列問題導致丟包

原理:

tcp狀態機(三次握手)

圖片

協議處理:

圖片

一個是半連接隊列(syn queue):

在三次握手協議中,服務器維護一個半連接隊列,該隊列為每個客戶端的SYN包開設一個條目(服務端在接收到SYN包的時候,就已經創建了request_sock結構,存儲在半連接隊列中),該條目表明服務器已收到SYN包,并向客戶發出確認,正在等待客戶的確認包(會進行第二次握手發送SYN+ACK的包加以確認)。這些條目所標識的連接在服務器處于Syn_RECV狀態,當服務器收到客戶的確認包時,刪除該條目,服務器進入ESTABLISHED狀態。該隊列為SYN隊列,長度為max(64, /proc/sys/net/ipv4/tcp_max_syn_backlog), 機器的tcp_max_syn_backlog值在/proc/sys/net/ipv4/tcp_max_syn_backlog下配置;

一個是全連接隊列(accept queue):

第三次握手時,當server接收到ACK 報之后, 會進入一個新的叫 accept 的隊列,該隊列的長度為 min(backlog, somaxconn),默認情況下,somaxconn 的值為 128,表示最多有 129 的 ESTAB 的連接等待 accept(),而 backlog 的值則應該是由 int listen(int sockfd, int backlog) 中的第二個參數指定,listen 里面的 backlog 可以有我們的應用程序去定義的;

查看:

連接建立失敗,syn丟包:

netstat -s |grep -i listen
SYNs to LISTEN sockets dropped

也會受到連接滿丟包影響

解決方案:增加大小 tcp_max_syn_backlog

連接滿丟包

-xxx times the listen queue of a socket overflowed

查看:

  • 查看accept隊列大小 :net.core.somaxconn
  • ss -lnt查詢socket隊列 :LISTEN 狀態: Recv-Q 表示的當前等待服務端調用 accept 完成三次握手的 listen backlog 數值,也就是說,當客戶端通過 connect() 去連接正在 listen() 的服務端時,這些連接會一直處于這個 queue 里面直到被服務端 accept();Send-Q 表示的則是最大的 listen backlog 數值,這就就是上面提到的 min(backlog, somaxconn) 的值,
  • 看一下是不是應用程序設置限制, int listen(int sockfd, int backlog);

解決方案:

  • Linux內核參進行優化,可以緩解壓力 tcp_abort_on_overflow=1
  • 調整net.core.somaxconn大小;
  • 應用程序設置問題,通知客戶程序修改;

syn flood攻擊丟包

目前,Linux下默認會進行5次重發SYN-ACK包,重試的間隔時間從1s開始,下次的重試間隔時間是前一次的雙倍,5次的重試時間間隔為1s, 2s, 4s, 8s, 16s,總共31s,第5次發出后還要等32s都知道第5次也超時了,所以,總共需要 1s + 2s + 4s+ 8s+ 16s + 32s = 63s,TCP才會把斷開這個連接。由于,SYN超時需要63秒,那么就給攻擊者一個攻擊服務器的機會,攻擊者在短時間內發送大量的SYN包給Server(俗稱 SYN flood 攻擊),用于耗盡Server的SYN隊列。對于應對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表示第三步的時候如果全連接隊列滿了,server發送一個reset包給client,表示廢掉這個握手過程和這個連接(本來在server端這個連接就還沒建立起來);

PAWS機制丟包

原理:PAWS(Protect Against Wrapped Sequence numbers),高帶寬下,TCP序列號可能在較短的時間內就被重復使用(recycle/wrapped) 就可能導致同一條TCP流在短時間內出現序號一樣的兩個合法的數據包及其確認包。

查看:

$netstat -s |grep -e "passive connections rejected because of time
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參數。它用來快速回收TIME_WAIT連接,不過如果在NAT環境下會引發問題;
  2. 當多個客戶端通過NAT方式聯網并與服務端交互時,服務端看到的是同一個IP,也就是說對服務端而言這些客戶端實際上等同于一個,可惜由于這些客戶端的時間戳可能存在差異,于是乎從服務端的視角看,便可能出現時間戳錯亂的現象,進而直接導致時間戳小的數據包被丟棄。如果發生了此類問題,具體的表現通常是是客戶端明明發送的SYN,但服務端就是不響應ACK。

解決方案:

在NAT環境下,清除tcp時間戳選項,或者不開啟tcp_tw_recycle參數;

TLP問題丟包

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

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

但在低時延場景下(短連接小包量),TLP與延遲ACK組合可能會造成無效重傳,導致客戶端感發現大量假重傳包,加大了響應延遲;

查看:

查看協議棧統計:

netstat -s |grep TCPLossProbes

查看系統配置:

sysctl -a | grep tcp_early_retrans

圖片

解決方案:

1.關掉延遲ack,打開快速ack;

2.linux實現nodelay語意不是快速ack,只是關閉nagle算法

3.打開快速ack選項,socket里面有個 TCP_QUICKACK 選項, 需要每次recv后再設置一次。

內存不足導致丟包

查看:

查看log:

dmesg|grep “out of memory”

查看系統配置:

cat /proc/sys/net/ipv4/tcp_mem
cat /proc/sys/net/ipv4/tcp_rmem
cat /proc/sys/net/ipv4/tcp_wmem

解決方案:

根據TCP業務并發流量,調整系統參數,一般試著增大2倍或者其他倍數來看是否緩解;

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

TCP超時丟包

查看:

抓包分析一下網絡RTT:

圖片

用其他工具測試一下當前端到端網絡質量(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

解決方案:

  • 關閉Nagle算法,減少小包延遲;
  • 關閉延遲ack:
sysctl -w net.ipv4.tcp_no_delay_ack=1

TCP亂序丟包

此時TCP會無法判斷是數據包丟失還是亂序,因為丟包和亂序都會導致接收端收到次序混亂的數據包,造成接收端的數據空洞。TCP會將這種情況暫定為數據包的亂序,因為亂序是時間問題(可能是數據包的遲到),而丟包則意味著重傳。當TCP意識到包出現亂序的情況時,會立即ACK,該ACK的TSER部分包含的TSEV值會記錄當前接收端收到有序報文段的時刻。這會使得數據包的RTT樣本值增大,進一步導致RTO時間延長。這對TCP來說無疑是有益的,因為TCP有充分的時間判斷數據包到底是失序還是丟了來防止不必要的數據重傳。當然嚴重的亂序則會讓發送端以為是丟包一旦重復的ACK超過TCP的閾值,便會觸發超時重傳機制,以及時解決這種問題;

查看:抓包分析是否存在很多亂序報文:

圖片

解決方案:如果在多徑傳輸場景或者網絡質量不好,可以通過修改下面值來提供系統對TCP無序傳送的容錯率:

圖片

擁塞控制丟包

在互聯網發展的過程當中,TCP算法也做出了一定改變,先后演進了

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

Linux 4.9內核首次采用BBR擁塞控制算法第一個版本,BBR抗丟包能力比其他算法要強,但這個版本在某些場景下面有問題(缺點),BBR在實時音視頻領域存在的問題,深隊列競爭不過Cubic。

問題現象就是:在深隊列場景,BBR的ProbeRTT階段只發4個包,發送速率下降太多會引發延遲加大和卡頓問題。

查看:

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

圖片

圖片

解決方案:

  • ProbeRTT并不適用實時音視頻領域,因此可以選擇直接去除,或者像BBRV2把probe RTT縮短到2.5s一次,使用0.5xBDP發送;
  • 如果沒有特殊需求,切換成穩定的cubic算法;

UDP層丟包

收發包失敗丟包

查看:netstat 統計

如果有持續的 receive buffer errors/send buffer errors 計數;

圖片

解決方案:

  1. CPU負載(多核綁核配置),網絡負載(軟中斷優化,調整驅動隊列netdev_max_backlog),內存配置(協議棧內存);
  2. 按峰值在來,增大buffer緩存區大小:
net.ipv4.udp_mem = xxx
net.ipv4.udp_rmem_min = xxx
net.ipv4.udp_wmem_min = xxx
  1. 調整應用設計:
  • UDP本身就是無連接不可靠的協議,適用于報文偶爾丟失也不影響程序狀態的場景,比如視頻音頻、游戲、監控等。對報文可靠性要求比較高的應用不要使用 UDP,推薦直接使用 TCP。當然,也可以在應用層做重試、去重保證可靠性
  • 如果發現服務器丟包,首先通過監控查看系統負載是否過高,先想辦法把負載降低再看丟包問題是否消失
  • 如果系統負載過高,UDP丟包是沒有有效解決方案的。如果是應用異常導致CPU、memory、IO 過高,請及時定位異常應用并修復;如果是資源不夠,監控應該能及時發現并快速擴容
  • 對于系統大量接收或者發送UDP報文的,可以通過調節系統和程序的 socket buffer size 來降低丟包的概率
  • 應用程序在處理UDP報文時,要采用異步方式,在兩次接收報文之間不要有太多的處理邏輯

應用層socket丟包

socket緩存區接收丟包

查看:

  1. 抓包分析是否存在丟包情況;
  2. 查看統計:
netstat -s|grep "packet receive errors"

解決方案:

調整socket緩沖區大小:

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

具體大小調整原理:

緩沖區大小沒有任何設置值是最佳的,因為最佳大小隨具體情況而不同

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

BDP = 帶寬 * RTT

可以通過計算當面節點帶寬和統計平均時延來估算BDP,即緩沖區的大小,可以參考下面常見場景估計:

圖片

應用設置tcp連接數大小丟包

查看:

請參考上面TCP連接隊列分析;

解決方案:

設置合理的連接隊列大小,當第三次握手時,當server接收到ACK 報之后, 會進入一個新的叫 accept 的隊列,該隊列的長度為 min(backlog, somaxconn),默認情況下,somaxconn 的值為 128,表示最多有 129 的 ESTAB 的連接等待 accept(),而 backlog 的值則應該是由 int listen(int sockfd, int backlog) 中的第二個參數指定,listen 里面的 backlog 可以有我們的應用程序去定義的;

應用發送太快導致丟包

查看統計:

netstat -s|grep "send buffer errors

解決方案:

  • ICMP/UDP沒有流控機制,需要應用設計合理發送方式和速度,照顧到底層buff大小和CPU負載以及網絡帶寬質量;
  • 設置合理的sock緩沖區大小:
setsockopt(s,SOL_SOCKET,SO_SNDBUF, i(const char*)&nSendBuf,sizeof(int));
  • 調整系統socket緩沖區大小:
# Default Socket Send Buffer
net.core.wmem_default = 31457280
# Maximum Socket Send Buffer
net.core.wmem_max = 33554432

附:簡單總結一下內核協議棧丟包:

圖片

相關工具介紹

1.dropwatch工具

原理:監聽 kfree_skb(把網絡報文丟棄時會調用該函數)函數或者事件嗎,然后打印對應調用堆棧;想要詳細了解 linux 系統在執行哪個函數時丟包的話,可以使用 dropwatch 工具,它監聽系統丟包信息,并打印出丟包發生的函數:

圖片

  1. tcpdump工具

原理: tcpdump 是一個Unix下一個功能強大的網絡抓包工具,它允許用戶攔截和顯示發送或收到過網絡連接到該計算機的TCP/IP和其他數據包

圖片

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • crc
    crc
    +關注

    關注

    0

    文章

    199

    瀏覽量

    29465
  • 網絡
    +關注

    關注

    14

    文章

    7565

    瀏覽量

    88788
  • 解碼
    +關注

    關注

    0

    文章

    181

    瀏覽量

    27392
  • 丟包
    +關注

    關注

    1

    文章

    12

    瀏覽量

    8155
收藏 人收藏

    評論

    相關推薦

    常見的網絡故障定位?法

    包了,類似情況想必?家都不陌?。針對?絡,本?提供?些常見的故障
    的頭像 發表于 12-07 09:48 ?1828次閱讀
    常見的<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>?法

    網絡常見故障分析及處理方式

    令:ping -t 192.168.16.1或者ping 192.168.16.1  網絡網絡中常見的故障之一,它會引起網速降低甚至造
    發表于 12-01 16:04

    網絡數據及攝像機的原因

    故障  設備故障主要是指設備硬件方面的故障,不包含軟件配置不當造成的。如網卡是壞的,交換機的某個端口出現了物理
    發表于 02-19 17:30

    網卡

    網卡率(Loss Tolerance或packet loss rate)是指測試中
    發表于 12-26 12:09 ?1303次閱讀

    網絡數據的原因及攝像機的原因

    不少人在使用網絡和監控攝像系統的時候都有遇到過數據的情況,數據的原因是多種多樣的,以下就為大家介紹一下
    的頭像 發表于 01-11 09:27 ?1.3w次閱讀

    常見的云網絡故障定位?法

    包了,類似情況想必?家都不陌?。針對?絡,本?提供?些常見的故障
    的頭像 發表于 02-23 11:30 ?4463次閱讀
    常見的云<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>?法

    網絡怎么辦,常見故障分析及處理方式

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

    網絡時常用的排錯思路

    今天浩道跟大家分享硬核網絡故障排錯干貨,主要針對網絡時常用的排錯思路。讓你遇到網絡
    的頭像 發表于 10-24 09:20 ?1695次閱讀

    Linux優化實戰:如何分析網絡的問題

    所謂,是指在網絡數據的收發過程中,由于種種原因,數據還沒傳輸到應用程序中,就被丟棄了。
    發表于 01-13 13:57 ?976次閱讀

    深入分析Linux網絡問題!

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

    深入分析Linux網絡問題

    所謂,是指在網絡數據的收發過程中,由于種種原因,數據還沒傳輸到應用程序中,就被丟棄了。這些被丟棄的數量,除以總的傳輸
    的頭像 發表于 05-04 15:08 ?1397次閱讀
    深入分析Linux<b class='flag-5'>網絡</b><b class='flag-5'>丟</b><b class='flag-5'>包</b>問題

    基于V682-SONiC交換機的實現網絡檢測的可視化

    網絡網絡通信中較為常見的故障,越早獲取到
    發表于 11-09 09:27 ?1340次閱讀
    基于V682-SONiC交換機的實現<b class='flag-5'>網絡</b><b class='flag-5'>丟</b><b class='flag-5'>包</b>檢測的可視化

    網絡問題解析

    什么是 數據在Internet上是以數據為單位傳輸的,單位為字節,數據在網絡上傳輸,受網絡設備,
    的頭像 發表于 11-09 15:10 ?916次閱讀
    <b class='flag-5'>網絡</b><b class='flag-5'>丟</b><b class='flag-5'>包</b>問題解析

    網絡問題分析

    所謂,是指在網絡數據的收發過程中,由于種種原因,數據還沒傳輸到應用程序中,就被丟棄了。這些被丟棄的數量,除以總的傳輸
    的頭像 發表于 11-13 11:24 ?1016次閱讀
    <b class='flag-5'>網絡</b><b class='flag-5'>丟</b><b class='flag-5'>包</b>問題分析

    網絡率正常范圍及其影響因素

    網絡率正常范圍及其影響因素 網絡率是評估網絡
    的頭像 發表于 12-29 14:45 ?6258次閱讀
    主站蜘蛛池模板: 成年女人色费视频免费| 又粗又大的机巴好爽欧美| 国产精品推荐天天看天天爽| 高清成年美女黄网站色大| 欧美另类丰满69xxxxx| 唐人社电亚洲一区二区三区 | 69pao强力打造在线| 日本亚洲免费| 亚洲国产成人精品不卡青青草原| 91av视频| 四虎hu| 久久视频精品线视频在线网站| 高清性色生活片欧美在线| 天天干夜夜拍| 99xxxx开心| 久久国产精品无码网站| 色色色色网站| 黄色日本视频网站| 亚洲丁香网| 91aaa免费观看在线观看资源 | 婷婷激情视频| 久久的色偷偷| 天堂资源地址在线| xxxx人妖| 亚洲xx网站| 精品国产成人系列| 国产高清亚洲| 婷婷六月天在线| 午夜在线观看网站| 在线观看网站黄| 亚洲在成人网在线看| 免费看污视频软件| 天天做天天爱天天操| 欧美激情第一欧美在线| 色噜噜综合网| 色天使久久综合给合久久97色| 又黄又湿又爽| 免费看黄的视频软件| 国产第一页在线观看| 三级精品| 午夜国产片|