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

游戏卡顿白皮书 › TCP 重传的根本原因

RTO 设置与环境不匹配 RTO min too low or too high

原因 ID rt-rto-setting · 主责 运维团队·系统运维 · 配合 研发团队·服务器开发

在含图示和实验的完整版中打开此卡片 →

RTO 最小值调得太低,稍微晚一点就会产生虚假重传;默认值(200 ms)对游戏来说又太长,每丢一次包都要停顿很久。

起因 为数据中心场景把 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(200 ms, 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 大 200 ms 以上,每丢一次包就停顿这么久
排除依据
rto 符合默认算法(rtt + 200 ms 左右),虚假 RTO 也少,停顿却特别长,看连续丢包或恢复机制方面(“thin stream 恢复慢”“中间设备剥离 TCP 选项”)
确认手段
运维工具即可确认(无需游戏代码)

出处

  1. RFC 6298: Computing TCP's Retransmission Timer IETF
    RTO = SRTT + max(G, 4·RTTVAR),建议最小 1 秒,每失败一次翻倍,如设最大值应不少于 60 秒
  2. include/net/tcp.h Linux kernel
    Linux TCP_RTO_MIN 200 ms,TCP_RTO_MAX 120 秒
  3. net/ipv4/tcp_input.c Linux kernel
    Linux RTO 为 SRTT + rttvar,rttvar 不会低于 RTO 最小值(默认 200 ms)
  4. tcp: add the ability to control max RTO Linux kernel
    新增 TCP_RTO_MAX_MS socket 选项(1~120 秒),从 Linux 6.15 起
  5. tcp: add sysctl_tcp_rto_min_us Linux kernel
    新增整台服务器默认的 RTO 最小值 tcp_rto_min_us,从 Linux 6.11 起
  6. tcp: support TCP_RTO_MIN_US for set/getsockopt use Linux kernel
    新增按 socket 设定 RTO 最小值的 TCP_RTO_MIN_US socket 选项,从 Linux 6.15 起
  7. 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
  8. ip-route(8) — Linux manual page iproute2
    按路由的 rto_min 选项:与该目的地通信时的 RTO 最小值
  9. Thin-streams and TCP Linux kernel
    用 TCP_THIN_LINEAR_TIMEOUTS 可以只对 thin stream 连接关闭指数退避
  10. tcp(7) — Linux manual page Linux man-pages
    TCP_USER_TIMEOUT:等待未确认数据、直到关闭连接的时间
  11. ss(8) — Linux manual page iproute2
    ss -i 的 rto(ms)和 rtt
  12. SNMP counter Linux kernel
    TcpExtTCPSpuriousRTOs:F-RTO 检测到的虚假 RTO

相关原因

同一层:TCP 重传的根本原因

其他层中同样导致“卡住”的原因

查看含图示和实验的原卡片