并发压测基础:压测目的、关键指标、常用工具

做性能优化,第一件事不是调代码,而是搞清楚——你的系统到底能扛多少压力?压测就是干这个的。我刚开始带项目时,跳过压测直接上线,结果用户一涌进来,服务直接打嗝。那之后,压测成了我的标配动作。

压测目的:找瓶颈与验证容量

说白了,压测就两件事:找瓶颈和验证容量。

  • 找瓶颈——把系统推到极限,看哪个环节先撑不住。可能是CPU打满、内存不够、连接池耗尽,或是数据库锁冲突。我记得有一次压Secrets SDK,发现加解密操作把CPU吃光了,但IO根本没动,明显是算法实现有问题。
  • 验证容量——在预期负载下,系统能否稳定跑出SLA承诺的指标。比如你承诺单机支持1000 QPS、P99延迟<50ms,就得压出结果来证明。

我曾经踩过一个坑:只压了单个接口,没压混合场景。结果上线后多个服务并发请求,数据库连接池先爆了。压测一定要贴近真实流量模式,别偷懒。

关键指标:QPS、P99延迟、错误率

压测完得看几个硬指标,不然压了等于白压。我个人习惯盯着这三个数:

指标 意义 关注点
QPS 每秒处理请求数,衡量吞吐量 随并发增加,QPS是否线性增长?拐点在哪?
P99延迟 99%的请求在多少毫秒内完成 P99比平均数更敏感,能暴露尾延迟问题
错误率 请求失败的比例 压力下错误率飙升往往是系统崩溃的前兆

你想想看,如果QPS很高但P99延迟飘到几秒,用户实际体验就是卡死。为什么?因为突然有几个慢请求拖住了连接,后面的请求全在排队。我见过一个案例,Secrets SDK在并发200时P99从10ms跳到800ms,查了半天是证书校验在同步锁里堵住了。

建议同时监控GC频率和堆内存。JVM应用压测时,P99抖动常常是GC引发,别上来就怀疑业务代码。

常用工具:wrk、locust、JMeter

工具各有各的脾气。我简单说说它们的特点,你根据场景选。

wrk

轻量、命令行、CPU密集。适合单机压测,写Lua脚本能做简单逻辑。我对它的评价是:快,但不灵活。

wrk -t12 -c400 -d30s --latency http://localhost:8080/secrets/query

locust

Python编写,支持分布式。压测逻辑用Python写,灵活度高。我用它模拟不同用户行为,比如依次登录、查询密钥、退出。

from locust import HttpUser, task, between

class SecretsUser(HttpUser):
    wait_time = between(1, 3)

    @task
    def query_secret(self):
        self.client.get("/secrets/query")

JMeter

老牌GUI工具,录制回放方便。适合复杂场景和团队协作。但我觉得它太重了,改参数得点半天。不过做容量验证时,它的报告生成能力确实靠谱。

jmeter -n -t secrets_test.jmx -l result.jtl -e -o report

工具对比速查

特性 wrk locust JMeter
语言 C + Lua Python Java
分布式 不支持(单机) 支持(master-worker) 支持(远程)
学习成本 低 中 中高
适合场景 快速压测、性能基准 复杂用户逻辑 多协议、企业级报告

我的选择原则:找瓶颈用wrk最快,验证容量用locust模拟真实用户,给客户出报告用JMeter。嗯,这差不多是共识了。

并发压测基础知识体系 压测目的 找瓶颈 · 验证容量 关键指标 QPS · P99延迟 · 错误率 常用工具 wrk · locust · JMeter 找瓶颈 CPU/内存/IO/锁 验证容量 SLA达标性确认 QPS 吞吐能力 P99延迟 尾延迟敏感 错误率 系统崩溃前兆 wrk 轻量/命令/Lua locust Python/分布式 JMeter GUI/多协议/报告 压测目的决定指标选择,指标驱动工具选择,三者环环相扣

你看这张结构图,压测目的、关键指标、常用工具三个模块是互相关联的。目的决定你要看哪些指标,指标又反过来帮你选趁手的工具。实际调优时,我通常先拿wrk做一次快速摸底,发现瓶颈后换locust模拟复杂场景,最后用JMeter出容量报告给老板看。

再多说一句坑:压测时千万记得监控系统资源(CPU、内存、网络、磁盘)。我曾经只盯着应用QPS,结果压到CPU 100%还以为正常——其实系统已经过载了,延迟全在排队。挂个htop或Prometheus,跟压测同步跑。