容量规划与压测:容量评估方法、全链路压测、压测工具选型
说到容量规划,我第一反应就是——别等系统挂了再想这事。
很多团队平时不压测,上线前才匆匆跑一轮。结果呢?要么压不出问题,要么一压就崩。说白了,容量规划不是一次性的活,它应该贯穿整个研发周期。
这一章,我把自己这些年踩过的坑、总结的方法论,全摊开来讲。
容量评估方法:先算清楚账
容量评估,核心就三个字:算峰值。
你想想看,如果连业务峰值都算不准,后面的压测就是瞎忙活。
我个人习惯用「峰值倍数法」来做初步估算:
- 先拿历史日均QPS,乘以3~5倍,得到日常峰值
- 再拿日常峰值,乘以2~3倍,得到大促/活动峰值
- 最后留出30%~50%的冗余水位
举个例子:
日均QPS = 10000
日常峰值 = 10000 × 4 = 40000
活动峰值 = 40000 × 2.5 = 100000
目标容量 = 100000 × 1.4 = 140000
嗯,这里要注意——这个公式只适用于稳态业务。如果是新业务,没有历史数据怎么办?
我在项目中遇到过这种情况:新功能上线,完全没数据参考。我的做法是——先按业务预估的10倍压,压到系统瓶颈,再反推合理容量。
核心原则:容量评估不是猜数字,而是通过压测不断修正的过程。
全链路压测:别只压单点
很多团队压测只压一个接口,结果上线后整个链路崩了。为什么?因为单点压测看不到上下游依赖的瓶颈。
全链路压测,说白了就是模拟真实用户请求,从网关到数据库,完整走一遍。
我画了一张图,帮你理解全链路压测的核心逻辑:
全链路压测有几个关键点,我重点说一下:
- 流量染色:压测流量必须打上特殊标记,防止污染线上数据
- 影子表:压测数据写入影子表,不影响真实业务
- 依赖隔离:第三方接口要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实时展示。这样压测过程中,你就能看到系统状态的变化。
最后说一句——压测不是终点,而是起点。每次压测完,把瓶颈记录下来,下次压测前先优化掉。这样循环几次,系统的稳定性自然就上来了。
想要更多资料,联系可可