遊戲 Lag 白皮書 › TCP 重傳的根本原因
RTO 設定不符合環境 RTO min too low or too high
原因 ID rt-rto-setting · 主要負責 基礎設施團隊(伺服器基礎設施) · 協同 遊戲開發團隊(伺服器開發)
在含圖解與實驗的完整版中開啟卡片 →
RTO 最小值調得太低時,只要稍微延遲就會產生不必要的重傳;預設值(200ms)對遊戲來說又太長,每遺失一次就要停住很久。
為什麼 為了資料中心環境把 RTO 最小值大幅調低,或在網際網路區段直接沿用預設值 → 於是 太低時,瞬間延遲也會引發大量重傳;太高時,每次遺失都要等很久 → 畫面上 預設值時,遺失一次就定格數百 ms 後快轉;調得太低時定格變短,但不必要的重傳暴增,浪費線路頻寬
- 症狀
- 定格, 快轉, 輸入延遲
- 因素
- 延遲
- 誰會遇到
- 整個伺服器
- 何時
- 一直都有
- 負責單位
- 主要負責 基礎設施團隊(伺服器基礎設施) · 協同 遊戲開發團隊(伺服器開發)
- 遊戲開發團隊要做的事
- Linux 6.15 以上時,評估在遊戲連線用 TCP_RTO_MAX_MS 調低 RTO 上限(放棄連線前的時間也會跟著縮短,所以要同時用 TCP_USER_TIMEOUT 設定斷線判定時間)、只對伺服器之間的內部連線用 socket 選項 TCP_RTO_MIN_US(6.15 以上)調低 RTO 最小值、評估用 socket 選項 TCP_THIN_LINEAR_TIMEOUTS 讓遊戲連線的連續 RTO 不再加倍。
- 基礎設施團隊要做的事
- 只對伺服器之間的內部連線依路由調低 rto_min,網際網路區段維持預設值,改用 RACK-TLP 與 thin stream 設定(tcp_thin_linear_timeouts)補強。
- 數值參考
- Linux RTO = 往返時間 + max(200ms, RTT 偏差×4)。每失敗一次就加倍,最大 120 秒。Linux 6.15 以上可用 TCP_RTO_MAX_MS 把這個上限最低降到 1 秒。
- 圖表上
- 一開始就一直偏高 · 各連線的 RTO、不必要的 RTO 次數
- 查看位置
- 查看伺服器的 RTO 最小值設定(ip route show 的 rto_min,Linux 6.11 以上為 sysctl net.ipv4.tcp_rto_min_us)與 ss -ti 的 rto、rtt,並查看 nstat 的 TcpExtTCPSpuriousRTOs 增加量
- 符合的跡象
- 調低最小值的伺服器上,網際網路連線的 rto 緊貼著 rtt,TcpExtTCPSpuriousRTOs 大量增加。維持預設值時,遊戲連線的 rto 比 rtt 大 200ms 以上,每遺失一次就停住那麼久
- 不符合的跡象
- rto 符合預設計算(rtt + 200ms 左右)、不必要的 RTO 也少,停頓卻特別長時,問題在連續遺失或復原方式(「thin stream 復原緩慢」、「中間設備移除 TCP 選項」)
- 確認方式
- 用基礎設施工具確認(不需要遊戲程式碼)
出處
- RFC 6298: Computing TCP's Retransmission Timer IETF
RTO = SRTT + max(G, 4·RTTVAR),建議最小 1 秒,每失敗一次就加倍,若要設最大值須在 60 秒以上 - include/net/tcp.h Linux kernel
Linux TCP_RTO_MIN 200ms、TCP_RTO_MAX 120 秒 - net/ipv4/tcp_input.c Linux kernel
Linux 的 RTO 為 SRTT + rttvar,rttvar 不會低於 RTO 最小值(預設 200ms) - tcp: add the ability to control max RTO Linux kernel
新增 TCP_RTO_MAX_MS socket 選項(1~120 秒),自 Linux 6.15 起 - tcp: add sysctl_tcp_rto_min_us Linux kernel
新增整台伺服器的預設 RTO 最小值 tcp_rto_min_us,自 Linux 6.11 起 - tcp: support TCP_RTO_MIN_US for set/getsockopt use Linux kernel
新增可為每個 socket 設定 RTO 最小值的 TCP_RTO_MIN_US socket 選項,自 Linux 6.15 起 - IP Sysctl Linux kernel
tcp_rto_min_us 預設 200000(路由選項 rto_min、socket 選項 TCP_RTO_MIN_US 優先)、tcp_rto_max_ms 1,000~120,000(預設 120,000)、tcp_thin_linear_timeouts - ip-route(8) — Linux manual page iproute2
各路由的 rto_min 選項:與該目的地通訊時使用的 RTO 最小值 - Thin-streams and TCP Linux kernel
用 TCP_THIN_LINEAR_TIMEOUTS 可以只對 thin stream 連線關閉指數退避 - tcp(7) — Linux manual page Linux man-pages
TCP_USER_TIMEOUT:等待未確認的資料多久後關閉連線 - ss(8) — Linux manual page iproute2
ss -i 的 rto(ms)與 rtt - SNMP counter Linux kernel
TcpExtTCPSpuriousRTOs:F-RTO 偵測到的不必要 RTO
相關原因
同一層:TCP 重傳的根本原因
同一症狀(定格)在其他層的原因
查看含圖解與實驗的完整版卡片