《MMO 服务器开发》附录 C 实测数据汇总
《MMO 服务器开发》卷一附录 C:把全卷 55 条实测数字按主题收进一张可追溯的表——并发与连接、编解码、弱网、定时器、Actor 背压、幂等、AOI 带宽、端到端承载与 Go/Java 对照。每条都标出处节号、测量条件与复现命令,并附基准三纪律与不可移植声明。
category
《MMO 服务器开发》卷一附录 C:把全卷 55 条实测数字按主题收进一张可追溯的表——并发与连接、编解码、弱网、定时器、Actor 背压、幂等、AOI 带宽、端到端承载与 Go/Java 对照。每条都标出处节号、测量条件与复现命令,并附基准三纪律与不可移植声明。
《MMO 服务器开发》卷一附录 B:把「在本机把这套书跑一遍」所需的一切写成可照抄的清单。给出 Go 1.26、Colima/Docker、Temurin 21 的实测版本表,从建工作区到跑 L1、L2、Java 对照、机器人压测读 JSON 的五步复现流程,附 macOS accept backlog 与文件描述符等踩坑,以及一页可直接粘贴的命令序列。
《MMO 服务器开发》卷一附录 A:把 aegis 第 1–17 章的 internal 包收成一张速查表。给出模块地图、每包导出类型/函数/方法签名与出处节号,钉死 11 字节帧头、length = 7 + N 与全卷 14 个命令号,并附一段用 go/ast 解析源码、断言 API 清单与包内导出符号逐字一致的 L1 自检。
卷一交出的七个零件——会话表、路由表、Actor 邮箱、定时器、幂等窗口、同步模型、权威校验——到了卷二《单服架构与玩法系统》手里会长成什么。本节给出「零件 → 卷二章节 → 用途」的交接映射表,讲清为什么玩法必须先有这套地基,把卷二不写的跨服、压测、运营划给卷三与卷四,最后把整张契约编码成可测试的 Go 类型。
把卷一 17 章跑出来的实测数字汇成一张四列总表:指标、数值、成立条件、出处节号。覆盖编解码字节数与吞吐、KCP 弱网重传、时间轮挂载、邮箱背压、幂等窗口、快照与增量、AOI 带宽、goroutine 与虚拟线程、端到端 QPS 与分位,并说明为什么这些数字只能同机比、不能跨栈搬。
卷一 17 章各造了一件零件,却从没按一条主线串起来看过。本节把帧格式、会话表、路由、时间轮、Actor 邮箱、幂等窗口、同步模型与权威校验按依赖顺序排成一张「零件 → 文件 → 验收方式 → 实测结论」总账,逐章交代它解决了什么问题、留下了什么接口、下一章为什么需要它,并用五条贯穿全卷的伏笔说明这些零件如何拼成一个可裁决的世界。
站内没有 k6/wrk,压测器得自己写。本节给出 aegis 自带的机器人客户端:用错峰建连绕开 macOS 的 accept backlog 上限,登录进世界后连发请求、按往返时延汇总 QPS 与 P50/P90/P99,最后交出本机第一组真实承载数字——吞吐天花板约三千消息每秒,以及连接数继续上升后延迟如何塌方。
三个真实客户端连上网关、登录进世界、各自移动,靠一套 AOI 均匀网格做到彼此可见。本节讲清「世界是一个 actor」的事件循环、权威移动的速度校验、以及 AOI 广播只发「集合差」的做法,再用一个 L2 测试与真起三进程的日志证明这条链路确实跑通、瞬移确实被拒。
前 16 章各自造了零件却从没装在一起跑过。本节把 proto、session、router、timing、aoi、world 按依赖顺序装配成可执行文件 aegis,讲清配置结构、启动顺序与优雅关停,并用一次真进程启动与关停日志验证「端口绑定失败即退出」与「SIGTERM 后连接与计数正确收摊」。
加密解决「别人看不懂」,完整性解决「别人改不动」——两者缺一不可。本节给 aegis 的封包加一层 AES-256-GCM 的 Sealer:seq|nonce|密文+tag 的封套、以 seq 作附加认证数据、64 位滑动窗口抗重放,并讲清方向密钥为什么必须由握手密钥材料按标签派生(与 6.3 重连票据呼应)。
连接耗尽靠的不是带宽,而是数量:几十万条只握手、不登录、不发数据的连接就能把接入层拖垮。本节只讲怎么加固自己的服务端——每 IP 连接上限、未登录连接上限、全局上限、握手令牌桶、slowloris 的读写超时兜底与拒绝策略,并用本机 loopback 的几十条连接做真跑验证。
长度字段来自网络,是不可信输入:一个声明「长度 = 4 GiB」的畸形包就能让服务端按声明预分配巨量内存。本节用 Go 原生 testing.F 给 internal/proto 的帧解析写一个 fuzzer,覆盖长度越界、截断、超长与 flags 组合,讲清「解析器必须对任意字节序列都不 panic、不无限分配」,并给出本机 5 秒百万级执行的实测。
15.2 的校验只会说「过 / 不过」,但反作弊需要的是「可疑到什么程度」。本节给 aegis 写三个真跑的零件:令牌桶限速、指数衰减的嫌疑分、以及把分数映射成处置的阈值表。核心是一个处置梯度——限速、标记、断开、封禁,宁可分级也不一刀切,把误伤的代价压到最低。
移动和战斗是外挂最爱下手的两条路径。本节给 aegis 写一套真跑的校验:把「目的地」当提议、用位移与时间的比值判定超速、用单帧位移上限抓瞬移、用线段采样挡穿墙,再让服务端独占技能冷却与命中判定;并说明为什么校验函数要写成无时钟、无 I/O 的纯函数。每条规则都配了断言,跑得绿才贴进来。
外挂的根子不在客户端有漏洞,而在服务端信了不该信的话。本节把权威边界画清楚:哪些字段客户端只能提议、哪些必须由服务端裁决;再用一个真跑的信任契约表证明——客户端一旦发来服务端自有字段就是违规。最后说明为什么信任模型必须落到字段级,以及「把一切搬上服务端」并不是正确答案。
延迟补偿不能无限给:给得越多,被击中的玩家越觉得「明明躲开了」。本节给补偿套上上限——回退窗口取「绝对上限」与「最大补偿 RTT 的一半」的较小值,并用一个 RTT 追踪器识别「平时很快、开枪瞬间掉包」的延迟作弊,最后讨论被高延迟玩家击杀的体感如何用反馈层缓解。
「我屏幕上打中了,为什么没伤害」和「我躲进掩体了,为什么还被击中」是同一枚硬币的两面。本节实现延迟补偿裁决:为每个实体保存历史位置,按「服务端当前时间 − 半程 RTT − 插值延迟」把世界回退到射手当时看到的那一刻再做命中判定,并用确定性测试复现这两种不公。
「现在几点」这个问题在服务器上比想象中难:墙钟会被 NTP 校时、被 GC 暂停打断,客户端时钟和服务端更是各走各的。本节把逻辑时间与墙钟彻底分离,用单调钟搭一条只向前走的时间线,用 NTP 四时间戳估出客户端时钟偏移,并用确定性测试演示一次向后跳变是怎么被时间线吸收掉的。
逻辑层拿到权威状态了,渲染层还没完:远端玩家的位置是离散快照,直接画会一顿一顿地跳。本节给 aegis 的 predict 包补齐渲染侧的三件工具——用位置插值把快照之间补平、用速度外推兜住「快照还没到」的空档、用误差平滑把 13.2 的校正摊到多帧上,并给出各自的取舍与真跑测试。
预测让客户端先走一步,但权威永远在服务端:一旦服务端的答案和本地不一致,客户端必须回滚到权威状态、把未确认的输入重放一遍。本节把 13.1 的输入缓冲接到和解逻辑上,讲清裁剪-复位-重放三步、用一条测试给回滚的代价定上界(重放条数只跟 RTT 有关),并给出和解误差阈值的取法与「小误差平滑、大误差瞬移」的判据。