游戏卡顿白皮书 › TCP 重传的根本原因
瓶颈队列溢出(拥塞丢包) Tail drop at a congested bottleneck
原因 ID rt-queue-drop · 主责 运维团队·网络运维 · 配合 外部·外部, 研发团队·客户端开发
在含图示和实验的完整版中打开此卡片 →
路由器、运营商之间的互联链路、数据中心线路这类最窄处的队列一旦满了,新来的数据包就会被丢弃。
起因 视频、下载和其他用户的流量把瓶颈链路占满 → 结果 队列满的期间,新到的数据包接连被丢弃(tail drop)。没被丢弃的包也要在满队列的末尾排队 → 画面表现 多个包同时丢失,长时间卡住后表现为快进,晚上多发
- 症状
- 卡住, 快进, 拉回
- 因素
- 丢包, 延迟
- 谁会遇到
- 同一家庭, 特定地区/运营商, 全服
- 何时出现
- 晚高峰, 人多的时候
- 负责方
- 主责 运维团队·网络运维 · 配合 外部·外部, 研发团队·客户端开发
- 研发团队要做的事
- 丢包集中或 ping 飙升时,在画面上显示网络状态(提示可能是同一线路上有大流量传输)。
- 运维团队要做的事
- 保证数据中心线路有余量;检查我方线路和交换机端口的队列丢弃(output drops)计数器;运营商链路拥塞时,改走其他线路或对等互联绕行。
- 外部要做的事
- 引导玩家在路由器上启用 SQM(fq_codel、CAKE)和 ECN(让发送方在队列溢出前降速);要求运营商给瓶颈链路扩容。
- 数值参考
- 队列溢出的那一刻,几十 ms 内进来的包会有相当一部分同时丢失。连续丢包时,重传的包也容易再丢,所以经常拖到 RTO。
- 监控图上
- 特定时段偏高 · 重传率、RTT(ping)
- 查看位置
- 把服务器重传率(每 1 分钟运行一次 nstat,取 TcpRetransSegs ÷ TcpOutSegs 的增量)和每个连接的 RTT 按地区、运营商、时段拆开看,同时看我方线路和交换机端口的出方向丢弃(ifOutDiscards)。在高峰和空闲时段分别对问题地区跑 mtr 并比较
- 确认依据
- 只在晚高峰重传率上升,丢包之前 RTT 先上升(队列在填满)。mtr 中只在高峰时段从某一跳起直到终点丢包和延迟一起增加
- 排除依据
- 丢包前 RTT 没有上升,看“流量监管丢弃超额流量”。不分时段、丢包率一直差不多,看“物理层错误”或“路径变更/ECMP 故障路径”
- 确认手段
- 运维工具即可确认(无需游戏代码)
- 真实案例
- Riot Games 2015: 绕远路的 League of Legends 流量与 Riot Direct
出处
- RFC 7567: IETF Recommendations Regarding Active Queue Management IETF
说明 tail drop 会让队列长时间处于满载,增加延迟并造成集中丢包,并建议采用 AQM - RFC 8290: The Flow Queue CoDel Packet Scheduler and Active Queue Management Algorithm IETF
fq_codel:用按流划分的队列和 AQM 让队列保持较短,减轻缓冲区膨胀 - RFC 3168: The Addition of Explicit Congestion Notification (ECN) to IP IETF
ECN:在 IP 头中做标记来通知拥塞,不必丢弃数据包 - Smart Queue Management Bufferbloat.net
SQM:把按流调度、队列长度管理(AQM)和流量整形结合使用的方式 - Cake Bufferbloat.net
CAKE:把流量整形器和 fq_codel 类队列管理合在一起的路由器用 SQM - net/ipv4/proc.c Linux kernel
nstat 中的 TcpRetransSegs、TcpOutSegs(Tcp 项下的 RetransSegs、OutSegs) - nstat(8) — Linux manual page iproute2
nstat 默认显示自上次运行以来的增量 - RFC 2863: The Interfaces Group MIB IETF
ifOutDiscards:没有错误,却因腾出缓冲区空间等原因没有发出、直接丢弃的数据包数 - An Internet-Wide Analysis of Traffic Policing Google
区分方法:队列溢出时,丢包前排队时间和 RTT 会先上升;流量监管则在 RTT 不增加的情况下丢弃超额部分(SIGCOMM 2016)
相关原因
同一层:TCP 重传的根本原因
其他层中同样导致“卡住”的原因
查看含图示和实验的原卡片