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

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

延迟飙升导致的虚假重传 Spurious RTO from delay spikes

原因 ID rt-spurious-delay · 主责 外部·外部 · 配合 运维团队·系统运维, 研发团队·客户端开发

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

数据包只是一时到得特别晚,并没有丢。但只要这段延迟超过 RTO,发送方就会判定为丢包并重传。

起因 缓冲区膨胀、Wi-Fi 省电、移动网络无线状态切换、虚拟机挂起,使瞬时延迟达到几百 ms → 结果 RTO 先到期并重传,原包随后也到达(接收方收到重复数据) → 画面表现 卡住和快进是延迟飙升本身造成的。虚假重传几乎不会让卡住变长,只会推高重传指标,被误认为丢包

症状
卡住, 快进, 操作延迟
因素
延迟, 抖动
谁会遇到
只有我, 全服
何时出现
偶尔随机, 挂机一段时间后
负责方
主责 外部·外部 · 配合 运维团队·系统运维, 研发团队·客户端开发
研发团队要做的事
Android 10 及以上的客户端在游戏中申请低延迟 Wi-Fi 模式(WIFI_MODE_FULL_LOW_LATENCY Wi-Fi 锁,仅在屏幕亮着且游戏在前台时生效),减少省电造成的延迟飙升。
运维团队要做的事
避免使用突发性能型实例;不要把 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、屏幕亮着且应用在前台时生效的低延迟 Wi-Fi 锁
  8. net/ipv4/proc.c Linux kernel
    nstat 中的计数器名 TCPTimeouts、TCPSpuriousRTOs、TCPDSACKRecv、TCPLostRetransmit
  9. net/ipv4/tcp_timer.c Linux kernel
    重传定时器(RTO)到期时 TCPTimeouts 增加
  10. nstat(8) — Linux manual page iproute2
    nstat 默认显示自上次运行以来的增量
  11. Display Filter Reference: Transmission Control Protocol Wireshark
    tcp.analysis.spurious_retransmission 显示过滤器

相关原因

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

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

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