凌晨两点半,告警群炸了。CPU 85%,还在往上爬。值班的兄弟第一反应是扩容,第二反应是——机器的配额上周刚用完,加机器要走流程,先扛。
这就是容量规划没做到位的典型夜晚。
“够不够”这个问题 大多数人问错了
常见的问法是:我们的服务器够不够用?
太模糊。够用是相对于什么负载?哪个时间点?哪种故障场景?
容量规划真正要回答的是三件事。系统在当前负载下的余量有多少,负载涨到多少会触到瓶颈,以及瓶颈先出现在哪一层。
注意最后一句。瓶颈往往不在你以为的地方。CPU 看着挺闲,数据库连接池先满了。带宽没打满,磁盘 IO 先到顶了。这种情况我见过太多次,监控大盘上一片绿,用户那头已经开始转圈。
所以容量规划的第一步不是算机器,是把链路上每一层的容量指标列出来。应用层看 QPS 和并发。中间件看连接数和队列深度。存储看容量、IOPS、吞吐三个维度,别混着算。网络看带宽和 PPS。数据库更麻烦,慢查询、锁等待、主从延迟都得盯。

线性外推是最容易踩的坑
“现在日活十万,用了二十台机器,涨到二十万就加二十台。”
这话听着没毛病,实际上错得离谱。
原因有几个。第一,负载不是均匀的。日活翻倍,峰值 QPS 可能翻不止两倍,因为用户行为会聚集。第二,单机性能不是线性的。CPU 利用率从 50% 到 70%,响应时间可能还挺稳;从 70% 到 85%,延迟开始肉眼可见地涨;过了 90%,那是雪崩的前夜。排队论早就把这条曲线画出来了,只是没人愿意看。第三,也是被忽略最多的——压测流量和真实流量根本不是一回事。
压测里每个请求都干干净净,参数合法,命中缓存。线上呢?爬虫、异常重试、热点 key、慢连接,全挤在一起。
有个团队跟我聊过,单机压测能跑到八百 QPS 稳稳的,上线之后到六百就开始抖。查了半天,是压测时没模拟长连接和 TCP 重传。这种账,纸面上永远算不平。

余量留多少 得看你能接受多大的坑
留余量这事,很多人喜欢拍个整数。30%。50%。听着吉利。
但余量不是一个数,是一组决策。
要不要做 N+1?意味着任何一个节点挂了,剩下的人扛得住。N+1 的成本很低,通常值得。要不要跨机房?这就贵了,而且复杂,数据同步的坑一堆。
还有个更实际的问题:降级方案是什么?容量规划如果不写清楚“扛不住的时候先牺牲谁”,那它只是一张采购清单。是关掉推荐?是限流?是把非核心业务降级?这些得提前定,跟业务方对齐,别等出事了在群里吵。
容量规划里有个反直觉的点。余量不是越多越好。余量太多,成本浪费,而且会掩盖性能问题。一个系统长期跑在 20% 水位,没人会去优化它,直到某天流量真的来了,才发现单机效率差得惊人。
所以余量要跟成本、风险、迭代速度一起权衡。这话说起来像废话,但真到拍板的时候,多数人只盯着其中一个。
容器化之后 容量规划换了个马甲

现在不少团队跑在 K8s 上,游戏规则变了。
以前是数机器,现在是配 requests 和 limits。requests 决定调度,limits 决定生死。配小了,Pod 被 OOMKill,日志里就一行字,找半天。配大了,资源碎片化,集群利用率低得可怜。
更麻烦的是,K8s 的调度是按 requests 算的,不是按实际用量。你 requests 写 2 核,实际只用 0.3 核,那 1.7 核就被锁死了。这种事在大集群里能吃掉三成成本。
所以容器环境下的容量规划,得同时看 requests、limits 和实际 usage 三条线。哪条线偏了,都是钱或者稳定性。
算完了还得写下来 不然等于没算
容量规划最怕什么?怕它变成一年一次的仪式。
做完一次,文档一存,明年再说。可业务在变,代码在变,架构在变。三个月前的假设,可能已经失效了。
我的建议是,把容量规划当成一个持续的小动作。每次大促前跑一次全链路压测。每个季度 review 一次容量水位。关键指标做趋势图,不要只看当前值,要看斜率和拐点。
文档里必须写清楚假设。用户增长假设是多少。缓存命中率假设是多少。这些假设如果错了,结论就全错了。写下来,下次复盘才有依据。
还有一点,容量规划的结果要能被验证。你预测系统能扛十万 QPS,那就想办法压到十万试试。压不到,说明模型有问题。压到了但线上表现不一样,说明流量模型有问题。
别怕犯错。怕的是错了还不知道为什么。
说回凌晨那个告警。后来怎么解决的?值班的兄弟把非核心的图片压缩服务临时降级了,扛过去了。第二天复盘发现,图片服务的容量水位其实早就该扩容,只是没人注意到它的增长曲线比主站还陡。
这种事,每个团队都遇到过。区别只在于,有的团队把它记下来,有的团队等下一次告警。