容量规划与压测:容量评估方法、全链路压测、压测工具选型

说到容量规划,我第一反应就是——别等系统挂了再想这事。

很多团队平时不压测,上线前才匆匆跑一轮。结果呢?要么压不出问题,要么一压就崩。说白了,容量规划不是一次性的活,它应该贯穿整个研发周期。

这一章,我把自己这些年踩过的坑、总结的方法论,全摊开来讲。

容量评估方法:先算清楚账

容量评估,核心就三个字:算峰值。

你想想看,如果连业务峰值都算不准,后面的压测就是瞎忙活。

我个人习惯用「峰值倍数法」来做初步估算:

  • 先拿历史日均QPS,乘以3~5倍,得到日常峰值
  • 再拿日常峰值,乘以2~3倍,得到大促/活动峰值
  • 最后留出30%~50%的冗余水位

举个例子:

日均QPS = 10000
日常峰值 = 10000 × 4 = 40000
活动峰值 = 40000 × 2.5 = 100000
目标容量 = 100000 × 1.4 = 140000

嗯,这里要注意——这个公式只适用于稳态业务。如果是新业务,没有历史数据怎么办?

我在项目中遇到过这种情况:新功能上线,完全没数据参考。我的做法是——先按业务预估的10倍压,压到系统瓶颈,再反推合理容量。

核心原则:容量评估不是猜数字,而是通过压测不断修正的过程。

全链路压测:别只压单点

很多团队压测只压一个接口,结果上线后整个链路崩了。为什么?因为单点压测看不到上下游依赖的瓶颈。

全链路压测,说白了就是模拟真实用户请求,从网关到数据库,完整走一遍。

我画了一张图,帮你理解全链路压测的核心逻辑:

全链路压测核心流程 压测工具(wrk/locust/JMeter) 网关层(Nginx/API Gateway) 服务层(微服务/业务逻辑) 数据层(DB/Cache/消息队列) 监控数据采集 瓶颈分析 容量调整 反馈循环:持续优化

全链路压测有几个关键点,我重点说一下:

  • 流量染色:压测流量必须打上特殊标记,防止污染线上数据
  • 影子表:压测数据写入影子表,不影响真实业务
  • 依赖隔离:第三方接口要mock掉,别把别人压崩了

我曾经在一次全链路压测中,忘了给压测流量染色。结果压测数据混入了线上订单表,导致对账系统跑了一整天都没对平。从那以后,我每次压测前都会反复确认:流量染色开了没?影子表建了没?

压测工具选型:选对工具,事半功倍

市面上的压测工具很多,但每个工具都有自己的脾气。我按场景给你拆开讲。

工具 核心特点 适用场景 我的评价
wrk 轻量、高性能、基于C 单接口压测、快速验证 简单粗暴,适合开发自测
locust Python脚本、分布式 复杂场景、自定义逻辑 灵活,但性能不如wrk
JMeter 图形化、插件丰富 全链路压测、企业级 功能最全,但学习成本高

wrk:开发自测首选

wrk是我个人最常用的工具。为什么?因为它够快。一个命令就能压起来:

wrk -t12 -c400 -d30s http://localhost:8080/api

参数说明:

  • -t12:12个线程
  • -c400:400个并发连接
  • -d30s:持续30秒

输出结果也很直观:

Thread Stats   Avg      Stdev     Max   +/- Stdev
  Latency    45.67ms   12.34ms  120.45ms   85.23%
  Req/Sec     8.90k     1.23k    12.45k    78.45%
  267890 requests in 30.00s, 345.67MB read
Requests/sec:  8929.67
Transfer/sec:   11.52MB

嗯,这里要注意——wrk只支持HTTP/1.1,不支持HTTP/2。如果你压的是gRPC服务,那得换工具。

locust:复杂场景的利器

locust用Python写脚本,灵活性很高。我在项目中遇到过需要模拟用户登录、浏览、下单的完整流程,用wrk搞不定,locust就派上用场了。

from locust import HttpUser, task, between

class WebsiteUser(HttpUser):
    wait_time = between(1, 5)
    
    @task(3)
    def view_items(self):
        self.client.get("/items")
    
    @task(1)
    def add_to_cart(self):
        self.client.post("/cart", json={"item_id": 123})

locust的分布式能力也很强。你可以用一台master控制多台worker,轻松压到几十万QPS。

小技巧:locust的Web UI可以实时查看RPS、响应时间、失败率。我习惯在压测时开着UI,一旦发现失败率超过1%,立刻停掉排查问题。

JMeter:企业级压测的标配

JMeter功能最全,但学习曲线也最陡。我一般只在全链路压测时用它,因为它的插件生态太丰富了。

举个例子,JMeter可以配合Backend Listener把压测数据实时写入InfluxDB,然后用Grafana展示。这样压测过程中,你就能看到每个接口的响应时间、吞吐量、错误率。

// JMeter的Backend Listener配置示例
// 选择 org.apache.jmeter.visualizers.backend.influxdb.InfluxdbBackendListenerClient
// 配置 influxdbUrl = http://localhost:8086
// 配置 measurement = jmeter

压测数据采集与分析:别被数据骗了

压测跑完了,数据也拿到了。但你真的看懂了吗?

我见过太多人只看平均响应时间,结果上线后大量请求超时。为什么?因为平均值会掩盖长尾延迟。

我个人习惯看这几个指标:

  • P99延迟:99%的请求在多少毫秒内完成。这个值比平均值更有参考价值
  • 错误率:超过1%就要警惕,超过5%立刻停压
  • 吞吐量拐点:当并发数增加,吞吐量不再上升甚至下降,说明系统到瓶颈了

避坑指南:我曾经压一个接口,P99延迟从50ms飙到500ms,但平均延迟只从30ms涨到80ms。如果只看平均值,我可能就放过去了。所以记住——永远不要只看平均值。

数据采集方面,我推荐用Prometheus + Grafana这套组合。压测工具把数据推给Prometheus,Grafana实时展示。这样压测过程中,你就能看到系统状态的变化。

最后说一句——压测不是终点,而是起点。每次压测完,把瓶颈记录下来,下次压测前先优化掉。这样循环几次,系统的稳定性自然就上来了。

想要更多资料,联系可可