한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

遊戲 Lag 白皮書 › TCP 重傳的根本原因

延遲飆升造成的不必要重傳 Spurious RTO from delay spikes

原因 ID rt-spurious-delay · 主要負責 外部(外部) · 協同 基礎設施團隊(伺服器基礎設施), 遊戲開發團隊(用戶端開發)

在含圖解與實驗的完整版中開啟卡片 →

封包沒有消失,只是短暫地很晚才到;但這段延遲比 RTO 長時,傳送端就會判斷為遺失而重傳。

為什麼 bufferbloat、Wi-Fi 省電、行動網路無線狀態切換、虛擬機器暫停,造成瞬間延遲達數百 ms → 於是 RTO 先到期而重傳,原本的封包也隨即抵達(接收端收到重複的封包) → 畫面上 定格與快轉是延遲飆升本身造成的。不必要的重傳幾乎不會拉長定格,只會推高重傳指標,因而被誤認為遺失

症狀
定格, 快轉, 輸入延遲
因素
延遲, 抖動
誰會遇到
只有我, 整個伺服器
何時
偶爾隨機發生, 閒置一段時間後
負責單位
主要負責 外部(外部) · 協同 基礎設施團隊(伺服器基礎設施), 遊戲開發團隊(用戶端開發)
遊戲開發團隊要做的事
Android 10 以上的用戶端在遊戲中要求低延遲 Wi-Fi 模式(WIFI_MODE_FULL_LOW_LATENCY Wi-Fi lock,只在螢幕開啟且遊戲位於前景時生效),減少省電造成的延遲飆升。
基礎設施團隊要做的事
避免使用突發型(burstable)執行個體、不要把 RTO 最小值調得太低、保持 F-RTO 與時間戳記開啟(tcp_frto、tcp_timestamps)、重傳指標要與 nstat 的 TCPSpuriousRTOs、TCPDSACKRecv 一起看,以免誤認為遺失。
外部要做的事
為了減少延遲飆升本身,建議玩家在分享器使用 SQM、關閉 Wi-Fi 省電。
數值參考
Linux 會用 F-RTO 偵測不必要的 RTO,有時也會撤回已降低的傳送量。可用 nstat 的 TCPSpuriousRTOs(判定為不必要 RTO 的次數)與 TCPDSACKRecv(接收端回報「已經收過」的次數)確認。
圖表上
偶爾隨機飆高 · RTT(ping)、不必要的 RTO 次數
查看位置
每 1 分鐘執行一次 nstat,一起查看 TcpExtTCPTimeouts(RTO 到期)、TcpExtTCPSpuriousRTOs、TcpExtTCPDSACKRecv、TcpExtTCPLostRetransmit 的增加量。有封包擷取時用 Wireshark 篩選條件 tcp.analysis.spurious_retransmission
符合的跡象
RTO 增加時,TcpExtTCPSpuriousRTOs 或 TcpExtTCPDSACKRecv 也一起增加,同一時間 RTT 飆到數百 ms。接收端的封包擷取中,原本的封包與重傳的封包都有抵達
不符合的跡象
TcpExtTCPSpuriousRTOs 與 DSACK 沒有變化,TcpExtTCPLostRetransmit(連重送的封包也再次遺失)卻增加時,是實際遺失。RTT 沒有飆高、只有 DSACK 一直很多時,是「封包亂序造成的不必要快速重傳」
確認方式
用基礎設施工具確認(不需要遊戲程式碼)

出處

  1. RFC 5682: Forward RTO-Recovery (F-RTO): An Algorithm for Detecting Spurious Retransmission Timeouts with TCP IETF
    F-RTO:利用 RTO 之後收到的 ACK,判斷該次 RTO 是否不必要
  2. RFC 3481: TCP over Second (2.5G) and Third (3G) Generation Wireless Networks IETF
    行動網路的延遲飆升(換手、鏈路復原等)會引發不必要的 TCP 逾時與重傳,並使壅塞視窗縮小
  3. RFC 2883: An Extension to the Selective Acknowledgement (SACK) Option for TCP IETF
    DSACK:接收端回報重複收到的封包,讓傳送端知道哪些重傳是不必要的
  4. SNMP counter Linux kernel
    TcpExtTCPSpuriousRTOs(F-RTO 偵測到的不必要 RTO)、TcpExtTCPDSACKRecv(收到的 DSACK 數)、TcpExtTCPLostRetransmit(SACK 回報重送的封包再次遺失的次數)
  5. IP Sysctl Linux kernel
    tcp_frto 預設開啟(對 RTT 波動大的無線網路有利),tcp_timestamps 預設 1
  6. RFC 6298: Computing TCP's Retransmission Timer IETF
    要避免不必要的重傳,最小 RTO 必須夠大的依據(建議至少 1 秒)
  7. WifiManager Android (Google)
    WIFI_MODE_FULL_LOW_LATENCY(API 29,Android 10):只在連上 AP、螢幕開啟且 App 位於前景時才生效的低延遲 Wi-Fi lock
  8. net/ipv4/proc.c Linux kernel
    nstat 顯示的計數器名稱 TCPTimeouts、TCPSpuriousRTOs、TCPDSACKRecv、TCPLostRetransmit
  9. net/ipv4/tcp_timer.c Linux kernel
    TCPTimeouts 在重傳計時器(RTO)到期時增加
  10. nstat(8) — Linux manual page iproute2
    nstat 預設顯示自上次執行以來的增加量
  11. Display Filter Reference: Transmission Control Protocol Wireshark
    tcp.analysis.spurious_retransmission 顯示篩選條件

相關原因

同一層:TCP 重傳的根本原因

同一症狀(定格)在其他層的原因

查看含圖解與實驗的完整版卡片