游戏卡顿白皮书 › 按症状查找
慢动作:24 个原因及负责方
又称:整个世界变慢、什么都慢吞吞
在含图示的完整版症状词典中打开 →
所有东西都动得很慢,技能施放和怪物移动像被拉长了一样。视服务器设计而定,也可能速度不变,表现为一卡一卡或瞬移。
同一区域的所有人一起变慢,通常出现在人多的地方。
服务器没能按时跑完 tick。线路没问题,所以在游戏外测的 ping 不变;游戏内的 ping 如果包含服务器处理的排队时间,可能会略有上升。排查人数暴增、视野计算、广播、内存不足。
导致此症状的原因
L1 客户端游戏进程
- 固定时间步长追赶失控: 停顿一次之后集中补算积压的计算,又因为这些计算再次积压。 (研发团队·客户端开发)
L5 数据中心网络设备
L7 服务器操作系统(内核)
- 线程过多与上下文切换: 线程数远多于核心数时,操作系统光是让它们轮流运行就要耗掉大量 CPU。 (研发团队·服务器开发)
- 容器 CPU 限流(CFS 配额): 给容器设置 CPU 上限后,一旦在规定周期(通常为 100 ms)内用完配额,周期剩下的时间里就会被强制停住(限流)。 (运维团队·系统运维)
- 服务器电源管理(C-state/调频)导致延迟跳变: 空闲的 CPU 核心为了省电会进入深度省电状态(C-state),频率也会降低。数据包或定时器到来时,唤醒和升频都需要时间,处理小数据包时就会多出一段延迟。 (运维团队·系统运维)
- 定时任务: 每天在同一时刻运行的日志压缩、备份、安全扫描会占用 CPU 和磁盘。 (运维团队·系统运维)
- OS/内核/驱动/固件更新后的性能变化: 游戏代码没变,服务器的 OS、内核、驱动、固件更新之后却开始变慢。更新可能会改变默认值、调度器、CPU 漏洞缓解措施(mitigations)和驱动行为。 (运维团队·系统运维)
L8 Socket 与协议
- 慢客户端导致的阻塞发送: 某个线路慢的玩家发送缓冲区已满时,如果用阻塞方式(缓冲区腾出空间之前调用不返回的发送)发送,服务器线程就会一直等这一个人。 (研发团队·服务器开发)
- 阻塞 I/O 模型: 等一个 socket 时线程就干不了别的事,这种结构下人越多,整体就越慢。 (研发团队·服务器开发)
L9 服务器游戏进程
- Tick 超出预算: 一个 tick 内要做的事超出预算时,服务器的 tick 周期会被拉长,整个区域都会变慢或一卡一卡。 (研发团队·服务器开发)
- 视野(AOI)计算激增(N²): 所有人两两比较谁能看到谁,人数变成 10 倍时,计算量就会变成 100 倍。 (研发团队·服务器开发)
- 单线程区域过载(热点): 每个区域由一个线程负责的架构下,人一旦聚到一处,只有那一个核心会跑到 100%。 (研发团队·服务器开发)
- 寻路计算激增: 几百只怪物同时追着玩家计算路径时,会占用大量 CPU。 (研发团队·服务器开发)
- 战斗集中在单一目标(世界 BOSS): 几百人同时打一个 BOSS 时,这一只 BOSS 的计算全压在一处,命中信息还要发给所有看得到的人。 (研发团队·服务器开发)
- 实体堆积(未清理的物品/召唤物): 本该消失的地面物品、召唤物、已结束的定时器没有被清理而不断堆积,服务器开得越久,每个 tick 要做的事就越多。 (研发团队·服务器开发)
L10 内存
- 内存泄漏: 没有释放的内存一点点累积,几天后引发 GC 失控、swap 或进程被强制终止。 (研发团队·服务器开发)
- GC 颠簸(堆余量不足): 存活数据接近堆上限时,GC 即使运行也几乎回收不到东西,于是不停地反复执行。 (研发团队·服务器开发)
- swap: 内存不足时,OS 会把一部分内存换出到磁盘。之后每次用到这部分内存,都要等待比内存慢 1,000 倍以上的磁盘。 (运维团队·系统运维)
- 缓存未命中: 数据分散在内存各处时,CPU 每次都要到较慢的内存里取数据并等待。 (研发团队·服务器开发)
- 内存碎片: 反复分配和释放会把空闲空间切得很碎,进程占用的内存会远多于实际使用量。 (研发团队·服务器开发)
- NUMA 远端内存: 在装有两颗 CPU 的服务器上,使用挂在另一颗 CPU 上的内存,访问会变慢。 (运维团队·系统运维)
L11 磁盘
- 云盘突发积分耗尽: 部分云盘和小规格实例有突发积分,可以短时间超过基准性能运行。繁忙时段一长、积分耗尽,速度就会突然下降。 (运维团队·系统运维)
L13 服务器架构与运维
- 弹性伸缩延迟: 人一多就会自动增加服务器,但准备要几分钟,这段时间现有服务器处于过载状态。 (运维团队·系统运维)
- 脚本/机器人过多: 机器人发请求的频率远高于真人,会吃掉服务器的处理能力。 (研发团队·服务器开发)
查看含图示的完整版症状词典