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

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

无线链路丢包 Wi-Fi / cellular link loss

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

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

Wi-Fi 和移动网络会在无线链路上重传几次,仍然失败就丢弃数据包。被丢弃的包要等过好一阵,才由 TCP 重新发送。

起因 信号弱或干扰严重,无线链路上的传输接连失败 → 结果 超过无线设备的重试上限(通常几次到十几次)就丢弃数据包 → 画面表现 卡住的时长等于 TCP 重传的等待时间,后面的包在接收缓冲区里等着,之后表现为快进

症状
卡住, 快进, 瞬移
因素
丢包, 抖动
谁会遇到
只有我, 同一家庭
何时出现
偶尔随机, 移动中/切换地图时
负责方
主责 外部·外部 · 配合 运维团队·系统运维, 研发团队·服务器开发, 研发团队·客户端开发
研发团队要做的事
服务器:开启 TCP_NODELAY(Nagle 开着时,RACK 没有后续数据包可用来判断丢包);重传阻塞期间要发的状态更新不要堆积,只发最新的(用 TCP_NOTSENT_LOWAT 限制堆在内核里的量)。客户端:开启 TCP_NODELAY(自己输入方向的丢包由客户端操作系统恢复);丢包集中或 ping 飙升时,在画面上显示网络状态。
运维团队要做的事
用 RACK-TLP 加快丢包恢复(服务器无法阻止无线丢包,能做的只有加快恢复);确认新版 Linux 的默认值 net.ipv4.tcp_recovery=1(RACK)、net.ipv4.tcp_early_retrans=3(TLP)没有被改掉。
外部要做的事
引导玩家改用有线连接,使用 5 GHz、6 GHz 频段,调整路由器位置或信道。
数值参考
无线丢包率 1% 意味着每 100 个游戏数据包丢 1 个。每秒收 10 个包,大约每 10 秒就会顿一下。没有 RACK-TLP 时,每次都要停顿一个 RTO(ping + 200 ms 以上)。
监控图上
仅部分偏高 · 每个连接的重传率、每个连接的 RTT(ping)
查看位置
在玩家 PC 上分别向路由器(网关)地址和游戏服务器 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 = 200 ms
  8. misc/ss.c iproute2
    ss -ti 显示 retrans:当前正在重传的数量/累计重传数量,以及 rtt:RTT/RTT 偏差(rttvar)

相关原因

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

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

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