游戏卡顿白皮书 › TCP 重传的根本原因
路径变更/ECMP 故障路径 Route change / bad ECMP member
原因 ID rt-path · 主责 运维团队·网络运维 · 配合 研发团队·服务器开发, 外部·外部
在含图示和实验的完整版中打开此卡片 →
互联网路由切换的几秒内,或者被分配到多条 ECMP 路径中某条故障路径的连接上,会出现丢包。
起因 BGP 路由重新计算,或多条路径(ECMP、LAG)中某一条的设备或线路故障 → 结果 路径切换期间暂时丢包,或只有走这条路径的连接持续丢包 → 画面表现 突然卡住几秒后快进,或者“重连就好了”(被分到了别的路径)
- 症状
- 卡住, 快进, 瞬移
- 因素
- 丢包
- 谁会遇到
- 特定地区/运营商
- 何时出现
- 偶尔随机
- 负责方
- 主责 运维团队·网络运维 · 配合 研发团队·服务器开发, 外部·外部
- 研发团队要做的事
- 记录每个连接的重传统计(TCP_INFO),以便提取受影响玩家的 IP、端口和时间点;连接停顿几秒时不要马上断开。
- 运维团队要做的事
- 按地区、运营商监控重传率;确认重连后路径是否改变;接入多家运营商线路;排查我方设备 ECMP、LAG 路径中的故障链路;测路径时也用和游戏相同的 TCP 端口(mtr --tcp --port。路径由地址和端口决定,普通 ping 可能走另一条路径,结果显示一切正常)。
- 外部要做的事
- 向运营商报告故障路径,附上用相同 TCP 端口测得的路径结果和重连前后的对比。
- 监控图上
- 某一时刻起台阶式上升 · RTT(ping),各地区、各运营商的重传率
- 查看位置
- 用 bcc tcpretrans -c 按连接汇总重传,提取受影响玩家的地址和端口;从服务器到玩家、从玩家到服务器,都用和游戏相同的 TCP 端口跑 mtr(mtr -T -P PORT)并比较。重连前后的结果也要比较
- 确认依据
- 以某一时刻为界,某地区或运营商的 RTT 像台阶一样跳变,同时出现几秒的集中丢包;或者同一运营商内只有部分连接(地址、端口组合)持续重传,重连后好转。有时普通 ping 一切正常,只有 TCP mtr 能看到丢包
- 排除依据
- 该运营商的所有连接在晚高峰一起变差,看“瓶颈队列溢出”。只有一名玩家差,且 ping 路由器就已丢包,看“无线链路丢包”
- 确认手段
- 运维工具即可确认(无需游戏代码)
- 真实案例
- Cloudflare 2020: Cloudflare 骨干网配置错误导致部分城市流量丢失
出处
- RFC 2991: Multipath Issues in Unicast and Multicast Next-Hop Selection IETF
说明多路径下 ping、traceroute 等诊断工具的结果不可靠,并介绍对流做哈希以固定路径的方式 - RFC 2992: Analysis of an Equal-Cost Multi-Path Algorithm IETF
ECMP 用区分流的头部字段的哈希值选择下一跳路径(同一个流走同一条路径) - tcp(7) — Linux manual page Linux man-pages
TCP_INFO:查询每个 socket 的状态(struct tcp_info) - mtr(8) manual page source mtr
-T(--tcp)用 TCP SYN 代替 ICMP,-P(--port)指定目标端口 - Demonstrations of tcpretrans, the Linux eBPF/bcc version IO Visor
每次重传输出一行,显示对端地址和端口;-c 按流汇总重传次数
相关原因
同一层:TCP 重传的根本原因
其他层中同样导致“卡住”的原因
查看含图示和实验的原卡片