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

游戏卡顿白皮书 › L8 Socket 与协议

TCP RTO 与指数退避 RTO and exponential backoff

原因 ID sk-rto · 主责 研发团队·服务器开发 · 配合 研发团队·客户端开发

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

重传每失败一次,等待时间就翻一倍,短暂的线路中断会变成长时间停顿。

起因 线路短暂中断,重传也接连失败 → 结果 到下一次尝试的间隔按 0.3 → 0.6 → 1.2 → 2.4 秒这样翻倍(以 ping 100 ms 为例) → 画面表现 线路只断了 1 秒,游戏却卡住 2 秒以上。断得更久,最终就会掉线

症状
卡住, 掉线
因素
丢包, 停顿
谁会遇到
只有我
何时出现
偶尔随机, 移动中/切换地图时
负责方
主责 研发团队·服务器开发 · 配合 研发团队·客户端开发
研发团队要做的事
服务器:响应心跳,一段时间收不到就主动清理连接(用 TCP_USER_TIMEOUT 让连接更早放弃);凭会话令牌接续会话;使用可靠 UDP。客户端:以较短间隔发送心跳,响应一断就尽快重连,不要等 TCP 重传。
数值参考
Linux 的 RTO(重传等待时间)最小为“ping + 200 ms”,建立连接时从 1 秒起步。按默认设置(tcp_retries2=15),即使重传一直失败,也要约 15 分钟后才放弃连接。
监控图上
断流后集中到达 · 每个连接的 RTO、backoff,RTO 超时次数
查看位置
对停顿的连接用 ss -ti 看 rto(重传等待 ms)和 backoff(连续超时次数),全服看 nstat -az 中 TcpExtTCPTimeouts(重传定时器超时次数)的增量
确认依据
停顿连接的 backoff 在 1 以上,rto 已涨到秒级,且那个时刻 TCPTimeouts 增加
排除依据
重传都以快速重传结束、没有 RTO 超时,停顿就很短。这时看“TCP 队头阻塞”
确认手段
运维工具即可确认(无需游戏代码)

出处

  1. RFC 6298: Computing TCP's Retransmission Timer IETF
    首个 RTO 为 1 秒,定时器每超时一次 RTO 就翻倍(指数退避)
  2. net/ipv4/tcp_input.c (Linux v6.12) Linux kernel
    Linux RTO = 平滑 RTT + RTT 波动值,波动值的下限是 tcp_rto_min(200 ms),所以 RTO 至少为 RTT+200 ms
  3. IP Sysctl Linux kernel
    tcp_rto_min_us 默认 200 ms,连接请求的首个 RTO 为 1 秒,tcp_retries2=15 时至少 924.6 秒(约 15 分钟)才放弃
  4. ss(8) — Linux manual page iproute2
    -i 的 rto(重传定时器,ms)和 backoff(指数退避次数)
  5. net/ipv4/proc.c (Linux v6.12) Linux kernel
    nstat 显示的计数器名:TcpExt 组的 TCPTimeouts
  6. net/ipv4/tcp_timer.c (Linux v6.12) Linux kernel
    重传定时器每超时一次,TCPTimeouts 就加一,backoff 加一,RTO 翻倍(直到最大值)

相关原因

同一层:L8 Socket 与协议

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

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