TCP 重傳突然飆升時(shí),如何用抓包把根因釘死

很多團(tuán)隊(duì)在監(jiān)控里看到 **TCP Retransmission**、**RTT 抖動(dòng)**、**吞吐下滑** 時(shí),第一反應(yīng)是:


- 是不是帶寬不夠了?

- 是不是服務(wù)器扛不住了?

- 是不是客戶端網(wǎng)絡(luò)太差?


遺憾的是,現(xiàn)實(shí)里的網(wǎng)絡(luò)故障排查,最怕的就是這種“看起來(lái)每個(gè)人都有點(diǎn)像嫌疑人”的場(chǎng)景。只盯著監(jiān)控曲線,很容易把問(wèn)題歸因到錯(cuò)誤方向;只看單點(diǎn)日志,又經(jīng)常會(huì)把鏈路問(wèn)題誤判成應(yīng)用問(wèn)題。


這篇文章給你一套更實(shí)戰(zhàn)的排查路徑:當(dāng) TCP 重傳突然飆升時(shí),如何結(jié)合指標(biāo)、抓包和鏈路行為,把根因從“猜測(cè)”變成“證據(jù)”。


## 一、先別急著抓包,先判斷這是“局部問(wèn)題”還是“鏈路級(jí)問(wèn)題”


看到重傳升高,不要一上來(lái)就沉迷 Wireshark。先回答 3 個(gè)問(wèn)題:


### 1)影響范圍有多大?


優(yōu)先看:


- 是否只有某個(gè)地域 / 機(jī)房 / AZ 出現(xiàn)異常

- 是否只有某個(gè)運(yùn)營(yíng)商出口受影響

- 是否只有特定業(yè)務(wù)接口變慢

- 是否只在高峰時(shí)段出現(xiàn)


如果問(wèn)題只集中在少數(shù)源 IP、某個(gè)地域或某個(gè)出口,通常更像:


- 局部鏈路抖動(dòng)

- 運(yùn)營(yíng)商路徑問(wèn)題

- NAT / SLB / 防火墻中間設(shè)備異常

- 某個(gè)機(jī)房交換網(wǎng)絡(luò)微突發(fā)


如果是全局性重傳升高,則更要懷疑:


- 服務(wù)端接收能力下降

- 全局流量結(jié)構(gòu)變化

- 發(fā)布后應(yīng)用層響應(yīng)模式變化

- 核心網(wǎng)絡(luò)設(shè)備擁塞或隊(duì)列配置異常


### 2)重傳和延遲、吞吐是不是一起變化?


重點(diǎn)看幾個(gè)組合關(guān)系:


- **重傳升高 + RTT 升高 + 吞吐下降**:典型鏈路質(zhì)量劣化 / 擁塞

- **重傳升高 + RTT 基本穩(wěn)定 + 吞吐下降**:更像中間盒丟包、策略限速、接收端處理不及時(shí)

- **零窗口 / Window Full 增加**:優(yōu)先懷疑接收端消費(fèi)不動(dòng)

- **Dup ACK 明顯增加**:說(shuō)明接收端已感知亂序或丟段


### 3)問(wèn)題發(fā)生時(shí)有沒(méi)有變更?


網(wǎng)絡(luò)排查里,很多“玄學(xué)故障”最后都死在變更記錄上:


- 應(yīng)用是否剛發(fā)布

- 容器 / 節(jié)點(diǎn)是否遷移

- 負(fù)載均衡策略是否調(diào)整

- 安全設(shè)備策略是否更新

- 帶寬 / QoS / 路由是否發(fā)生切換


如果你跳過(guò)這一層,后面的抓包經(jīng)常會(huì)越抓越像推理小說(shuō)。


## 二、抓包的目標(biāo)不是“抓到很多包”,而是抓到能定責(zé)的包


真正有效的抓包,核心不是包量,而是位置。


建議至少準(zhǔn)備兩個(gè)觀察點(diǎn):


- **服務(wù)端網(wǎng)卡處抓包**

- **客戶端側(cè)或出口處抓包**


