丟包是什麼意思?丟包率怎麼算、怎麼測與常見原因
丟包是指資料包從傳送端出發後沒能到達接收端,英文叫 packet loss;丟包率是丟失的包占傳送總數的百分比。1% 的丟包率聽上去很小,但它會讓 TCP 反覆重傳、降速,讓語音和遊戲斷斷續續,對體驗的影響遠比這個數字大。
丟包是什麼意思?資料在網路上被切成一個個“包”來傳輸,一個包從傳送端出發,要經過網路卡、交換器、路由器,最後到達接收端;途中任何一處把它丟棄或損壞,接收端就收不到它,這就是丟包,英文是 packet loss。丟包率是丟失的包占發出總數的百分比,英文是 packet loss rate,計算公式是:丟包率 =(傳送數 − 接收數)÷ 傳送數 × 100%。網路裝置本來就不保證每個包都送達:佇列滿了要丟,校驗出錯要丟,超過限速要丟,被安全策略攔下也要丟。少量丟包由 TCP 重傳補回來,代價是變慢;丟包多了,網頁載入卡頓、下載速度上不去、遊戲和語音斷斷續續。
丟包率怎麼算:公式和三種統計口徑
公式本身很簡單。用 ping 向一台伺服器發 500 個包,收到 493 個回覆:
丟包率 = (500 − 493) ÷ 500 × 100% = 1.4%
麻煩在於,“丟包率”在不同地方統計的東西並不一樣。維運排障時常見三種口徑:
| 口徑 | 在哪裡看 | 怎麼算 | 說明什麼 |
|---|---|---|---|
| ping、mtr 的丟包率 | 發起測試的客戶端 | (傳送 − 收到回覆)÷ 傳送 | 端到端的一來一回是否完整,去程、回程任一方向丟了都算丟 |
| 介面丟棄率 | 伺服器網路卡、交換器連接埠 | 丟棄包數 ÷ 收(或發)總包數 | 這一台裝置、這一個連接埠自己有沒有丟 |
| TCP 重傳率 | 伺服器 | 重傳段數 ÷ 傳送段數 | 業務連線實際遇到的丟包,最接近使用者的感受 |
介面口徑在 Linux 上這樣看:
ip -s link show eth0
RX: bytes packets errors dropped missed mcast
9876543210 12500000 0 2500 0 120
TX: bytes packets errors dropped carrier collsns
8765432100 11000000 0 0 0 0
接收方向丟棄了 2,500 個包,接收丟棄率 = 2,500 ÷ 12,500,000 = 0.02%。這些計數從開機(或驅動載入)起累計,要隔一段時間看兩次,用差值算才是當前的情況。各版本 iproute2 的列名略有不同,含義一致。
TCP 重傳率用核心計數器算:
nstat -az TcpOutSegs TcpRetransSegs
# TcpOutSegs 2000000
# TcpRetransSegs 6000
重傳率 = 6,000 ÷ 2,000,000 = 0.3%。同樣是累計值,按兩次取樣的差值計算更準確。
三個數字不能直接互相比較:ping 的丟包包含兩個方向、只代表 ICMP;介面計數只代表這一台裝置;TCP 重傳裡還包含超時誤判造成的“多餘重傳”。判斷丟沒丟、丟在哪,通常要把它們放在一起看。
丟包的英文和相關術語對照
查資料、看裝置輸出時,下面這些詞指的都是丟包或與它相關的現象:
| 中文 | 英文 | 常出現在 |
|---|---|---|
| 丟包 | packet loss | 通用說法 |
| 丟包率 | packet loss rate、loss rate;ping 統計裡寫作 % packet loss 或 % loss | ping、監控系統、SLA 條款 |
| 請求超時 | Request timed out | Windows ping 中某個包沒收到回覆 |
| 丟失 | Lost | Windows ping 的統計行 |
| 丟棄 | drop、discard | 網路卡、交換器計數,多為佇列滿或策略主動丟棄 |
| 錯誤包 | error、CRC error、FCS error | 幀校驗失敗,多為網線、光模組等物理層問題 |
| 重傳 | retransmission | TCP 發現丟包後重新傳送 |
| 往返時延 | latency、RTT | ping 每一行的 time= |
| 抖動 | jitter | 延遲的波動,mtr 的 StDev 列可以近似反映 |
用 ping 看丟包:Windows 和 Linux 的輸出怎麼讀
Windows 預設只發 4 個包,用 -n 指定數量;Linux 預設一直髮,用 -c 指定數量:
ping -n 100 203.0.113.10
請求超時。
來自 203.0.113.10 的回覆: 位元組=32 時間=36ms TTL=52
203.0.113.10 的 Ping 統計資訊:
資料包: 已傳送 = 100,已接收 = 96,丟失 = 4 (4% 丟失),
往返行程的估計時間(以毫秒為單位):
最短 = 33ms,最長 = 118ms,平均 = 37ms
ping -c 100 203.0.113.10
--- 203.0.113.10 ping statistics ---
100 packets transmitted, 96 received, 4% packet loss, time 99153ms
rtt min/avg/max/mdev = 33.118/37.402/118.247/9.611 ms
讀結果時注意五點:
- 看超時的分佈,不只看總數。連續十幾個“請求超時”後恢復,是一次短暫中斷,常見於鏈路切換、路由收斂、連接埠閃斷;零星分散的超時,是持續性的小比例丟包,常見於擁塞或誤碼。兩種情況的丟包率可能一樣,原因完全不同。
- 樣本量決定精度。100 個包丟 1 個就是 1%,這個測試分辨不出 0.1% 級別的丟包;要看千分之幾的丟包,至少發上千個包,並且在出問題的時段測。
- Windows 會把“無法存取目標主機”算作已接收。本機(同網段內 ARP 解析不到目標時)或沿途的路由器返回“目標不可達”,Windows 也把這次回覆計入已接收:
來自 192.168.1.1 的回覆: 無法存取目標主機。
資料包: 已傳送 = 4,已接收 = 4,丟失 = 0 (0% 丟失),
統計顯示 0% 丟失,實際上一個包都沒到達目標。所以要看回復來自哪個位址,回覆位址不是目標 IP,就不算通。
- ping 分不出丟在哪個方向。請求在去程丟了,和回覆在回程丟了,結果一樣都是“超時”。要區分方向,需要在兩端分別測,或者用 iperf3 這類工具在一端發、另一端統計。
- 換大包再測一次。預設的 32 位元組(Windows)或 56 位元組(Linux)小包正常,不代表大包也正常。Windows 用
ping -n 100 -l 1400 203.0.113.10,Linux 用ping -c 100 -s 1400 203.0.113.10。大包丟得明顯更多,要懷疑 MTU 不匹配,或者鏈路有誤碼,因為包越長,碰上位元錯誤的機率越高。
用 mtr 看丟包丟在哪一段
ping 只給出終點的結果,mtr 對路徑上每一跳持續探測,每一跳的 Loss% 就是“這一跳沒有回應的探測包比例”。下面這份報告的特點是隻有最後一跳丟包:
mtr -rwn -c 200 203.0.113.10
HOST: office-gw Loss% Snt Last Avg Best Wrst StDev
1.|-- 192.168.10.1 0.0% 200 0.6 0.7 0.4 2.1 0.2
2.|-- 100.64.12.1 0.0% 200 3.2 3.5 2.8 9.7 0.8
3.|-- 198.51.100.33 0.0% 200 5.9 6.3 5.1 14.2 1.3
4.|-- 198.51.100.90 0.0% 200 28.4 28.9 27.6 35.0 1.1
5.|-- 203.0.113.1 0.0% 200 30.1 30.6 29.8 38.3 1.2
6.|-- 203.0.113.10 6.5% 200 31.0 31.4 30.2 40.1 1.4
到第 5 跳(機房閘道器)為止都不丟,只有伺服器本身丟了 6.5%。問題範圍被縮小到最後一段:伺服器網路卡、伺服器所接的交換器連接埠和網線,或者伺服器自己對 ICMP 做了限速。再用 TCP 方式(mtr -T -P 連接埠)複測一次:TCP 也丟,就查網路卡和連接埠;TCP 不丟,多半是伺服器對 ICMP 做了限速,對 TCP 業務沒有影響。
不同的丟包形態,對應不同的含義:
| 丟包形態 | 含義 |
|---|---|
| 中間某一跳丟,後面各跳恢復為 0 | 那台路由器對發給它自己的探測包限速,不是業務丟包 |
| 從某一跳開始,後面每一跳都丟 | 真丟包,問題在這一跳或它前面那段鏈路 |
| 只有最後一跳丟 | 目標本身或它的接入連接埠,或者目標對 ICMP 限速 |
| 丟包出現的同時,延遲從某一跳起整體抬高 | 擁塞的典型表現:佇列先變長、延遲升高,佇列滿了才開始丟包 |
還要記住 mtr 只能測出去的路徑。回程可能走另一條線路,去程看不出問題時,要從伺服器向你這一端再測一次。
丟包的常見原因
| 原因 | 典型特徵 | 怎麼確認 |
|---|---|---|
| 線路或出口擁塞 | 晚高峰出現、凌晨消失,丟包時延遲同步抬高 | 鏈路利用率曲線是否貼頂;mtr 中丟包從擁塞段開始一直延續到終點 |
| 連接埠或套餐限速 | 流量低時不丟,超過某個速率就丟;下載速度貼著一個固定值 | 交換器連接埠限速配置、服務商的頻寬套餐 |
| 網線、光模組故障或光衰 | 全天按大致固定的比例丟,和流量大小關係不大;大包更明顯 | 交換器連接埠的 CRC、錯誤計數持續增長;光模組收光功率低於廠商規定的下限 |
| 速率或雙工協商異常 | 一端全雙工、一端半雙工,流量一大就丟 | ethtool eth0 看 Speed 與 Duplex,與交換器連接埠狀態對照 |
| 裝置 CPU 過高 | ping 裝置本身丟包;純硬體轉發的裝置轉發通常不受影響,軟路由、軟體防火牆 CPU 打滿時轉發也會丟 | 對比 ping 裝置本身和 ping 裝置後面的主機;檢視裝置 CPU 利用率 |
| ICMP 限速被誤判 | 只有 ping、mtr 顯示丟包,TCP 業務正常 | 用 TCP 方式複測,或看業務的 TCP 重傳率 |
| 伺服器來不及接收 | 流量大時伺服器網路卡的丟棄計數增長,交換器連接埠不丟 | ip -s link、ethtool -S eth0 中的 drop、miss、fifo 類計數;dmesg 中是否有 nf_conntrack: table full, dropping packet |
| 遭受攻擊或被清洗 | 突發,伴隨入方向流量暴漲 | 流量圖、服務商的攻擊和清洗記錄 |
| MTU 不匹配 | 小包正常,大包丟;網頁能開啟,大檔案下載或 HTTPS 握手卡住 | Linux 用 ping -M do -s 1472 目標,Windows 用 ping -f -l 1472 目標,逐步減小包長找出能透過的上限 |
擁塞和限速是“裝置主動丟”,物理層故障是“包壞了被丟”,ICMP 限速則是“看起來丟了、其實沒丟”。先分清是哪一類,再去找對應的裝置。
丟包和延遲有什麼區別
| 對比項 | 丟包 | 延遲 |
|---|---|---|
| 定義 | 包沒有到達 | 包到達了,花了多長時間 |
| 單位 | 百分比 | 毫秒(ms) |
| 主要成因 | 擁塞、限速、物理故障、策略丟棄 | 物理距離、路由繞行、排隊 |
| 怎麼看 | ping 統計行、mtr 的 Loss%、介面計數、TCP 重傳率 | ping 的 time=、mtr 的 Avg 與 StDev |
| 使用者的感受 | 時好時壞、斷續、偶爾卡住幾秒、下載速度上不去 | 每次操作都慢半拍,但穩定 |
兩者又是連在一起的。對 TCP 業務來說,丟包最終會以“延遲”的形式出現,因為丟掉的資料要等發現之後重發:
- 收到連續 3 個重複確認觸發快速重傳,大約多花一個往返時間;
- 等不到確認只能靠超時重傳,Linux 上重傳超時最短也是 200 毫秒;
- 建立連線的 SYN 包丟了,按 RFC 6298 的建議要等 1 秒才重發,使用者看到的是“偶爾點一下要卡一秒”;
- DNS 查詢走 UDP,查詢包丟了,Linux 上 glibc 解析器預設(
/etc/resolv.conf的 timeout)要等 5 秒才重試,表現為“偶爾開啟網頁要等好幾秒”。
所以看到偶發的 1 秒、5 秒停頓,先查丟包,而不是延遲。
丟包還會直接壓低單個 TCP 連線的速度,因為 Reno、CUBIC 這類基於丟包的擁塞控制把丟包當成擁塞訊號而降速。按常用的 Mathis 公式估算(吞吐上限 ≈ MSS ÷ RTT × 1.22 ÷ √丟包率),在 50 ms 往返時延、MSS 1,460 位元組的鏈路上,丟包率 0.01% 時單連線上限約 28.5 Mbps,0.1% 時約 9 Mbps,1% 時只剩約 2.85 Mbps。丟包率從 0.01% 升到 1%,單連線的速度上限降到原來的十分之一,所以 1% 的丟包損失的遠不止 1% 的速度。
UDP 業務沒有重傳。語音、視訊會議、即時遊戲丟一個包就少一幀畫面或一段聲音,程式只能靠插值、補償來掩蓋,丟包多了就會出現卡頓、畫面跳躍、人物瞬移。
在管理系統裡怎麼落地
在 IDC 機房裡,丟包最常見的兩個源頭是連接埠或出口擁塞,以及接入鏈路的物理故障。擁塞常由個別伺服器引起:某台機器被攻擊或濫用,把同一上聯的其他客戶擠到丟包。頻寬自動限速 在它最近幾分鐘的平均頻寬超過閾值時,自動把它的交換器連接埠限到設定速率,流量回落並持續穩定後再恢復原速率;按平均值判斷,偶發的尖峰不會誤觸發。物理故障要從連接埠入手:Toplink DCIM 的伺服器列表裡能直接看到每台機器接在哪台交換器的哪個連接埠,在 交換器管理 裡開啟瀏覽器終端,執行 display interface 或 show interface 檢視 CRC 和錯誤計數是否在增長,整個排障會話會被錄影並記錄命令日誌,事後可以回看當時看到的計數。
常見問題
連 Wi-Fi 時丟包,怎麼判斷是無線的問題還是寬頻的問題?
先 ping 自己的路由器(閘道器位址)。到路由器就有丟包,問題在無線這一段,常見是訊號弱、同頻干擾或離路由器太遠,換有線或換 5 GHz 頻段再測;到路由器不丟、到外網才丟,問題在寬頻線路或更遠的網路。
丟包率和誤位元速率是一回事嗎?
不是。誤位元速率(BER)是物理層傳輸中位元出錯的比例,丟包率以整個包為單位統計。誤碼會讓幀校驗失敗、整幀被丟棄,所以誤碼升高會表現為丟包;但擁塞、限速、策略攔截造成的丟包與誤碼無關。
遊戲裡顯示的丟包和 ping 測出來的為什麼不一樣?
遊戲統計的是它自己的資料包,多為 UDP,包的大小、頻率和連接埠都和 ping 的 ICMP 不同,中間裝置對兩者的限速和優先順序也可能不同。以遊戲內的統計為準,再用 mtr 找出丟在哪一段。