小村軟體有限公司
第 7 章

綜合演習 — 以封包的視角解讀 TCP 的行為

把模擬實務故障調查的 8 個案例,依照症狀 → 是哪項承諾的話題 → 該看的數字的順序切分。卡住了就回到對應章節複習。

收尾的 8 題 — 把症狀翻譯成「哪項承諾的話題」

最終章是沒有講解的綜合演習。對 8 個模擬實務故障調查的案例,橫跨全部 6 章的知識來作答。迷惘時,請回到本課程的口訣 — 現在快被打破的,是送達的承諾?順序?還是步調的配合?然後把症狀翻譯成數字:是 RST 還是沉默、重複 ACK 的號碼指向哪裡、取 min 的是哪扇窗。

卡住的話回去的章節
IP 的性質、TCP/UDP 的分工、四元組第 1 章
交握、TIME_WAIT、RST 與 FIN第 2 章
seq/ack 的計算、RTO、重複 ACK 與快速重傳第 3 章
視窗通告、in-flight、視窗 ÷ RTT、零視窗第 4 章
cwnd、慢啟動、對遺失的 2 段反應第 5 章
位元組串流、framing第 6 章
從連不上、很慢、資料怪怪的這 3 個系統的症狀出發,追溯到該看的封包證據與對應章節的 TCP 故障切分地圖

本課程做出來的切分地圖。依照症狀 → 封包的證據 → 哪項承諾的話題的順序往下走,就能從亂槍打鳥的重啟畢業。

案例 7-1 — 連不上、斷掉

第 1〜2 章的範圍。請翻譯成「是立即的拒絕,還是沉默」「是 FIN 還是 RST」。

Q1. 案例:無法連上新部署的 API 伺服器。從用戶端 A 立刻收到 Connection refused,從用戶端 B 則等了 30 秒後連線逾時。對各自狀況的解讀,正確的是哪一個?

Q2. 案例:一台經由負載平衡器向後端建立大量短連線的代理伺服器,用 netstat 一看,TIME_WAIT 狀態的連線排了數萬條。對這個狀況的理解,正確的是哪一個?

Q3. 案例:一條連往資料庫的常駐連線,在深夜批次處理睽違數小時送出查詢的瞬間被 RST 切斷。從連線建立到閒置為止沒有任何異常。最可疑的原因是哪一個?

案例 7-2 — 很慢、堵住

第 3〜5 章的範圍。請翻譯成「重傳是哪一型」「取 min 的是哪扇窗」。

Q4. 案例:接到傳輸很慢的申告後查看封包擷取,發現大量排列著相同 ack 號碼的 ACK。接收端已連續收到位元組 8000 為止,只有 8001〜9000 的區段遺失,後續(9001 以後)持續送達。排列著的重複 ACK 的 ack 號碼是多少?

Q5. 案例:用頻寬 1 Gbps(= 125 MB/秒)的專線向海外據點(RTT 50 毫秒)傳檔案,卻只有 4 MB/秒。調查後發現接收端的設定把視窗固定在 200 KB(200,000 位元組)。這個設定下的吞吐量上限是多少 MB/秒?(1 MB = 100 萬位元組)

MB/秒

Q6. 案例:往記錄收集伺服器的傳輸週期性地停住。封包擷取中排列著來自接收端的視窗 0 通告,與來自送信端反覆的小型探詢封包。接下來該調查的地方是哪裡?

案例 7-3 — 資料怪怪的

第 6 章的範圍。請找出「在 TCP 的承諾之外,假設了什麼」。

Q7. 案例:一個 parse 從 socket 收到的 JSON 的服務,只在正式環境每月數次發生 parse 錯誤。查看錯誤時的資料,發現 JSON 中途截斷的,與 2 個 JSON 相連的兩種都有。正確的處置是哪一個?

Q8. 案例:傳輸完全沉默數秒後,從同一區段的重傳重新開始,這個模式不斷重複。幾乎看不到重複 ACK。這段期間送信端的壅塞視窗(cwnd)發生的事情是哪一個?

課程的結尾 — 用數字的心情去讀

辛苦了。這門課程需要死背的項目其實非常少。取而代之希望你帶走的,是在封包擷取與故障記錄的任何場面都通用的讀法。

  • 一定送達(沒送到就會發現) — ack 是下一個想要的位元組。重複 ACK 是指向缺漏開頭的箭頭。重傳有輕症型(重複 ACK)與重症型(RTO)
  • 按照順序 — 累積確認與接收緩衝區修正亂序。但切點在承諾之外 — 邊界由應用程式以 framing 建立
  • 配合對方與網路 — 上限是 min(rwnd, cwnd) ÷ RTT。零視窗是對方的堵塞,cwnd 的斷崖是路徑的壅塞

如果原本停在「總之逾時了,先重啟再說」的調查,已經變成能指出哪項承諾、在哪個封包、如何快被打破的調查,本課程的目標就達成了。下次打開封包擷取時,seq、ack 與 win 的數列,應該就能像文章一樣讀懂了。