如果能拿到雙端包,就能回答一個(gè)關(guān)鍵問(wèn)題:


> 這個(gè)包到底是沒(méi)發(fā)出去、路上丟了,還是對(duì)端收到了但沒(méi)及時(shí)確認(rèn)?


### 常見(jiàn)抓包策略


#### 服務(wù)端抓包


```bash

tcpdump -i eth0 host 10.10.20.8 and port 443 -w server.pcap

```


#### 按時(shí)間窗口抓取異常流


```bash

tcpdump -i eth0 tcp and port 443 -G 60 -W 5 -w trace-%Y%m%d%H%M%S.pcap

```


#### 只抓某個(gè)五元組附近流量


```bash

tcpdump -i eth0 'tcp and host 10.10.20.8 and host 10.10.30.9 and port 443' -w flow.pcap

```


抓包時(shí)務(wù)必記?。?/p>


- 時(shí)間同步要準(zhǔn)確,NTP 漂移會(huì)讓雙端對(duì)比變得很痛苦

- 盡量縮小抓取范圍,否則你會(huì)在海量噪聲里淹死

- 如果是短時(shí)突發(fā),優(yōu)先用循環(huán)抓包保留現(xiàn)場(chǎng)


## 三、看到重傳,不等于先判定“網(wǎng)絡(luò)丟包”


很多人一看到 Wireshark 里的 **[TCP Retransmission]**,就默認(rèn)鏈路壞了。其實(shí)這是非常常見(jiàn)的誤判。


重傳只是結(jié)果,不是原因。它至少可能來(lái)自四類問(wèn)題:


### 1)真實(shí)鏈路丟包


這是大家最熟悉的一種。


典型信號(hào):


- 大量 Dup ACK

- SACK 明確標(biāo)記缺失段

- 某一跳或某一類路徑上持續(xù)出現(xiàn)間歇丟包

- 重傳位置比較穩(wěn)定,常集中于某些時(shí)段或某些路徑


### 2)亂序被誤看成丟包


在 ECMP、多路徑回程、鏈路聚合或云網(wǎng)絡(luò)復(fù)雜轉(zhuǎn)發(fā)場(chǎng)景下,報(bào)文亂序并不少見(jiàn)。


表現(xiàn)通常是:


- 先看到 Dup ACK

- 隨后缺失段很快補(bǔ)到

- 重傳并不一定持續(xù)惡化

- RTT 不一定明顯變高


如果你只看單端抓包,極容易把亂序當(dāng)丟包。


### 3)接收端處理不過(guò)來(lái)


這類問(wèn)題在高并發(fā)服務(wù)、日志寫(xiě)盤(pán)壓力大、應(yīng)用線程阻塞時(shí)很常見(jiàn)。


典型信號(hào):


- TCP Window 很小,甚至出現(xiàn) **Zero Window**

- 應(yīng)用層響應(yīng)延遲顯著上升

- CPU 不一定滿,但軟中斷、隊(duì)列堆積、磁盤(pán)等待可能異常

- 服務(wù)端沒(méi)丟包,但 ACK 返回慢


這時(shí)你會(huì)看到發(fā)送端不斷認(rèn)為“包是不是沒(méi)到”,于是觸發(fā)重傳;實(shí)際上問(wèn)題根子在接收端消費(fèi)速度。


### 4)中間設(shè)備改寫(xiě)或吞包


這類鍋特別難看出來(lái),因?yàn)殡p方主機(jī)都可能“以為自己沒(méi)問(wèn)題”。


例如:


- 防火墻會(huì)話表抖動(dòng)

- NAT 設(shè)備老化或端口耗盡

- 負(fù)載均衡器健康狀態(tài)震蕩

- 某些安全設(shè)備對(duì)大包 / 分片 / 特征流做了特殊處理


如果只有單點(diǎn)抓包,你通常只能看到“包似乎消失了”;但雙端對(duì)比會(huì)暴露出它到底消失在哪一段。


## 四、一個(gè)高效的分析框架:按“誰(shuí)先失憶”來(lái)定責(zé)


做 TCP 重傳分析,我建議用一個(gè)非常接地氣的思路:


