游戏卡顿白皮书 › 只有部分人遇到的问题
刚进入时集中到达的出现信息丢失 Initial spawn burst lost (unreliable channel, receive buffer, fragmentation)
原因 ID pt-spawn-burst · 主责 研发团队·服务器开发 · 配合 研发团队·客户端开发
在含图示和实验的完整版中打开此卡片 →
进入场景的那一刻,服务器会一次性发出周围几十到几百个实体的出现信息。如果用不可靠(unreliable)通道发送,或者客户端在加载中读不了 socket、接收缓冲区溢出,就会丢掉一部分,而且不会再来。
起因 刚进入时出现信息在极短时间内集中到达 → 结果 正在加载的客户端读 socket 读得晚,OS 接收缓冲区溢出;或者大的 UDP 包被分片,只丢一个分片整个包就没了。不可靠通道也不会重发 → 画面表现 只有加载慢的那个客户端缺了几只 NPC。离开视野再回来就能看到
- 症状
- 隐身/幽灵实体
- 因素
- 丢包
- 谁会遇到
- 双开时只有一个客户端, 只有我
- 何时出现
- 刚登录/维护结束后, 移动中/切换地图时
- 负责方
- 主责 研发团队·服务器开发 · 配合 研发团队·客户端开发
- 研发团队要做的事
- 服务器:出现/离开通知一定要用保证重传的可靠通道,初始信息分批发送。客户端:在与加载分开的线程里接收,加大接收缓冲区。
- 数值参考
- PC 的 UDP 接收缓冲区默认值因 OS 而异,大多为几十到几百 KB。进入人多的城镇时,出现信息量超过这个值,只要因加载短暂读不了 socket 就会溢出。
- 监控图上
- 开服/维护后激增 · 刚进入时的接收量,出现通知缺失数
- 查看位置
- 对比服务器在进入后发出的出现通知数与客户端收到的数量,并查看是用哪个通道(可靠、不可靠)发送的。在服务器侧抓包,看进入后发给该玩家的数据量和分片包(Wireshark 过滤器 ip.flags.mf == 1 || ip.frag_offset > 0)
- 确认依据
- 收到的数量比发出的少,缺的集中在进入后扎堆的那一段,且用的是不可靠通道或大包被分片。在加载慢的那个客户端上更常见
- 排除依据
- 发出和收到的数量相同却看不到,是收到后丢弃(“加载中到达的出现通知被丢弃”)或视野计算的问题。与是否刚进入无关、随时都会缺,是线路丢包
- 确认手段
- 需要游戏服务器/客户端的日志和指标
出处
- RFC 8085: UDP Usage Guidelines IETF
分片的包只要丢一个分片,整个包就没了 - UDP vs. TCP Gaffer On Games
UDP 不保证送达和顺序,丢了的包要自己检测并重发 - Socket.ReceiveBufferSize Property Microsoft
socket 接收缓冲区的默认大小因 OS 而异 - Display Filter Reference: Internet Protocol Version 4 Wireshark
用 ip.flags.mf(More fragments)、ip.frag_offset(Fragment Offset)过滤出分片的 IP 包
相关原因
同一层:只有部分人遇到的问题
其他层中同样导致“隐身/幽灵实体”的原因
查看含图示和实验的原卡片