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

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

無線區段的封包遺失 Wi-Fi / cellular link loss

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

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

Wi-Fi 與行動網路在無線區段會先重傳幾次,仍然失敗就丟棄封包。被丟棄的封包,TCP 要過好一段時間才會重送。

為什麼 訊號弱或干擾嚴重,無線區段的傳輸接連失敗 → 於是 超過無線設備的重試上限(通常是數次~十幾次)就丟棄封包 → 畫面上 定格的時間等於 TCP 等待重傳的時間,後面的封包在接收緩衝區等候,之後快轉

症狀
定格, 快轉, 瞬移
因素
遺失, 抖動
誰會遇到
只有我, 同一個家
何時
偶爾隨機發生, 移動中/切換地圖時
負責單位
主要負責 外部(外部) · 協同 基礎設施團隊(伺服器基礎設施), 遊戲開發團隊(伺服器開發), 遊戲開發團隊(用戶端開發)
遊戲開發團隊要做的事
伺服器:開啟 TCP_NODELAY(Nagle 開著時,RACK 沒有後續封包可用來判斷遺失);重傳卡住期間,待送的狀態更新只保留最新的一筆(用 TCP_NOTSENT_LOWAT 限制累積在 kernel 的量)。用戶端:開啟 TCP_NODELAY(玩家輸入方向的遺失由用戶端 OS 負責復原);遺失集中出現或 ping 急遽升高時,在畫面上顯示網路狀態。
基礎設施團隊要做的事
用 RACK-TLP 加快遺失復原(伺服器無法阻止無線遺失,能做的只有加快復原)、確認新版 Linux 的預設值 net.ipv4.tcp_recovery=1(RACK)、net.ipv4.tcp_early_retrans=3(TLP)沒有被改掉。
外部要做的事
建議玩家改用有線連線、使用 5GHz 或 6GHz 頻段、調整分享器位置或更換頻道。
數值參考
無線遺失率 1% 時,每 100 個遊戲封包就有 1 個消失。每秒收 10 個封包的話,大約每 10 秒就會頓一下。沒有 RACK-TLP 時,每次遺失都要停住一個 RTO(ping + 200ms 以上)的時間。
圖表上
只有部分偏高 · 各連線的重傳率、各連線的 RTT(ping)
查看位置
在玩家電腦上分別對分享器(閘道)位址與遊戲伺服器各 ping 數百次,比較遺失與延遲的變動幅度,再改用有線或行動數據重新測量。伺服器端用 ss -ti 查看該玩家連線的 retrans 與 rtt(平均值/偏差)
符合的跡象
ping 分享器時就已出現遺失或忽高忽低的延遲,改用有線後就消失。從伺服器看,只有該玩家連線的 retrans 與 RTT 偏差偏大
不符合的跡象
到分享器為止都正常、過了分享器才開始遺失時,問題在電信業者或路徑端(「瓶頸佇列溢位」、「路由變更、ECMP 不良路徑」)。同一電信業者的多位玩家同時變差時,先查電信業者區段
確認方式
在玩家端環境確認
深入了解
無線設備的重試會造成抖動(每次重試數 ms),只有超過重試上限的封包才會變成遺失。因此無線品質越差,症狀就會依「抖動 → 偶爾定格 → 頻繁定格」的順序加重。在分享器(AP)之間切換的瞬間(漫遊),有時會連續遺失數十 ms~數秒。行動網路在基地台區段會大量重傳,所以比起遺失,更常以數百 ms 的延遲飆升出現。
實際案例
Square Enix 2021: FINAL FANTASY XIV 資料片上市的壅塞與登入排隊錯誤

出處

  1. net/wireless/core.c Linux kernel
    Linux 無線協定堆疊的預設重試上限:短訊框 7 次、長訊框 4 次(dot11ShortRetryLimit、dot11LongRetryLimit)
  2. RFC 3481: TCP over Second (2.5G) and Third (3G) Generation Wireless Networks IETF
    行動網路靠鏈路層重傳讓 IP 遺失很少,但這種復原會以抖動與延遲飆升的形式出現
  3. Wi-Fi roaming support in Apple devices Apple
    切換 AP 時,在新 AP 的認證完成前無法傳送資料,802.1X 環境下可能要花幾秒
  4. RFC 8985: The RACK-TLP Loss Detection Algorithm for TCP IETF
    RACK(以時間判斷遺失)與 TLP(重傳最後一個封包)的定義
  5. IP Sysctl Linux kernel
    tcp_recovery 預設 0x1(RACK)、tcp_early_retrans 預設 3(TLP 開啟);以 TCP_NOTSENT_LOWAT、tcp_notsent_lowat 限制尚未送出的資料量
  6. tcp(7) — Linux manual page Linux man-pages
    TCP_NODELAY 會關閉 Nagle 演算法,讓小資料也立刻送出
  7. include/net/tcp.h Linux kernel
    RTO 最小值 TCP_RTO_MIN = 200ms
  8. misc/ss.c iproute2
    ss -ti 會顯示 retrans:目前重傳中的數量/累計重傳次數,以及 rtt:RTT/RTT 偏差(rttvar)

相關原因

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

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

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