> 先找出是誰(shuí)最先“不記得”這個(gè)包了。


具體可以按下面步驟走。


### Step 1:鎖定一個(gè)異常連接


不要一上來(lái)分析全量流量。先挑一個(gè):


- 慢請(qǐng)求對(duì)應(yīng)的連接

- 重傳次數(shù)明顯高的連接

- 某個(gè)關(guān)鍵客戶或大流量連接


先把樣本做扎實(shí),比鋪天蓋地看統(tǒng)計(jì)圖更有用。


### Step 2:看序列號(hào)和 ACK 號(hào)的推進(jìn)是否連續(xù)


重點(diǎn)看:


- 某個(gè) Seq 是否發(fā)出后長(zhǎng)時(shí)間沒(méi)被 ACK

- ACK 是否卡在某個(gè)位置不前進(jìn)

- 是否連續(xù)出現(xiàn) Dup ACK

- SACK 指向的缺口是不是穩(wěn)定重復(fù)


如果 ACK 長(zhǎng)時(shí)間卡住,而發(fā)送端多次重傳同一段,說(shuō)明問(wèn)題已經(jīng)可以被定位到“這一段數(shù)據(jù)沒(méi)有被正常確認(rèn)”。


### Step 3:對(duì)比雙端抓包


這里是定責(zé)關(guān)鍵。


#### 場(chǎng)景 A:服務(wù)端發(fā)出了包,客戶端沒(méi)收到


更像:


- 中間鏈路丟包

- 網(wǎng)絡(luò)設(shè)備擁塞

- 中間盒丟棄


#### 場(chǎng)景 B:客戶端收到了包,但服務(wù)端沒(méi)收到 ACK


更像:


- ACK 回程路徑異常

- 回程鏈路丟包

- 回程方向策略設(shè)備處理異常


#### 場(chǎng)景 C:客戶端其實(shí)很晚才 ACK


更像:


- 客戶端處理?xiàng)7泵?/p>

- 接收窗口受限

- 應(yīng)用消費(fèi)慢


### Step 4:把抓包結(jié)論和主機(jī)指標(biāo)對(duì)齊


這一步經(jīng)常被忽略,但它恰恰決定結(jié)論是不是站得住。


你需要對(duì)齊:


- 網(wǎng)卡丟包 / error / drop 計(jì)數(shù)

- CPU softirq

- socket backlog

- 重傳統(tǒng)計(jì)

- 應(yīng)用線程池飽和度

- 磁盤(pán) IO wait

- 負(fù)載均衡 / 防火墻會(huì)話數(shù)


如果抓包說(shuō)像接收端處理慢,而主機(jī)上剛好出現(xiàn) backlog 堆積、軟中斷拉高、應(yīng)用線程耗盡,那證據(jù)鏈就閉環(huán)了。


## 五、一個(gè)真實(shí)排查思路:?jiǎn)栴}不在公網(wǎng),而在接收端“假性正?!?/p>


某次排查里,業(yè)務(wù)方反饋“公網(wǎng)質(zhì)量差,接口偶發(fā)超時(shí)”。監(jiān)控上看,現(xiàn)象也很像:


- TCP 重傳升高

- 接口 P99 飆升

- 峰值時(shí)吞吐下降


第一眼很容易把鍋甩給公網(wǎng)運(yùn)營(yíng)商。


但雙端抓包后發(fā)現(xiàn):


- 服務(wù)端數(shù)據(jù)包其實(shí)穩(wěn)定發(fā)出

- 客戶端也收到了大部分?jǐn)?shù)據(jù)

- 真正異常的是 ACK 返回不穩(wěn)定

- 同時(shí)客戶端偶發(fā) Zero Window


繼續(xù)查客戶端節(jié)點(diǎn),發(fā)現(xiàn)不是鏈路問(wèn)題,而是某個(gè)日志采集進(jìn)程異常占用 IO,導(dǎo)致應(yīng)用線程處理變慢,ACK 回包被拖后。發(fā)送端因此連續(xù)誤判為丟包并重傳。


