停服不是简单地把进程杀掉。对游戏服务器来说,停服时可能还有玩家在副本里,拍卖正在结算,邮件正在发放,排行榜正在锁榜,数据库里还有未落盘数据。粗暴停服看起来省事,实际上会把大量可控状态变成异常状态。第二天开发和客服面对的,可能就是副本次数丢失、奖励没发、玩家卡在线、活动结算不一致。
优雅停服的第一步是关闭入口。网关停止接受新连接,登录服务返回维护提示,匹配服务停止创建新房间,活动服务停止进入高风险玩法。已经在线的玩家可以继续完成短流程,但系统不再接纳新的复杂流程。这个阶段的目标是让负载只减少不增加,为后续排空创造条件。
入口关闭要分层。登录入口可以先关,防止新玩家进入;商城支付入口可能需要更早关闭,避免停服过程中产生新订单;普通聊天可以晚一点关闭,方便玩家接收通知;后台管理入口则要保留给运维和客服。不同入口有不同风险,不能只靠一个全局维护开关。
玩家通知要提前且一致。公告、游戏内倒计时、登录提示、客户端弹窗、社群公告,时间要统一。玩家最反感的是公告说还有五分钟,实际已经被踢下线;或者服务器已经维护,客户端却只显示网络错误。服务端应该提供维护状态接口,让客户端能展示明确原因和预计恢复时间。
第二步是排空进行中的流程。短局房间可以等待自然结束,长局副本可以保存进度并把玩家迁回安全点,匹配队列可以取消并返还消耗,交易和拍卖可以暂停新操作但完成已确认流程。排空不是无限等待,每类流程都要有最大等待时间。超过时间后,进入预设兜底策略。
房间服停服尤其要谨慎。正在战斗的房间是否允许打完?如果停服窗口只有十分钟,而副本最长三十分钟,是否在维护前半小时就禁止进入?这些规则要由服务端开关配合运营公告。不要等到维护时间到了再强杀房间,那样玩家体验一定差。更好的方式是提前进入“只出不进”状态。
第三步是保存状态。在线玩家数据、房间快照、队伍状态、临时活动进度、待发奖励、消息队列 offset,都要在停服流程中 flush。保存要有超时和失败记录。不能因为一个玩家数据保存失败,让整个停服脚本卡住;也不能忽略失败。失败项应进入修复队列,重启后继续处理或交给客服后台。
后台任务也要有停服协议。邮件批量发送、排行榜结算、活动统计、数据归档,如果正在执行,应该能完成当前小批次并记录检查点。收到停服信号后,不再领取新任务,但把已领取任务处理到安全点。任务系统如果直接被 kill,重启后必须能根据幂等流水继续,不会重复发奖或漏处理。
服务停服顺序要明确。一般来说,先关入口和新写入,再停业务服务,再停房间和活动,再停基础服务。数据库、缓存、消息队列、配置中心这类依赖应该最后关闭。顺序反了,上层服务还在保存数据,底层连接已经不可用,就会产生大量失败。停服脚本应该把依赖关系写清楚,而不是靠运维临时记忆。
优雅停服需要每个服务响应信号。收到 shutdown 后,服务设置 draining 状态,拒绝新请求,等待当前请求完成,flush 缓存,关闭连接,最后退出。这个过程要有最大时限。超过时限可以强制退出,但必须记录未完成事项。没有 draining 状态的服务,只能被外部粗暴杀掉,谈不上优雅。
在线状态清理也很重要。停服时玩家连接会全部断开,但这不代表玩家应被记录为异常掉线。在线状态服务应知道这是维护下线,避免触发掉线惩罚、逃跑判定或异常告警。重启后也要清理旧 session,防止玩家登录时提示“账号已在线”。
维护期间的支付回调要特别处理。玩家可能在停服前发起支付,渠道回调在停服中到达。支付入口关闭不代表回调不会来。支付服务应保留最小可用能力,或者让回调进入可靠队列,开服后继续处理。任何和真实货币相关的流程都不能因为停服简单丢弃。
重启后的检查和停服同样重要。服务进程起来,只说明程序启动了,不代表游戏可开放。需要检查数据库连接、缓存状态、消息队列积压、配置版本、未完成任务、在线状态残留、关键错误日志、活动开关状态。开服前最好有自动 checklist,所有关键项通过后再打开入口。
演练是优雅停服最容易被忽略的一环。很多团队只在真实维护时第一次跑完整流程,结果脚本权限、服务顺序、超时参数、通知文案都有问题。应该在测试环境定期演练,甚至在低峰期做小范围正式演练。停服流程和备份恢复一样,不演练就不能假设它可靠。
优雅停服的本质是尊重系统里的进行中状态。它把一次硬中断变成受控迁移:不再接入新玩家,处理完能处理的流程,保存必须保存的数据,清楚记录未完成事项,然后按顺序关闭依赖。做得好,玩家只会觉得服务器按公告维护;做得差,维护结束才是真正事故的开始。
停服前的只出不进
优雅停服最好从维护前就开始,而不是维护时间到了才执行。比如计划 23:30 停服,23:00 起禁止进入预计超过 30 分钟的玩法,23:15 起停止新匹配和新副本,23:25 起关闭商城购买和高价值交易,23:30 正式断开入口。这个过程叫只出不进:已经在流程里的玩家尽量自然结束,新玩家不再进入可能被中断的流程。
只出不进需要服务端开关支持。客户端隐藏入口只是体验优化,服务端必须拒绝新请求。否则旧客户端、脚本或网络延迟仍可能进入玩法。拒绝时要返回明确错误码,比如 maintenance_draining,而不是普通失败。客户端根据错误码展示维护提示,玩家更容易理解。
不同玩法的提前关闭时间不同。三分钟竞技可以维护前五分钟关闭,四十分钟副本可能要提前一小时关闭,跨服战场甚至需要当天不再开启新轮次。这些时间应由玩法配置控制,不要写死在停服脚本里。
数据保存的优先级
停服窗口有限,不可能无限等待所有事情完美完成。服务端要区分数据优先级。玩家资产、付费订单、战斗结算、邮件发放属于最高优先级,必须尽力完成或进入可靠恢复队列。聊天缓存、临时红点、部分统计可以延后或丢弃。优雅停服不是所有数据都同等重要,而是关键数据不能丢。
保存玩家数据时,最好有批次和进度。比如当前在线 5 万玩家,按分片并发 flush,每批记录成功数和失败数。失败玩家写入 retry 表,开服后继续保存或检查。停服脚本输出“保存完成”必须有真实含义,而不是简单等待固定秒数。
内存状态也要考虑。房间服中有未结算掉落,活动服务中有未刷新的进度,排行榜服务中有未落盘快照。每个服务都应该实现自己的 shutdown hook,把关键状态写到持久层或可靠队列。统一停服系统只负责触发和观察,不能替每个业务理解内部状态。
维护中的最小可用服务
停服后,并不是所有服务都必须完全关闭。支付回调、官网状态接口、维护公告、客服后台、补偿任务可能仍要保留最小可用能力。尤其是支付回调,渠道不会因为你维护就停止发送。支付服务可以进入 maintenance mode:不允许新下单,但接收和记录回调,待开服后完成发货。
登录服务也可以保留维护响应。玩家打开游戏时,服务端返回维护状态、预计开服时间和公告链接。这样客户端能展示明确提示。如果登录服务完全不可用,玩家只会看到网络错误,社群里很快就会出现误解。
开服前检查清单
开服不是把进程启动就结束。入口打开前,至少要检查配置版本一致、数据库迁移完成、缓存可用、消息队列积压在可接受范围内、未完成结算任务已恢复、支付回调队列正常、活动开关状态正确、在线状态表无大量残留、关键服务健康检查通过。任何一项失败,都可能在开服后放大。
检查最好自动化,输出明确结果。人工看日志很容易漏。可以有一个 open_server_check 命令,逐项检查并给出 pass 或 fail。失败项附带原因和建议。运维根据检查结果决定是否开放入口。这个工具会比口头 checklist 可靠得多。
开服也可以灰度。先开放内部账号,再开放一个小区服,再逐步打开全部区服。观察登录成功率、角色加载耗时、错误日志、支付回调、活动入口和在线人数曲线。维护后最容易出现配置不一致或缓存冷启动问题,灰度开服能把风险缩小。
停服流程要可重入
停服脚本可能执行到一半失败,比如关闭匹配成功,保存房间失败。重新执行脚本时,它应该识别已经完成的步骤,而不是重复执行产生副作用。关闭入口重复执行没有问题,发维护邮件重复执行就可能有问题。每个步骤都要么天然幂等,要么有执行记录。
状态记录可以放在运维数据库或配置中心里。步骤包括 close_login、close_matchmaking、drain_rooms、flush_players、stop_workers、shutdown_services。每步记录开始时间、结束时间、结果和错误。这样停服过程本身也可观测,出问题能知道卡在哪里。
团队协作和复盘
优雅停服不仅是技术脚本,也需要团队协作。运营负责公告和玩家预期,客服准备常见问题,开发确认风险玩法,运维执行流程,数据同学观察关键指标。维护结束后,最好复盘实际停服耗时、失败项、玩家投诉、开服错误和后续改进。停服流程会随着游戏内容变复杂,复盘能让它持续更新。
真正成熟的停服流程,会让玩家觉得维护只是短暂不可用,而不是一次数据冒险。服务器尊重每一个进行中的状态,玩家也会更愿意相信系统。
上线前的工程核对
真正把这套方案放进生产环境前,团队还需要做一次朴素但有效的核对。第一,确认关键状态都有唯一标识,能从日志里串起一次完整链路。第二,确认重复请求不会造成重复副作用,尤其是资产、奖励、排名、邮件这类玩家能直接感知的结果。第三,确认配置、开关和版本都能回滚,而不是只能向前发布。第四,确认客服或运营能查到必要证据,避免所有问题都只能找开发临时查库。
还要准备一组小规模演练。演练不需要复杂,但要覆盖真实失败:服务重启一次,消息重复投递一次,下游接口超时一次,客户端重连一次,配置回滚一次。很多设计在文档里看起来可靠,只有演练时才会暴露状态缺失、错误码不清、日志字段不够、后台按钮不可用这些具体问题。把这些问题提前暴露出来,比在线上由玩家帮你测试要便宜得多。
最后,要把边界写进团队共识。哪些数据必须强一致,哪些可以最终一致;哪些操作允许重试,哪些必须人工确认;哪些异常直接降级,哪些必须停止入口。游戏服务器开发最怕每个模块都各自理解规则。规则统一后,代码实现、运营处理和客服解释才会站在同一条线上。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。