Skip to content

压测、容量规划与扩缩容 ​

Category ​

operation / observability 子树。节点定位:压测→容量模型→扩缩容是一条推理链——拐点比极限值有用、影子流量取舍、有状态服务对弹性的约束。

Definition ​

压测最容易做成的样子,是上线前跑一个脚本、得到一个吞吐数字、写进汇报材料。它真正应该回答的问题要具体得多:在什么样的玩家行为分布下,系统先在哪里卡住,卡住之后的表现如何,加机器能不能解决这个瓶颈。压测、容量规划和扩缩容实际上是一条推理链,任何一环脱离模型单独做,产出都会迅速贬值。

Problem ​

上线前跑脚本得到一个吞吐数字不是容量工作:脱离玩家行为分布的压测会失真,「加机器」解决不了架构瓶颈。容量模型要回答的是:什么行为分布下、先在哪里卡住、卡住后表现如何、加机器能不能解——有状态服务还让弹性伸缩远比无状态昂贵。

压测目标从容量模型来,而不是从脚本来 ​

容量模型回答的是“系统将要面对什么”:预期在线规模、玩家行为分布(在线时长、操作频率、玩法构成、付费与结算节奏),以及各组件因此承受的负载形态。压测目标是从这个模型里推出来的——单机要稳定承载多少同场景玩家、登录峰值每秒多少、数据库要承受每秒多少写、广播链路要撑住多大的房间。

跳过模型直接压,得到的数字没有判断标准:压出八千是多是少,取决于要支撑的目标是多少。压出数字和验证容量是两件事,前者的产出无法进入容量决策,也无法回答“还差多少”。

容量推演链的基本形态 ​

常见的推演路径是:单机或单组件压测得出上限,按峰值负载反推组件数量,再留出余量。余量的分配有两个容易混淆的原则:

  • 余量是给故障的:某台机器损坏或某个组件抖动时,流量要接得住。
  • 弹性是给增长的:超出预期的负载,靠扩容和动态开服消化。

把两者混在一起,要么容量虚高浪费成本,要么故障时没有缓冲。游戏负载的峰谷悬殊进一步放大了容量决策的分量:按晚间峰值规划、大部分时间空转是常态。峰谷比越大的品类,弹性伸缩的成本收益越值得仔细算,而谷值时段的空转成本也确实是容量模型的一部分。

压测结果为什么会失真 ​

压测数字的可信度取决于模拟质量。常见的失真来源有几类:

  • 机器人行为不真实:只发登录和心跳的机器人,测出的上限可能比真实混合负载高数倍。
  • 数据量不足:空库和亿行库的数据库表现完全不同,最慢的查询路径往往要在数据量上来之后才暴露。
  • 环境差异:规格更高、网络拓扑更简单、缺少真实第三方依赖,都会让结果系统性偏乐观。
  • 加压方式均匀:真实压力是局部尖峰——某几个房间爆满、活动开启瞬间的洪峰、整点批量结算,均匀加压测不出这种形态。

这些失真的共同点是都朝乐观方向偏,而这恰恰是最危险的方向:压测给出的安全感,上线之后要用故障来偿还。机器人行为分布通常参照同类产品或历史数据建模,数据量则按生产规模灌入,这两件事的成本远低于它们防住的事故。

关键场景的选取决定压测的价值 ​

压测场景的选取,本质上是在回答“哪种压力最可能先打垮系统”。常见的候选场景包括:

  • 开服与回流洪峰:登录链路在短时间内的集中冲击,往往与稳态负载相差一个量级。
  • 活动开启与整点重置:大量玩家同时触发同一段逻辑,瞬时写入集中爆发。
  • 团战与大规模同屏:广播量、对象规模和同步频率同时达到上限。
  • 跨服与全服玩法:把区服级负载汇聚到全局组件上,暴露的是全局容量。

场景选取的错误形态通常有两种:只压最熟悉的登录链路,把压测做成登录测试;或者均匀地压所有接口,什么瓶颈都测不出来。有价值的做法是从容量模型出发挑出三五个最可能成为短板的场景,把资源集中在它们身上。

压测环境与数据准备 ​

环境准备的目标是让结论可迁移:规格尽量与生产一致,拓扑尽量还原,至少对存疑的部分保持谨慎。数据准备的目标是让慢路径暴露:按生产规模灌入数据,尤其是查询最重的表,让索引缺失和全表扫描在压测期而不是上线后出现。机器人侧则按真实行为分布建模——在线时长、操作频率、玩法构成的分布,比单纯堆连接数更能反映真实负载。

这三项准备的共同特点是成本发生在压测之前,收益发生在上线之后。省略它们省下的是几天时间,赔进去的往往是开服当晚。

拐点比极限值更有用 ​

系统在压力下的表现通常不是线性恶化,而是存在一个拐点:过了它,延迟开始非线性上升,错误率抬头,排队开始积压。极限吞吐数字是瞬时的、不可运行的;拐点对应的水位才是可以持续运行的。生产负载通常控制在明显低于拐点的位置,留出的缓冲用于吸收波动和局部尖峰。

