一场没有结论的评审会
先从一个很常见的会议说起。
某工作室准备做一款新的竞技游戏。客户端主程说,必须上帧同步,不然技能手感不对;服务端主程说,帧同步的重连和观战会拖垮进度,状态同步更稳;制作人问,那到底要几个人、几个月;运营问,上线后能不能改数值、能不能加新英雄;老板问,为什么上一款 SLG 的服务端不能直接复用。
两个小时后,会议记录上写着“同步方案待定”。没有人不同意“要低延迟”,也没有人反对“要能扩展”。分歧不在目标,而在每个方案背后的代价没有被摆到同一张桌子上:帧同步把成本转移到确定性和重连,状态同步把成本转移到带宽和服务器,复用 SLG 的后端把成本转移到玩法改造和团队认知。
这类会议不会因为再多读一篇“帧同步原理”而结束。它需要的是另一套语言:把品类事实翻译成架构约束,把每个选项的代价写成可比较的条目,把决策和它的失效条件一起记录下来。
这套书想提供的,就是这套语言。
已经有一套 MMO 书,为什么还要写这一套
站内已经有一套《MMO 服务器开发》四卷本,从网络与并发内核一路写到玩法系统、工具链与运维。那套书回答的是:如果今天从零做一个 MMO 服务端,具体怎么实现。
本书回答的是另一个问题:在给定品类、规模、团队和预算的前提下,为什么选这个架构,代价是什么,什么时候应该换。
两者的差别可以用一张表说清楚。
| 问题 | 《MMO 服务器开发》 | 本书 |
|---|---|---|
| 连接怎么建 | epoll、协议编解码、心跳与重连的实现 | 长连接、短连接、WebSocket、QUIC 在什么品类下值得 |
| 房间怎么管 | 房间对象的生命周期与消息循环 | 大厅与房间为什么分开、分配器该防住哪几种故障 |
| 地图怎么切 | AOI、九宫格、场景管理的代码 | 按玩家、按格子、按区块三种切法的延迟与合规代价 |
| 战斗怎么算 | 技能、Buff、结算的领域实现 | 帧同步与状态同步的选择依据、权威应该放在哪一层 |
| 怎么上线 | 部署、监控、运维脚本 | 部署单元怎么切、故障域多大、爆炸半径怎么算 |
所以本书刻意不重写网络库,不展开 AOI 实现,也不教 Go 语法。遇到这些题目,正文会用一段话概括,然后用站内链接指回《MMO 服务器开发》的对应章节。本书把篇幅留给决策:备选方案、判据、代价、失败模式,以及“什么条件下这个决定应该被推翻”。
三个反复出现的问题
写这套书之前,我整理了近几年游戏服务端项目里反复出现的争论。它们大多可以归到三个问题。
问题一:品类到底决定了什么
“游戏服务端”不是一个同质的领域。5v5 竞技、全球同服 SLG、休闲小游戏、开放世界,对服务端的要求几乎相反:
- 竞技要求帧稳定和公平,宁可牺牲单局成本;
- SLG 要求世界持久和跨区一致,宁可接受秒级延迟;
- 休闲要求上线快、成本低,宁可先接受单体;
- 开放世界要求无缝和可扩展,宁可把一致性切到边界上。
品类不是标签,它是一组产品事实:同时在线人数、单局时长、是否共享世界、是否实时、是否跨区、状态规模、更新频率。这些事实会一步步压缩拓扑的可行域。本书卷一的核心任务,就是把这条推理链写清楚,而不是给出一张“最佳架构”排名。
问题二:状态放在哪里,成本就在哪里
游戏服务端与普通后端最大的差别,是它长期持有大量有状态对象:房间、场景、玩家、行军、战斗。状态放在哪里,决定了重启会丢什么、扩容要搬什么、故障会传染多远。
把状态全放内存,延迟最低,但重启和迁移最贵;全部外置到 Redis 或数据库,恢复容易,但每帧都要付一次网络往返;分区归属能兼顾两者,但要求路由、租约和迁移协议都写对。
本书不会说“应该外置”或“应该内存”。它会给出判据:这份状态能不能丢、丢失窗口多大、迁移时谁来拒绝旧写入、扩容时哪些房间必须原地不动。卷一的第 4 章、第 11 章,以及后续卷二的容量与高可用章节,都会回到这个问题。
问题三:边界画错,后面全是补丁
很多架构问题不是性能问题,而是边界问题:大厅服务顺手改了房间状态,网关承担了业务规则,战斗服直接写经济账本,平台服务把三款产品的配置混在一张表里。边界一旦模糊,后面每加一个功能都要跨三个团队确认。
边界不是画在 PPT 上的框,它要能落到代码和部署上:模块之间允许哪些依赖、数据由谁独占写入、接口的幂等责任在谁、故障时哪一方先降级。本书会把每个边界写成可检查的条目,并用 Go 代码和测试把其中一部分固定下来。
北辰工作室与三款产品
为了让决策有具体对象,本书虚构了北辰工作室和它的三款产品。它们由多个真实项目里的常见问题拼合而成,不对应任何一家公司,也不指向任何具体的个人。
| 产品 | 品类 | 架构关键词 | 首要矛盾 |
|---|---|---|---|
| 《裂隙战场》 | 5v5 竞技 | 大厅 + 房间、tick、专用服、观战回放 | 帧稳定性与公平性 |
| 《群岛纪元》 | SLG | 全球同服、大地图分片、异步结算、离线推进 | 全球延迟与结算一致性 |
| 《泡泡工坊》 | 休闲小游戏 | 无状态大厅 + 有状态房间、轻量后端 | 上线速度与成本上限 |
平台侧统一为 northstar-platform:账号、支付、匹配、社交、排行榜、邮件、配置、数据与 GM。平台与产品之间的契约,会在卷四展开。
三款产品会反复出现在各个章节里。同一个问题,它们给出的答案往往不同:连接选型不同,状态归属不同,部署单元不同,发布节奏也不同。这种对照比任何“最佳实践”清单都更能说明:架构选择的起点是产品事实,不是技术偏好。
全书四卷
本书共四卷,每卷独立成册,又按顺序递进。
| 卷 | 主题 | 回答的问题 |
|---|---|---|
| 卷一 | 品类、状态与拓扑 | 为谁做架构?品类如何压缩拓扑的可行域?状态、时间、连接、权威放在哪? |
| 卷二 | 核心系统与契约 | 账号、匹配、房间、战斗、经济、社交、排行榜等核心系统如何切分与约定? |
| 卷三 | 规模化、全球化与成本 | 单区跑通之后,如何扩展到大区、全球、百万在线,并把成本算清楚? |
| 卷四 | 平台化与架构治理 | 多产品如何共享平台?架构决策如何评审、演进和治理? |
你现在读到的是卷一《品类、状态与拓扑》。它不追求覆盖所有系统,而是先把最底层的四个变量——品类、状态、时间、连接——讲透,再进入权威、竞技、SLG、休闲、开放世界五类具体形态。卷一只划边界,不展开核心系统的实现;那些留给卷二。
本书的四个立场
立场一:先讲品类,再讲架构
脱离品类的“高并发架构”“微服务最佳实践”没有意义。一个日活两万的休闲游戏上微服务,和一个百万在线的竞技游戏坚持单体,可能是同样错误的决定。本书的每一组方案都会先列出产品事实,再讨论拓扑。
立场二:决策必须留下代价
只说“我们选了 A”不够,还要写清楚:为什么不选 B,A 在什么条件下会失效,失效时怎么退出。本书大量使用 ADR 的结构,但不是为了套模板,而是为了强迫作者把假设和退出条件写出来。
立场三:数字要有口径
本书出现的延迟、吞吐、在线数、成本,只要标注“示例值”,就表示它是用来说明数量级或取舍关系的,不是某次 benchmark 的结果。标注“本机实测”的数字,必须能追溯到命令、环境和输出。没有口径的数字,比没有数字更危险。
立场四:关键结论要能跑
架构书很容易停留在框图。本书要求每一节至少交付一项可验证的东西:一段能编译的 Go 代码、一组表驱动测试、一份可执行的检查清单,或者一次带命令和输出的测量。代码统一放在 gsarch-lab 中,按 L1/L2/L3 标注可运行级别。卷一以 L1 为主,不声称跑过本机没有的环境。
适合谁读,不适合谁读
这本书适合:
- 正在做技术选型或架构评审的游戏服务端工程师;
- 从普通后端转来做游戏、需要理解品类差异的开发者;
- 需要判断“这个方案要几个人、几个月、什么代价”的技术负责人;
- 想理解服务端约束、避免提出不可实现需求的产品与运营同学。
这本书不适合:
- 想找一份照抄即可的框架代码的读者——请先读《MMO 服务器开发》;
- 想学 Go 语法、网络编程基础或 Kubernetes 操作的读者;
- 希望得到“某引擎/某云厂商最佳实践”的读者——本书刻意保持引擎与云厂商中立。
关于代码、数字与环境
本书的代码以 Go 1.26.0 为基线,只使用标准库和极少数通用依赖。可运行片段统一放在 gsarch-lab,按三级标注:
- L1:纯逻辑或单包,不依赖外部进程,验收为
gofmt -l、go vet、go test; - L2:进程内端到端,使用内存适配器或本地端口;
- L3:真实依赖,例如 PostgreSQL 或 Redis,通过 Docker Compose 启动。
卷一不依赖 Kubernetes。本书不会声称在未安装的环境里跑过任何东西。涉及容器、数据库或压测的数字,如果没有附上可复现的命令和输出,就只会以“示例值/预期值”的形式出现。
最后一点关于时间:书中的产品、团队、事故和数字都是教学案例。它们足够具体,是为了让取舍看得见;它们不是对任何真实项目的描述。真正可复用的,不是某个具体参数,而是从产品事实推到架构约束、再推到验证方法的那条路径。
如果读完之后,你在下一次评审会上能多说清楚一句“这个选择的代价是什么、什么条件下我们会改”,这套书的目的就达到了。
阅读入口:《游戏服务端架构·品类、状态与拓扑》目录与学习路径 。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。