這類問(wèn)題的危險(xiǎn)在于:


- 從監(jiān)控看像網(wǎng)絡(luò)故障

- 從應(yīng)用日志看像偶發(fā)超時(shí)

- 從用戶體感看像公網(wǎng)不穩(wěn)定


但真正的根因,其實(shí)是接收端資源爭(zhēng)搶。


如果沒(méi)有抓包與系統(tǒng)指標(biāo)交叉驗(yàn)證,這種問(wèn)題非常容易錯(cuò)治。


## 六、排查 TCP 重傳時(shí),最容易踩的 5 個(gè)坑


### 坑 1:只看單端抓包就下結(jié)論


單端抓包只能說(shuō)明“我這邊看到了什么”,不能完整說(shuō)明“鏈路上發(fā)生了什么”。


### 坑 2:把 Wireshark 的標(biāo)注當(dāng)最終事實(shí)


`TCP Retransmission`、`Out-of-Order`、`Dup ACK` 都只是分析器根據(jù)上下文給出的解釋,不是法院判決書(shū)。


### 坑 3:只盯帶寬,不看隊(duì)列與窗口


很多性能問(wèn)題不是“管道太細(xì)”,而是“接收端吞不動(dòng)”或“中間隊(duì)列抖了”。


### 坑 4:忽略回程路徑


去程正常,不代表回程正常。很多 ACK 異常都藏在回程。


### 坑 5:抓包時(shí)間和系統(tǒng)指標(biāo)對(duì)不上


如果抓包時(shí)間、應(yīng)用日志時(shí)間、監(jiān)控時(shí)間沒(méi)對(duì)齊,最后只會(huì)得到一堆看似合理但互相打架的結(jié)論。


## 七、給團(tuán)隊(duì)一套能復(fù)用的處置清單


如果你經(jīng)常處理網(wǎng)絡(luò)慢、接口超時(shí)、重傳飆升這類問(wèn)題,建議把下面這份清單固化成 SOP:


1. 先定影響范圍:地域、運(yùn)營(yíng)商、業(yè)務(wù)、時(shí)段

2. 再看組合指標(biāo):重傳、RTT、吞吐、窗口、Dup ACK

3. 核對(duì)最近變更:應(yīng)用、網(wǎng)絡(luò)、LB、安全策略

4. 鎖定單條異常連接做樣本

5. 雙端抓包,不要只抓一邊

6. 對(duì)齊主機(jī)與中間設(shè)備指標(biāo)

7. 最后再給根因歸類:鏈路丟包 / 亂序 / 接收端處理慢 / 中間盒異常


這套流程看起來(lái)不花哨,但非常有效。網(wǎng)絡(luò)排查最值錢的,不是神秘經(jīng)驗(yàn),而是能持續(xù)復(fù)用的證據(jù)鏈方法。


## 八、結(jié)語(yǔ):別把“重傳”當(dāng)答案,把它當(dāng)入口


TCP 重傳從來(lái)不是根因本身,它只是鏈路里有人開(kāi)始“說(shuō)不清楚話了”的第一個(gè)報(bào)警信號(hào)。


真正高水平的排查,不是看到重傳就開(kāi)始甩鍋,而是能快速回答:


- 包到底發(fā)沒(méi)發(fā)出去?

- 對(duì)端到底收沒(méi)收到?

- ACK 為什么沒(méi)按預(yù)期回來(lái)?

- 是網(wǎng)絡(luò)真丟了,還是系統(tǒng)處理慢了,或者中間盒搞事?


當(dāng)你把這些問(wèn)題用抓包和指標(biāo)一層層釘死,網(wǎng)絡(luò)故障就不再是“靠感覺(jué)”,而是“靠證據(jù)”。


如果你在做網(wǎng)絡(luò)流量分析、TCP 異常定位、鏈路性能優(yōu)化,AnaTraf 可以幫助你更快關(guān)聯(lián)流量、時(shí)延、重傳與業(yè)務(wù)影響,減少靠人工反復(fù)翻包的時(shí)間成本。更多信息可見(jiàn):www.anatraf.com

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容