为什么需要热更新
在线游戏服务端的更新不可避免,但停机维护会让玩家流失、口碑受损。热更新(不中断服务完成更新)因此成为游戏服务端架构的核心能力。它分两个层次:
- 配置热更新:改数值表、活动配置、掉落率——配置/数据库实时加载,服务端监听变更即可;
- 逻辑热更新:改业务代码、修 Bug、加功能——这才是真正的难题。
无状态服务:滚动更新
无状态服务的热更新相对简单,标准流程:
- 新版本编译出新可执行文件;
- 启动新进程,负载均衡器逐步把流量切过去;
- 旧进程流量归零后关闭。
整个过程对客户端透明,服务持续可用。这也是 Go 服务最常见的部署方式。
有状态服务:状态迁移的难题
游戏服务进程里缓存着大量玩家状态,直接迁移整批数据代价惊人:
| 网络类型 | 带宽 | 1GB 状态迁移耗时 |
|---|---|---|
| 万兆网络 | 10Gbps | 0.8–1.2 秒 |
| 千兆局域网 | 1Gbps | 8–10 秒 |
| 典型云服务 | 500Mbps | 16–20 秒 |
| 普通互联网 | 100Mbps | 80–100 秒 |
典型规模:1000–10000 个玩家 × 每玩家约 1MB = 1GB–10GB 缓存。就算万兆网也要 1 秒,玩家明显感知卡顿。结论:整批迁移不可行,必须细化迁移粒度。
方案:玩家级精细化迁移 + Router 服务
以单个玩家(约 1MB)为迁移单元,普通网络下只需几毫秒到几十毫秒,单个玩家几乎无感知。引入 Router 服务作为核心协调组件:
- Router 维护
userId → serverId的映射; - 迁移时把该 userId 标记为”迁移中”,暂停处理其请求;
- 请求暂存到消息队列(不丢失);
- 把该玩家状态迁移到新服务进程;
- 更新路由映射指向新进程;
- 恢复处理该玩家请求。
每个玩家只经历几十毫秒的中断,基本无感知;不同玩家可以并行迁移,整体更新窗口大幅缩短。
技术实现要点
- 状态序列化:高效的序列化机制(如 Protobuf)减小迁移数据量;
- 消息队列:迁移期间请求可靠暂存,保证不丢消息;
- 一致性:迁移前后状态校验,防止”旧进程还在改、新进程已接管”导致的状态分叉;
- 回滚:迁移失败自动回滚到旧进程,请求继续由旧进程处理;
- 监控:实时观测迁移进度、成功率、单玩家中断时长。
总结
游戏服务端热更新的本质:无状态靠滚动,有状态靠细粒度迁移。基于 Router 的玩家级迁移架构,用”单玩家几十毫秒中断”换取整个服务的不停机更新,是大规模在线游戏的主流选择。
