游戏卡顿白皮书 › L8 Socket 与协议
空闲后的慢启动 Slow start after idle
原因 ID sk-slowstart · 主责 运维团队·系统运维 · 配合 研发团队·服务器开发
在含图示和实验的完整版中打开此卡片 →
TCP 空闲一段时间后会重新缩小拥塞窗口(一次能发送的量),突然要发大量数据时只能分几次发。
起因 在空闲了一段时间的连接上发送大量数据(例如进入城镇) → 结果 拥塞窗口已经缩小,要分成多个往返发送 → 画面表现 进入后周围的角色和 NPC 要晚几个往返才出现(服务器越远越明显)
- 症状
- 操作延迟, 隐身/幽灵实体
- 因素
- 延迟
- 谁会遇到
- 只有我
- 何时出现
- 移动中/切换地图时, 挂机一段时间后
- 负责方
- 主责 运维团队·系统运维 · 配合 研发团队·服务器开发
- 研发团队要做的事
- 减少进入时的数据量(先发最必要的)。
- 运维团队要做的事
- 关闭 tcp_slow_start_after_idle(Linux,服务器全局设置)。
- 数值参考
- 空闲时间超过 RTO,拥塞窗口就开始缩小;空闲很久的话会降到约 14 KB(10 个包)。这时 100 KB 无法一次发完,要分 3 个往返发送。
- 监控图上
- 仅部分偏高 · 进入后的传输时间(RTT 长的玩家)
- 查看位置
- 确认 sysctl net.ipv4.tcp_slow_start_after_idle 的值,在空闲后进入区域的瞬间,看该连接 ss -ti 中的 cwnd(拥塞窗口)是否变小
- 确认依据
- 设置为 1(默认),空闲后进入的瞬间 cwnd 降到 10 左右,传输被分成多个往返。RTT 越长的玩家出现得越晚,改为 0 后消失
- 排除依据
- cwnd 保持得很大却仍然出现得晚,看服务器侧的进入处理(“进入密集区域时实体生成激增”)
- 确认手段
- 运维工具即可确认(无需游戏代码)
出处
- IP Sysctl Linux kernel
tcp_slow_start_after_idle 默认开启,空闲达到 RTO 就缩小拥塞窗口(RFC 2861 方式) - RFC 5681: TCP Congestion Control IETF
超过 RTO 未发送数据时,把拥塞窗口缩小到重启窗口 min(IW, cwnd) 以下并慢启动 - RFC 6928: Increasing TCP's Initial Window IETF
初始窗口 10 个报文段,最大 14,600 字节 - ss(8) — Linux manual page iproute2
-i 的 cwnd(拥塞窗口)、ssthresh(慢启动阈值)
相关原因
同一层:L8 Socket 与协议
其他层中同样导致“操作延迟”的原因
查看含图示和实验的原卡片