只记录“最高压到多少吞吐”而不记录拐点位置的压测报告,对容量决策几乎没有贡献。阶梯式加压、逐档观察延迟与错误率,目的就是找到这个拐点,而不是冲一个好看的峰值。

影子流量与线上压测的取舍 ​

在真实生产环境导入压测流量,是消除环境差异最直接的手段。它的价值在于真实的数据形态、真实的依赖、真实的拓扑;风险也同样具体:

  • 写请求会污染生产数据:假订单、假支付、假邮件一旦落库,清理成本很高。
  • 可能触发真实的下游动作:结算、发货、推送、对第三方的回调。
  • 压垮的是真实用户正在使用的共享依赖。

所以线上压测通常要以一整套防护为前提:流量带标记并在存储层隔离、写路径旁路或模拟、共享依赖提前评估、随时可以一键熔断、选业务低谷执行。防护没做全就开压,压测本身就变成了一次没有人想要的事故演练。也正因为防护成本不低,线上压测通常只留给关键链路和重大版本,而不是常态化随手执行。

扩容什么时候有用,什么时候没用 ​

加机器只对可分摊的负载有效。横向扩容有效的典型:无状态的接入与逻辑服务、可自动分片的房间。扩容无效或收效甚微的典型:

  • 单局热点:一个房间或一张地图的对象规模上限,瓶颈在单进程内部。
  • 全局锁与中心化状态:所有请求挤过同一个节点。
  • 单条慢查询:应用侧加多少机器,数据库还是那个瓶颈。
  • 下游依赖:第三方接口的限流额度不会因为自己加机器而提高。

看到瓶颈先加机器,是容量问题里最常见也最昂贵的误判。扩容之前先回答瓶颈类型,答案往往决定该扩的是机器、是架构拆分,还是玩法设计本身。

有状态对弹性伸缩的约束 ​

游戏服务端的特殊性在于状态在内存里:玩家会话和房间状态不能随手迁移或销毁。这限制了弹性的作用范围——真正能随意伸缩的是无状态组件,玩家所在的房间与场景服要按预案启停,缩容需要等待排空或完成迁移。把 web 服务“随时重启、随时漂移”的运维习惯直接带进游戏服,是事故的高发来源。扩缩容方案设计时区分这两类服务,比事后补救便宜得多。

扩容预案是容量模型的执行面 ​

容量模型给出的结论,只有在变成可执行预案之后才真正生效。预案通常要回答:容量水位到多少时触发扩容、由谁执行、启动机器和开服的步骤是什么、新服的数据初始化和接入配置是否自动化。没有预案的扩容,在洪峰到来时退化成临时申请机器、手工初始化、口头协调,速度和正确性都没有保障。

预案同样需要演练。扩容演练暴露的问题非常典型:镜像里缺配置、新服连不上某个依赖、开服脚本假设了旧的区服数量。这些问题在演练里暴露是几分钟的事,在真实洪峰里暴露就是事故的一部分。

容量模型要随版本演进 ​

负载形态会被玩法改变:新玩法的对象规模、新的广播模式、活动规则的变化,都会让上一轮压测结论过期。常见的做法是把容量复核挂进版本流程——大版本前后对关键场景复测,线上持续观察实际负载与模型的偏差,偏差持续扩大时更新模型。容量治理是一次次修正出来的持续工作,不是上线前的一次性仪式;模型过期的第一个信号,往往就是线上水位和预测曲线开始系统性分叉。

容量决策里的成本视角 ​

容量从来不只是技术数字。按峰值配置的机器大部分时间空转,谷值的空转成本、弹性伸缩的收益边界、预留与按量的配比,都是容量模型的一部分。技术侧把水位和拐点讲清楚,成本侧的取舍才有依据;脱离成本谈容量,规划容易一路加码,反过来脱离水位谈省钱,省下的钱迟早用故障偿还。

常见误区 ​

  • 压测目标没有来源,压出数字当结论,无法支撑容量决策。
  • 机器人行为失真、数据量不足,得到系统性偏乐观的上限。
  • 只记录极限值不找拐点,报告漂亮但对应的水位不可运行。
  • 线上压测没有隔离与熔断防护,压测自身变成事故。
  • 瓶颈类型不明就先加机器,成本上升而体验不变。
  • 一次性压测,玩法迭代之后容量模型长期过期。

压测、容量和扩缩容合在一起看,共同点很清楚:它们都是围绕“系统将要面对什么”的推理,而不是围绕“系统能打多少分”的测量。推理的输入越接近真实的行为分布,输出才越接近可用。

Used By ​

容量模型建设与压测场景设计;扩缩容预案与拐点评估;版本迭代中的容量回归。

关系链:容量模型 → 推演链 → 压测校准 → 拐点 → 扩缩容预案。上游:observability/02(线上指标校准模型)。下游:production/03(灰度发布的容量面)。

Reference ​

本页为工程经验归纳。

游戏知识体系