游戏卡顿白皮书 › L9 服务器游戏进程
游戏线程中的同步调用 Synchronous DB / file I/O on the game loop
原因 ID sp-sync-call · 主责 研发团队·服务器开发
在含图示和实验的完整版中打开此卡片 →
tick 中途等待 DB 响应或文件写入时,等多久,服务器上整个游戏的运行就停多久。
起因 在 tick 内等待 DB 查询或存盘、写日志、调用外部 API → 结果 DB 耗时 100 ms,tick 也停住 100 ms → 画面表现 每当 DB、磁盘变慢,整个野外就顿一下
- 症状
- 卡住, 一卡一卡
- 因素
- 停顿
- 谁会遇到
- 特定地点/分线, 全服
- 何时出现
- 做特定操作时, 偶尔随机
- 负责方
- 主责 研发团队·服务器开发
- 研发团队要做的事
- 慢操作(DB 查询和存盘、写日志、调用外部 API)全部交给异步处理,结果在下一个 tick 应用(只加超时的话,等待期间照样停住)。
- 数值参考
- 即使同一数据中心内 DB 往返只要 0.5 ms,一个 tick 调用 100 次也要 50 ms,一下就用光 20 tick 的全部预算。
- 监控图上
- 偶发随机尖峰 · 服务器 tick 耗时、DB 查询延迟
- 查看位置
- 把 tick 耗时曲线和 DB 查询延迟(slow query log 等)、磁盘延迟放在同一时间轴上看。没有 tick 指标时,用 bcc offcputime -p 看游戏线程在哪里等待
- 确认依据
- tick 冲高的时刻与 DB、文件延迟冲高的时刻重合,游戏线程的等待时间集中在接收 DB 响应、写文件的调用栈上
- 排除依据
- DB、磁盘延迟平稳而 tick 冲高,看 GC 停顿或锁竞争
- 确认手段
- 需要游戏服务器/客户端的日志和指标
出处
- Designs, Lessons and Advice from Building Large Distributed Systems Google
LADIS 2009 主题演讲(Jeff Dean)。同一数据中心内往返约 0.5 ms(500,000 ns) - ASP.NET Core Best Practices Microsoft
数据访问、I/O、耗时长的操作用异步调用;同步阻塞调用会导致线程池耗尽和响应延迟 - Demonstrations of offcputime, the Linux eBPF/bcc version IO Visor
按调用栈汇总线程停住、离开 CPU 的时间(off-CPU),-p 指定进程
相关原因
同一层:L9 服务器游戏进程
其他层中同样导致“卡住”的原因
查看含图示和实验的原卡片