Linux丟包問題排查思路
判斷問題與網(wǎng)絡(luò)丟包有關(guān)
通過抓tcpdump,通過wireshark提示查看數(shù)據(jù)包狀態(tài)。比如客戶端重傳多次失敗,服務(wù)端提示丟包等錯誤,均是可能由于丟包導(dǎo)致的異常。
丟包可能存在的位置
網(wǎng)絡(luò)丟包在交互過程中的每一個環(huán)節(jié)都有可能出現(xiàn)。主要環(huán)節(jié)如下:
- 兩端服務(wù)器:主要表現(xiàn)在網(wǎng)卡異常、服務(wù)器資源限制(負(fù)載,TCP連接數(shù)等)、軟件異常、服務(wù)器配置等導(dǎo)致的丟包
- 網(wǎng)絡(luò)鏈路(包括鏈路層、網(wǎng)絡(luò)層、傳輸層):主要是TCP/UDP傳輸過程中出現(xiàn)異常導(dǎo)致,比如:arp表溢出、路由過濾、防火墻攔截、tcp分片重組超時重組異常失敗、MTU丟包、限速限流、帶寬占滿等導(dǎo)致的丟包。
- 應(yīng)用層:主要表現(xiàn)在應(yīng)用在處理socket連接時的異常。
丟包原因分析
網(wǎng)絡(luò)鏈路丟包
網(wǎng)絡(luò)鏈路的丟包主要通過網(wǎng)絡(luò)鏈路的監(jiān)控、以及客戶端抓包數(shù)據(jù)完整、但服務(wù)端收包內(nèi)容有截取等判斷,需要考慮鏈路中的防火墻等安全設(shè)備的影響,首先排除掉安全設(shè)備的原因。
我們在實(shí)際生產(chǎn)中有遇到過nginx響應(yīng)請求返回400/499,經(jīng)分析,存在WAF過濾報文中部分信息、大包未分片導(dǎo)致超過MTU限值的情況。
應(yīng)用層丟包
應(yīng)用層丟包主要出現(xiàn)在應(yīng)用使用線程池化的模式處理請求連接池,當(dāng)池化不合理導(dǎo)致池滿未釋放,無法建立新連接時容易出現(xiàn)。
服務(wù)器上的丟包情況
接下來著重討論應(yīng)該如何在服務(wù)器上排查丟包情況。
請求在服務(wù)器內(nèi)部的流程
-
首先網(wǎng)絡(luò)報文通過物理網(wǎng)線發(fā)送到網(wǎng)卡
-
網(wǎng)絡(luò)驅(qū)動程序會把網(wǎng)絡(luò)中的報文讀出來放到 ring buffer 中,這個過程使用 DMA(Direct Memory Access),不需要 CPU 參與
-
內(nèi)核從 ring buffer 中讀取報文進(jìn)行處理,執(zhí)行 IP 和 TCP/UDP 層的邏輯,最后把報文放到應(yīng)用程序的 socket buffer 中
-
應(yīng)用程序從 socket buffer 中讀取報文進(jìn)行處理
通過如上圖,可看出,在每一個環(huán)節(jié)都有存在丟包的可能性。接下來逐一分析。
網(wǎng)卡、網(wǎng)卡驅(qū)動丟包
首先可通過命令查看,是否網(wǎng)卡有丟包。
# ifconfig
#RX(receive 接收報文):packets 正確的數(shù)據(jù)包數(shù), bytes 數(shù)據(jù)量字節(jié),errors 產(chǎn)生錯誤的數(shù)據(jù)包數(shù),dropped 丟棄的數(shù)據(jù)包數(shù), overruns 速度過快丟失的數(shù)據(jù)包數(shù),frame 發(fā)生frame錯誤而丟失的數(shù)據(jù)包數(shù)。
#TX(transmit 發(fā)送報文):packets, bytes ,errors,dropped,overruns 與接收一致。carrier 發(fā)生carrier錯誤而丟失的數(shù)據(jù)包數(shù)。collisions 沖突信息包的數(shù)目。
[root@gavin ~] ifconfig ens33
ens33: flags=4163<UP ,BROADCAST,RUNNING,IULTICAST> mtu _1500
inet 192.168.76.3 netmask 255.255.255.0 broadcast 192.168.76.255
inet6 fe80::3dc2:5ebd:8970:475a prefixlen 64scopeid 0x20<link>
ether 00:0c:29:d0:ef:9e txqueuelen 1000 (Ethernet)
RX packets 3001 bytes 3447676(3.2 MiB)
Rx errors 0 dropped 0 overruns 0 frame 0
TX packets 949 bytes 62837(61.3 KiB)
TX errors dropped 0 overruns 0 carrier 0 collisions 0
#netstat
#netstat -i 打印網(wǎng)卡信息
#Iface:網(wǎng)卡名
#MTU:最大傳輸單元
#RX-OK:接收時,正確的數(shù)據(jù)包數(shù)
#RX-ERR:接收時,產(chǎn)生錯誤的數(shù)據(jù)包數(shù)
#RX-DRP:接收時,丟棄的數(shù)據(jù)包數(shù)
#RX-OVR:接收時,由于過速而丟失的數(shù)據(jù)包數(shù)
#TX-OK:發(fā)送時,正確的數(shù)據(jù)包數(shù)
#TX-ERR:發(fā)送時,產(chǎn)生錯誤的數(shù)據(jù)包數(shù)
#TX-DRP:發(fā)送時,丟棄的數(shù)據(jù)包數(shù)
#TX-OVR:發(fā)送時,由于過速而丟失的數(shù)據(jù)包數(shù)
[root@gavin ~]# netstat -i
Kernel Interface table
Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg
ens33 1500 14586 0 0 0 7943 0 0 0 BMRU
ens37 1500 400 0 0 0 64 0 0 0 BMRU
lo 65536 50 0 0 0 50 0 0 0 LRU
privbr0 1500 399 0 0 0 64 0 0 0 BMRU
virbr0 1500 0 0 0 0 0 0 0 0 BMU
#netstat -s 統(tǒng)計個協(xié)議信息
[root@gavin ~]# netstat -s
Ip:
Forwarding: 1
16333 total packets received
15 with invalid addresses
0 forwarded
0 incoming packets discarded
15955 incoming packets delivered
9039 requests sent out
139 dropped because of missing route
Icmp:
2 ICMP messages received
0 input ICMP message failed
ICMP input histogram:
destination unreachable: 2
2 ICMP messages sent
0 ICMP messages failed
ICMP output histogram:
destination unreachable: 2
IcmpMsg:
InType3: 2
OutType3: 2
Tcp:
46 active connection openings
2 passive connection openings
28 failed connection attempts
3 connection resets received
3 connections established
15484 segments received
8871 segments sent out
0 segments retransmitted
0 bad segments received
30 resets sent
Udp:
251 packets received
2 packets to unknown port received
0 packet receive errors
194 packets sent
0 receive buffer errors
0 send buffer errors
IgnoredMulti: 250
UdpLite:
TcpExt:
8 TCP sockets finished time wait in fast timer
17 delayed acks sent
Quick ack mode was activated 2 times
15228 packet headers predicted
24 acknowledgments not containing data payload received
58 predicted acknowledgments
2 connections reset due to early user close
IPReversePathFilter: 304
TCPRcvCoalesce: 36
TCPAutoCorking: 4
TCPOrigDataSent: 89
TCPDelivered: 105
IpExt:
InMcastPkts: 141
OutMcastPkts: 81
InBcastPkts: 250
InOctets: 17680346
OutOctets: 385931
InMcastOctets: 13407
OutMcastOctets: 9914
InBcastOctets: 72750
InNoECTPkts: 18122
MPTcpExt:
#ethtool
# 有錯誤說明有丟包
[root@gavin ~]# ethtool -S ens33 | grep rx_ | grep errors
rx_errors: 0
rx_length_errors: 0
rx_over_errors: 0
rx_crc_errors: 0
rx_frame_errors: 0
rx_missed_errors: 0
rx_long_length_errors: 0
rx_short_length_errors: 0
rx_align_errors: 0
rx_csum_offload_errors: 0
buffer滿導(dǎo)致的丟包
主要是ring buffer 和socket buffer滿導(dǎo)致的丟包
ring buffer:環(huán)形緩沖器,在通信程序中,經(jīng)常使用環(huán)形緩沖器作為數(shù)據(jù)結(jié)構(gòu)來存放通信中發(fā)送和接收的數(shù)據(jù)。環(huán)形緩沖區(qū)是一個先進(jìn)先出的循環(huán)緩沖區(qū),可以向通信程序提供對緩沖區(qū)的互斥訪問。
socket buffer:套接字緩存,Linux網(wǎng)絡(luò)核心數(shù)據(jù)結(jié)構(gòu)。它代表一個要發(fā)送或處理的報文,并貫穿于整個協(xié)議棧。
#查看是否因ring buffer 滿導(dǎo)致的丟包
#ethtool 或 /proc/net/dev
[root@gavin ~]# ethtool -S ens33|grep rx_fifo
[root@gavin ~]# cat /proc/net/dev
Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
lo: 46780 774 0 0 0 0 0 0 46780 774 0 0 0 0 0 0
ens33: 18909713 22098 0 0 0 0 0 0 697617 9849 0 0 0 0 0 0
ens37: 1125961 3788 0 3 0 0 0 0 8591 68 0 0 0 0 0 0
privbr0: 1069444 3768 0 0 0 0 0 635 8363 68 0 0 0 0 0 0
virbr0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
virbr0-nic: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
#查看ring buffer 設(shè)置
[root@gavin ~]# ethtool -g ens33
Ring parameters for ens33:
Pre-set maximums:
RX: 4096
RX Mini: n/a
RX Jumbo: n/a
TX: 4096
Current hardware settings:
RX: 256
RX Mini: n/a
RX Jumbo: n/a
TX: 256
#修改大小
ethtool -G ens33 rx 4096 tx 4096
# socket buffer 丟包一般由于系統(tǒng)高負(fù)載,導(dǎo)致 socket buffer占滿丟包
#可通過命令判斷
[root@gavin ~]# netstat -s | grep "buffer errors"
0 receive buffer errors
0 send buffer errors
#socket buffer 調(diào)整需要通過修改內(nèi)核參數(shù)的方式
net.ipv4.tcp_wmem
net.ipv4.tcp_rmem
net.ipv4.tcp_mem
net.core.rmem_default
net.core.rmem_max
net.core.wmem_max
服務(wù)器TCP連接、連接數(shù)限制等導(dǎo)致建連失敗丟包
此情況一般是查看TCP連接數(shù)和狀態(tài),確認(rèn)服務(wù)器最大文件打開數(shù),tcp 線程數(shù)限制等。
#統(tǒng)計TCP各連接狀態(tài)的數(shù)量
netstat -an | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
#修改limit 限制、最大文件打開數(shù),最大進(jìn)程數(shù)、最大連接數(shù),針對用戶。非針對系統(tǒng)服務(wù)的資源
/etc/security/limits.conf
# - core - limits the core file size (KB) 限制內(nèi)核文件的大小。
# - data - max data size (KB) 最大數(shù)據(jù)大小
# - fsize - maximum filesize (KB) 最大文件大小
# - memlock - max locked-in-memory address space (KB) 最大鎖定內(nèi)存地址空間
# - nofile - max number of open file descriptors 最大打開的文件數(shù)(以文件描敘符,file descripter計數(shù))
# - rss - max resident set size (KB) 最大持久設(shè)置大小
# - stack - max stack size (KB) 最大棧大小
# - cpu - max CPU time (MIN) 最多CPU占用時間,單位為MIN分鐘
# - nproc - max number of processes 進(jìn)程的最大數(shù)目
# - as - address space limit (KB) 地址空間限制
# - maxlogins - max number of logins for this user 此用戶允許登錄的最大數(shù)目
# - maxsyslogins - max number of logins on the system 系統(tǒng)最大同時在線用戶數(shù)
# - priority - the priority to run user process with 運(yùn)行用戶進(jìn)程的優(yōu)先級
# - locks - max number of file locks the user can hold 用戶可以持有的文件鎖的最大數(shù)量
# - sigpending - max number of pending signals
# - msgqueue - max memory used by POSIX message queues (bytes)
# - nice - max nice priority allowed to raise to values: [-20, 19] max nice優(yōu)先級允許提升到值
#設(shè)置內(nèi)核最大的文件句柄數(shù)
/proc/sys/fs/file-max
#設(shè)置進(jìn)程最大的文件句柄數(shù),不能超過1
/proc/sys/fs/nr_open
時間戳和TCP連接復(fù)用配置導(dǎo)致的連接丟包
主要是 tcp_tw_recycle,tcp_timestamps造成的影響。
-
net.ipv4.tcp_tw_recycle:用于快速回收處于TIME_WAIT 狀態(tài)的socket 連接;(通常在開啟net.ipv4.tcp_timestamps 時有效,1代表開啟,0代表關(guān)閉)
-
net.ipv4.tcp_timestamps:啟用時間戳,默認(rèn)缺省值為1,開啟;該值必須為單調(diào)遞增,否則接受到的包可能會被丟掉。
TCP協(xié)議中有一種機(jī)制,緩存了每個主機(jī)(即ip)過來的連接最新的timestamp值。這個緩存的值可以用于PAWS(Protect Against Wrapped Sequence numbers,是一個簡單的防止重復(fù)報文的機(jī)制)中,來丟棄當(dāng)前連接中可能的舊的重復(fù)報文。在tcp_tw_recycle/tcp_timestamps都開啟的條件下,60s內(nèi)同一源ip主機(jī)的tcp 鏈接請求中的timestamp必須是遞增的。文章來源:http://www.zghlxwxcb.cn/news/detail-610726.html
這兩個值開啟與否需要根據(jù)實(shí)際情況進(jìn)行判斷,我們在生產(chǎn)中曾經(jīng)遇到過未開啟而導(dǎo)致三次握手中最后一次握手丟包的情況,也存在開啟后,導(dǎo)致第一次握手無應(yīng)答的情況。文章來源地址http://www.zghlxwxcb.cn/news/detail-610726.html
到了這里,關(guān)于Linux丟包問題排查思路的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!