游戏卡顿白皮书 › 按症状查找
快进:36 个原因及负责方
又称:唰唰唰、倍速播放、一下子全结算
在含图示的完整版症状词典中打开 →
停住的画面恢复后,积压的移动、打击和伤害一下子快速放完。
怪物和玩家像快进一样移动,伤害数字和特效一股脑儿涌出来。
数据包在某处积压,然后一次性放出来了。典型原因有 TCP 等待重传、服务器追赶进度、客户端处理积压。
导致此症状的原因
L1 客户端游戏进程
- 主线程数据包处理瓶颈: 收到的数据包每帧只处理固定数量时,一下子涌来的数据包会不断顺延到下一帧。 (研发团队·客户端开发)
- 固定时间步长追赶失控: 停顿一次之后集中补算积压的计算,又因为这些计算再次积压。 (研发团队·客户端开发)
L2 客户端操作系统与设备
- 后台进程占用 CPU: 杀毒扫描、Windows 更新、直播软件、浏览器视频占着 CPU 核心时,游戏线程分不到 CPU,只能等待。 (外部·外部)
- 接收缓冲区溢出: 游戏太忙,从 socket(操作系统提供的网络收发接口)里取数据包取得晚,操作系统的缓冲区就会溢出。 (研发团队·客户端开发)
- 同一设备上其他应用占用带宽: 云同步、大文件下载、游戏更新在同一台 PC 上运行时,游戏数据包要在队列里排队。 (外部·外部)
- 窗口最小化/失去焦点时处理受限: 切到别的窗口或最小化游戏时,游戏和 Windows 为了省电会让游戏降速运行。切回来时,积压的数据包会一下子涌来,或者已经掉线。 (研发团队·客户端开发)
L3 家庭网络
- 缓冲区膨胀(路由器队列): 家里有人上传视频或下载大文件时,路由器队列里会堆积几百 ms 的数据包,游戏数据包也得排在后面等。 (外部·外部)
L6 服务器网卡
- 云宿主机维护/热迁移: 云厂商维护物理服务器(宿主机)时,会把虚拟机迁到其他宿主机(热迁移)或暂停片刻。这期间整台服务器停住,停住时间一长,连接就会断开。 (运维团队·系统运维)
L7 服务器操作系统(内核)
L8 Socket 与协议
- TCP 队头阻塞: TCP 为了保证顺序,在重新收到丢失的那个包之前,不会把后面已经到达的数据包交给游戏。 (研发团队·服务器开发)
- 可靠 UDP 重传配置: 在 UDP 之上自己实现的重传规则太保守,恢复就慢;太激进,又会让线路更堵。 (研发团队·服务器开发)
- 拥塞控制导致发送量骤降: TCP 把丢包当作拥塞信号,把发送速率降低 30~50%。遇到 Wi-Fi 丢包也会同样降速。 (运维团队·系统运维)
L9 服务器游戏进程
- 广播激增: 把一个人的移动发给所有能看到他的人时,要发的更新数量是聚集人数的平方。 (研发团队·服务器开发)
- 战斗集中在单一目标(世界 BOSS): 几百人同时打一个 BOSS 时,这一只 BOSS 的计算全压在一处,命中信息还要发给所有看得到的人。 (研发团队·服务器开发)
- 进入密集区域时实体生成激增: 传送到挤满人的城镇时,服务器要把新进入视野的几百人的外观、装备、状态一次性发过来。 (研发团队·服务器开发)
L10 内存
- 服务器 GC 全局停顿: Java、C# 服务器为回收垃圾对象而暂停所有线程(stop-the-world),这段时间里整个服务器都停住。 (研发团队·服务器开发)
同步设计
- 没有时间戳、一到就播放: 服务器事件不附带发生时刻、一收到就播放时,网络抖动会原封不动地让表现时机忽快忽慢。 (研发团队·客户端开发)
只有部分人遇到的问题
- 网络差的玩家在别人画面上快进移动: 线路差的人,输入会忽多忽少地扎堆到达服务器。服务器每个 tick 收到多少就应用多少时,在别人眼里,这个角色会顿一下,然后一下子走出好几步。 (研发团队·服务器开发)
- 到达即处理的服务器造成的快进: 在包一到就立即处理并广播的服务器上,网络差的人扎堆到达的动作会被接连立即执行。 (研发团队·服务器开发)
- 怪物控制权在慢的客户端上: 有的游戏为减轻服务器负载,把怪物的移动计算交给附近某个玩家的客户端。这个人的线路差时,这只怪物在所有人的画面上都会动得很怪。 (研发团队·服务器开发)
- 后台窗口处理受限: 处于后台窗口的客户端,游戏、引擎、OS 都会减少它的帧和处理量。收到的包不能及时处理,就会积压或溢出。 (研发团队·客户端开发)
TCP 重传的根本原因
- 无线链路丢包: Wi-Fi 和移动网络会在无线链路上重传几次,仍然失败就丢弃数据包。被丢弃的包要等过好一阵,才由 TCP 重新发送。 (外部·外部)
- 瓶颈队列溢出(拥塞丢包): 路由器、运营商之间的互联链路、数据中心线路这类最窄处的队列一旦满了,新来的数据包就会被丢弃。 (运维团队·网络运维)
- 突发发送导致浅缓冲区溢出: 服务器每个 tick 在一瞬间集中发出几千人份的更新,交换机的小缓冲区或云平台的瞬时上限不到 1 ms 就会溢出,一部分包被丢弃。 (研发团队·服务器开发)
- 流量监管丢弃超额流量: 运营商套餐限速、云实例上限和 DDoS 防护设备,有时会把超过规定速率的数据包直接丢弃,不放进队列。 (运维团队·网络运维)
- 物理层错误(线缆/光模块/连接器不良): 线缆损坏、光纤连接器积灰、光模块老化都会产生误码,损坏的数据包会被设备悄无声息地丢弃。 (运维团队·网络运维)
- 双工不匹配: 一端用自动协商,另一端把速率和双工写死,就会有一端以半双工工作,每当负载上来就因冲突丢包。 (运维团队·网络运维)
- 接收端服务器主机丢包: 数据包已经到了服务器,却因网卡的环形缓冲区(暂存到达数据包的缓冲区)溢出,或内核中负责接收处理的 CPU 核心饱和而被丢弃。 (运维团队·系统运维)
- 中间设备超出处理上限(防火墙/IPS/DDoS 防护): 防火墙、入侵防御设备(IPS)、DDoS 防护设备会逐个检查经过的数据包。一旦超出检测能力,处理不过来的包就会被丢弃。 (运维团队·网络运维)
- 路径变更/ECMP 故障路径: 互联网路由切换的几秒内,或者被分配到多条 ECMP 路径中某条故障路径的连接上,会出现丢包。 (运维团队·网络运维)
- 延迟飙升导致的虚假重传: 数据包只是一时到得特别晚,并没有丢。但只要这段延迟超过 RTO,发送方就会判定为丢包并重传。 (外部·外部)
- RTO 设置与环境不匹配: RTO 最小值调得太低,稍微晚一点就会产生虚假重传;默认值(200 ms)对游戏来说又太长,每丢一次包都要停顿很久。 (运维团队·系统运维)
- thin stream 恢复慢: 像游戏这样稀疏地发小包时,还没等到“后续 3 个包”,RTO 就先到期了。同样的丢包,停顿时间比大流量传输长得多。 (研发团队·服务器开发)
- 中间设备剥离 TCP 选项: 部分防火墙或加速设备删除或改写 TCP 选项后,丢多个包时每个往返只能恢复一个,或者窗口(一次能发送的量)变小,速度变慢。 (运维团队·网络运维)
- 零窗口(看起来像重传的停顿): 接收方程序没有及时读取 socket,缓冲区满了之后,发送方就会停止发送,只发零窗口探测。这与线路无关。 (研发团队·客户端开发)
查看含图示的完整版症状词典