最近英雄联盟手游(LOLM)可以玩了,出于好奇,对其中一些体验到的技术点做了简单分析。

基本信息
英雄联盟手游客户端基于 Unity 研发,网络同步方案采用帧同步

帧同步快速恢复

现象:游戏后台 60 秒后回到前台,花了 14 秒快速运算追上最新帧。录像中可以明显看到整个游戏世界被加速了。

60s
后台时间
14s
恢复耗时
~3.8ms
单帧运算(60帧)

问题:若游戏已进行 20 分钟,恢复过程就需要约 4 分钟,体验相当差。两种猜测方案:

1
省略非必要计算
恢复时省略不必要的流程(比如渲染),从而减小计算量,加快恢复速度。
2
服务端快照恢复
服务端与客户端同步运算游戏逻辑(不只是广播帧操作),支持生成快照下发给客户端,客户端据此恢复,避免冗长的帧计算过程。

完全断线重连

现象:游戏进行 10 分钟时杀掉客户端进程,重新打开,从 loading 界面到能够继续游戏约 5 秒

分析1 — 对应猜测1(省略非必要计算)
假设 4 秒跑逻辑、1 秒收网络消息。逻辑以 20 帧运行,10 分钟共 1.2 万帧,单帧逻辑运算开销约 0.41ms(测试设备:iPhone XS Max)。
A
重 C# 实现 可能性高
如果是重 Lua 开发模式,0.41ms 极难达到。猜测用 C# 实现了绝大部分战斗逻辑。即便如此,0.41ms 已经非常出色。
B
多核并行 + ECS 有可能
若 CPU 8 核且充分利用多核,单帧总运算量约 3.28ms,更符合历史开发经验。要高效利用 8 核且方案可工程化,首先想到的是 ECS(面向数据编程)框架。
分析2 — 对应猜测2(服务端快照恢复)
若服务器下发了一帧的快照,客户端根据快照恢复,5 秒时间绰绰有余。快照恢复最难的部分是客户端需要 100% 还原数据,连 vector 中元素顺序都不能变。

若采用服务端同步运算方案,有以下关键要点:

1
极速结算
服务端同步运算,结算时估计 1 秒内即可得出战斗结果。若非同步运算,服务端校验就需从头跑完整局(估算约 10 秒)。实际体验中,结束动画播完到显示结算不到 1 秒。
2
外挂检测
服务端同步运算意味着可每 5 秒对关键逻辑做信息摘要并与服务器对比,检测帧同步一致性、及早发现不同步。帧同步本身对大多数外挂天然防御——客户端只上传操作,比较难防的主要是透视。
3
快照调试
快照除了恢复,对帧同步一致性排查同样有帮助。结合信息摘要对比,内网开发版甚至可以在每个函数入口都生成摘要做对比,精准定位不同步在哪个函数调用后发生——类似调试中的断点功能。
佐证:AI 托管
玩家掉线或长时间未操作后,该玩家会被 AI 托管自动游戏。至少有两种实现方案:
  • 方案1:服务端同步运算,拥有完整游戏逻辑,直接输出 AI 操作
  • 方案2:服务端不运算,AI 委托给某个正常客户端输出操作并上报
若全部玩家都掉线后 AI 仍在托管,方案2就被否定了。

双通道网络通信

游戏内双通道说明
双通道架构
客户端
消息编号去重
WiFi 通道
移动网络通道
游戏服务器
同一消息双发
1
同一消息双通道同时下发
每个包都在动态选择最优通道,以局部最优实现全局最优。代价:服务器出口流量翻倍、客户端网络 CPU 开销翻倍、消耗移动网络流量。
2
按敏感度分流
帧消息走双通道,非帧消息(聊天、地图标记等)走单通道节省流量;也可只让某个通道走单号帧来降低开销。核心:在流量开销与玩家感受之间寻找平衡点。
3
重传时启用双通道
正常时走单通道,判断需要重传时启用双通道尽最大努力重传,恢复后回归单通道。可引入"主通道"概念,实时根据网络质量动态选择。实现难度最大。
三种猜测的对比总结

流量预估:假设帧同步 20 帧/秒、10 人同场,单客户端上传流量最大约 0.48 kb/s,下载约 4.8 kb/s。10 分钟战斗下载流量约 2.8 MB。

实际测试结果:

WiFi 单通道
18 分钟游戏
5 MB
移动网络单通道
18 分钟游戏 4.2 MB
杀进程重连额外 +4.4 MB
双通道
15 分钟游戏
WiFi 4 MB + 移动 2.8 MB
关键发现
杀进程重连额外消耗约 4.4 MB 且游戏时间越长越多——此结果几乎能证明断线恢复是从第一帧重新运算到最新帧,而非基于快照恢复。结合实际流量,LOLM 的双通道方案更接近猜测2和猜测3。

客户端登录请求频率限制

登录频率限制提示

服务器处理登录请求的开销相比其他请求要大得多:

💾
数据加载:从 DB 加载玩家数据到进程,Redis/MongoDB 较快,MySQL 更慢
🌐
SDK 验证:平台账号验证通过 HTTP 处理。实测:异步 IO 处理 HTTP 约 2000 条/s,Redis 约 2 万条/s,公网通信约 1.5 万条/s
📨
登录后流量激增:活动数据、商城信息、好友列表、邮件推送等,登录后几秒内持续消耗 CPU

应对突发情况,登录排队和限制登录时间间隔都是可行方案。在架构设计上,若将不同类型请求微服务化,应对手段会更多——服务降级、弹性伸缩等。

弱网表现

TODO
原本想在 PC 上用模拟器抓包并模拟弱网来深入分析,但 LOLM 不支持 Android 模拟器。后续尝试在 PC 上搭建代理服务器,让手机经由 PC 代理再连接游戏服务器,这样就可以在 PC 端抓包和模拟弱网了。