背景:架构问题通常藏在正常路径之外
副本玩法经常处在“时间长、状态多、奖励重”的交叉点。玩家打到最后一个 Boss 时断线,服务端实例因为空房被回收;玩家重登后希望继续,系统又要防止重复领奖、重复消耗门票和复制掉落。副本进度保存与恢复架构的核心,是把可恢复状态、不可恢复过程和奖励边界分清楚。
早期副本常常只在内存里保存状态,实例销毁就只剩最终结果。如果玩家中途断线,服务端只能让他从头来,体验差;如果为了体验直接补偿奖励,又容易被利用。还有一种做法是每秒全量保存副本状态,成本高且恢复后仍然不知道哪些奖励已经结算。
推荐采用检查点模型。副本在关键阶段写入 progress checkpoint,例如入场消耗、Boss 击杀、机关完成、奖励锁定。断线恢复时根据最后一个安全检查点重建实例或发放可恢复入口。奖励发放必须基于 reward claim state,而不是副本内存。
架构视图
flowchart TD
E[进入副本] --> C1[检查点: 门票已消耗]
C1 --> P[副本进行中]
P --> C2[检查点: 阶段完成]
C2 --> B[Boss战]
B --> C3[检查点: 奖励锁定]
C3 --> R[领奖状态机]
P --> D[断线/实例销毁]
D --> X[按最近安全检查点恢复]
这张图只展示主干流程,实际落地时还要补上权限、审计、监控、配置版本和异常补偿。画架构图的意义不是让系统显得复杂,而是让团队在写代码前确认几个问题:状态在哪里被创建,在哪里被修改,失败后谁负责收尾,玩家能看到什么结果,客服和研发能不能在事后还原过程。
设计要点 1
检查点要少而准。每个怪物血量都保存没有必要,但阶段完成、门票消耗、关键机关、Boss 死亡、奖励锁定必须保存。检查点越贴近产品承诺,恢复越容易解释。比如“已击杀二号 Boss,可从三号前继续”比“恢复到 18 分 32 秒状态”更稳定。
设计要点 2
恢复入口要有有效期和次数限制。副本进度不能无限保留,否则会积累大量历史状态,也可能被玩家用于跨版本套利。可以根据副本类型设置 30 分钟、24 小时或赛季内有效。恢复次数也要限制,避免反复试错刷随机结果。
设计要点 3
奖励边界必须独立。Boss 掉落一旦锁定,就写入领奖状态;玩家是否已领取、是否已发送邮件、是否已补偿,都由领奖状态机管理。副本实例恢复不应重新随机掉落。否则断线恢复会变成复制奖励的入口。
设计要点 4
实例重建不等于完全还原。很多临时状态可以重置,例如小怪巡逻位置、非关键机关动画、短期 Buff;核心进度和奖励边界必须还原。把恢复目标定义为“继续玩法承诺”,而不是“逐帧还原现场”,成本会合理很多。
设计要点 5
跨服失败要有托底。副本服崩溃或跨服网关断开时,主服至少要知道玩家处于哪个 dungeonRunId、最后检查点和门票状态。玩家回到主服后可以选择恢复、退还门票或等待修复,不能只显示副本不存在。
数据模型与状态边界
这类模块不要只围绕一张数据库表设计。更稳妥的方式是先定义领域对象、命令、事件和读模型。领域对象负责维护权威状态,命令表达一次业务意图,事件记录已经发生的事实,读模型服务客户端展示和运营查询。这样做会比直接增删改查多一些代码,但当系统进入长线运营后,状态边界会清楚得多。
每一次关键状态变化都应该带上版本号和来源。版本号用于并发控制和缓存失效,来源用于审计和问题定位。比如一次来自活动配置的变更、一次来自玩家操作的变更、一次来自补偿脚本的变更,处理策略可能完全不同。没有来源字段,线上排查时只能翻调用链猜测。
状态边界还决定了能否拆服务。如果一个模块必须同时读写十几个系统的内部表,它后面很难独立扩容,也很难做灰度。相反,如果它只暴露命令接口和事件输出,其他系统通过读模型或订阅事件协作,拆分和回滚都会简单很多。
失败路径与补偿策略
游戏服务器必须把失败当成常态。玩家会断线,客户端会重试,网关会重连,数据库会超时,配置会临时回滚,外部平台会延迟回调。架构设计如果只覆盖成功路径,测试环境里看不出问题,线上高峰时会集中爆发。
建议为每个核心动作定义四类结果:成功、业务拒绝、可重试失败、不可自动处理失败。成功进入正常事件流;业务拒绝返回明确原因,例如条件不满足或状态已变化;可重试失败进入带幂等键的重试队列;不可自动处理失败进入死信或人工工单。不要把所有异常都包装成系统繁忙,否则调用方无法采取正确动作。
补偿策略要和幂等设计绑在一起。补发奖励、恢复状态、重放事件、重新生成读模型,都必须能识别之前是否已经执行过。没有幂等键的补偿脚本,是很多二次事故的来源。
性能与容量估算
性能设计要从业务峰值倒推,而不是上线后再看机器报警。先估算单玩家、单房间或单账号在高峰场景下的请求频率,再乘以同时在线和活动放大系数。很多系统平时负载很低,一到赛季结算、限时活动、主播开黑或版本更新,就会出现数倍甚至数十倍尖峰。
容量估算时要分清 CPU、内存、网络、存储和外部依赖。一个模块可能 CPU 很轻,但写放大严重;也可能数据库压力不大,但网关推送带宽很高。只看 QPS 容易误判。建议在压测脚本里模拟真实操作序列,而不是只压单个接口。
为了防止局部热点,需要准备限流、批处理、合并、异步化和降级。降级不是失败,而是提前定义较低质量但可接受的服务形态。例如延迟刷新、摘要展示、只读模式、排队等待、转邮件托底。
观测与排障
观测指标至少分三层。第一层是玩家结果,例如成功率、拒绝率、延迟分位、可见错误、投诉量。第二层是系统状态,例如队列积压、缓存命中、回源耗时、事件延迟、重试次数。第三层是证据链,例如请求 ID、玩家 ID、配置版本、策略版本、状态版本、裁决原因。
排障面板要支持按区服、玩法、客户端版本、配置版本和时间窗口切分。游戏事故很少平均发生,通常集中在某个活动、某个灰度桶、某个地图或某个玩家群体。没有这些维度,平均值会把问题掩盖。
日志不要只记录错误。对资产、结算、处罚、关系、进度这类高价值变更,成功日志同样重要。玩家争议发生时,研发需要证明系统当时做了什么,而不是只知道没有报错。
上线与回滚建议
上线时尽量先走影子模式或小流量灰度。影子模式可以让新逻辑计算结果但不影响玩家,用来观察和旧逻辑的差异;小流量灰度可以验证真实玩家行为和边界场景。直接全量切换只适合低风险展示功能,不适合影响状态和资产的核心模块。
回滚路径要提前演练。代码回滚、配置回滚、开关熔断、读模型重建、事件重放、人工补偿分别解决不同问题。一次事故中常常需要组合使用。没有演练的回滚,在真正事故时会变成新的风险。
上线后至少观察一个完整业务周期。如果是日常任务,要跨过一次日重置;如果是排行榜,要跨过一次结算;如果是副本,要覆盖断线恢复和奖励领取。只看发布后十分钟没有报错,不能说明系统可靠。
常见误区
第一,把客户端表现当成服务端事实。客户端可以预测、缓存和合并,但服务端必须有自己的权威状态和裁决理由。
第二,把平均延迟当成体验指标。游戏玩家感知的是尾部延迟、连续失败和关键动作是否被正确处理。
第三,把配置灵活性当成安全性。配置越灵活,越需要校验、灰度、版本和回滚。
第四,把重试当成补偿。没有幂等和状态检查的重试,只是在放大错误。
第五,把后台工具当成内部小功能。运营、客服、研发都会在压力下使用这些工具,权限、审计和结果反馈必须按生产系统标准设计。
工程落地细节
副本运行 ID 要贯穿全链路。门票消耗、实例创建、检查点保存、奖励锁定、断线恢复、邮件托底都使用同一个 dungeonRunId。没有这个 ID,客服只能看到零散记录:门票少了、实例没了、邮件发了,却串不成一次完整过程。
保存检查点时要区分同步确认和异步归档。门票消耗、阶段完成、奖励锁定属于强检查点,必须确认写入后才能继续关键流程;小怪状态、临时掉落、机关动画可以异步归档或不保存。把所有状态都强写会拖慢副本,把所有状态都异步又会丢承诺。
恢复时还要处理版本变化。玩家周一打到一半,周二副本配置热更了。系统应记录 runConfigVersion,恢复时优先使用原版本;如果原版本不可用,要明确走补偿或重开策略,而不是悄悄用新版本继续。
线上案例化复盘
一次跨服副本故障中,副本服重启后实例内存丢失,但主服只知道玩家门票已经扣除,不知道打到哪一层。最后只能全量退票,影响了正常已经通关的玩家。后来团队把阶段检查点写回主服,并在奖励锁定前后各写一次状态。再遇到副本服故障时,主服能区分三类玩家:未完成退票,已锁定奖励走邮件托底,已领取只修复展示状态。补偿范围从全服变成精确到 dungeonRunId。
交付检查清单
副本恢复能力要在故障演练里验收,而不是只靠正常测试。可以在门票消耗后、阶段完成后、奖励锁定前、奖励锁定后分别杀掉副本进程,观察玩家重登后得到的入口、门票、进度和奖励是否符合预期。还要检查恢复入口过期后的处理,以及配置版本不存在时的补偿策略。只要能把玩家分到清晰的恢复类别,客服处理就会轻很多。
接口契约补充
接口契约要把调用方能依赖的内容写清楚:请求字段哪些必填,幂等键如何生成,成功后状态何时可见,失败是否允许重试,客户端应该展示什么文案键。很多线上误会不是服务端没有处理,而是调用方不知道这个接口到底承诺什么。把契约写进文档和自动化用例,比口头约定可靠。
小结
副本进度保存与恢复架构的价值,不在于把所有情况都抽象成一个万能平台,而在于把高频路径、失败路径和争议路径都设计清楚。玩家看到的是一次点击、一次移动、一次领取或一次切换,服务端背后需要处理顺序、状态、版本、并发、补偿和证据。
如果团队资源有限,建议先做三件事:明确权威状态,补齐幂等和版本,建立能回答争议的日志。做到这三点,即使系统还不够优雅,也具备持续演进的基础。后续再加入灰度、自动化修复、容量模型和可视化工具,架构会自然长成,而不是被事故一次次推倒重来。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。