本文目录导读:

- 第一步:明确压测目标与核心指标
- 第二步:选择合适的压测工具
- 第三步:设计压测场景
- 第四步:执行阶梯式压测(寻找拐点)
- 第五步:监控与定位瓶颈(最重要的部分)
- 第六步:分析结果与报告
- 常见陷阱与注意事项
- 总结:一个典型的容量压测脚本示例(使用 k6)
对系统进行容量压测,核心目标是找到系统的拐点(即性能开始急剧下降或报错的那个临界点),从而得出系统在不违背服务等级协议的前提下,能承载的最大并发用户数或每秒请求数。
下面是一套经过实践检验的容量压测方法论,包含从准备到分析的完整流程。
第一步:明确压测目标与核心指标
在开始压测前,必须先定义“容量”是什么,通常关注以下指标:
- 吞吐量: 每秒事务数或每秒请求数。
- 响应时间(RT): 特别是 TP95 或 TP99 响应时间(目标是 TP99 < 500ms)。
- 错误率: 通常要求低于 1%(5xx 错误、超时)。
- 资源利用率: CPU、内存、IO、网络带宽、数据库连接数等。
目标示例: “在 TP99 < 200ms 且错误率 < 0.1% 的前提下,找到系统在 4核8G 配置下的最大并发用户数。”
第二步:选择合适的压测工具
市面上的工具可分为几类,根据场景选择:
| 工具类型 | 代表工具 | 适用场景 |
|---|---|---|
| 协议级/接口级 | Locust (Python),k6 (Go/JS), JMeter (Java) | 最常用,对 HTTP、gRPC、WebSocket 等协议进行压测。 |
| 全链路/流量复制 | GoReplay,Tcpcopy | 生产环境流量回放,模拟真实用户行为组合。 |
| 云原生/容器化 | 阿里云 PTS,AWS Distributed Load Testing | 免运维,支持千万级并发,自带监控和报告。 |
| 单机轻量级 | ab (Apache Bench),wrk,Vegeta | 快速测试单个接口的极限。 |
建议: 团队如果追求灵活和脚本可控,推荐 k6(性能好、语法简单)或 Locust(支持分布式、可编程性强)。
第三步:设计压测场景
不能只压一个接口,要模拟真实流量模型。
- 单接口基准测试: 单独压测登录、搜索、下单等关键接口,找出各自的瓶颈。
- 混合场景测试: 按生产环境流量比例混合压测(60% 浏览 + 30% 搜索 + 10% 下单)。
- 阶梯式负载测试: 这是容量压测的核心方法。
第四步:执行阶梯式压测(寻找拐点)
这是容量压测最关键的步骤——阶梯式加压,不推荐直接上 10000 并发。
执行流程:
- 初始化: 从低并发开始(如 100 并发)。
- 阶梯加压:
- 以 10%-20% 的增量逐步增加并发数(如 100 -> 200 -> 500 -> 1000 -> ...)。
- 每个阶段持续运行 3-5 分钟,让系统有足够时间达到稳态(让 GC、缓存、连接池等稳定下来)。
- 监控拐点: 在加压过程中,持续观察下文第四步中的核心监控。
- 找到拐点: 当出现以下任一情况时,该前一个阶段的并发数即为系统的容量极限:
- 响应时间出现拐点: TP99 突然从 200ms 飙升到 2s。
- 错误率出现拐点: 突然出现大量 5xx、超时或连接拒绝。
- 资源利用率出现拐点: CPU 达到 85%-90% 且不再上升(进入饱和);或者内存达到上限开始频繁 GC/交换;或者数据库连接池耗尽;或者网络带宽打满。
第五步:监控与定位瓶颈(最重要的部分)
压测只是手段,定位瓶颈才是目的,需要监控以下层次:
-
应用层(你自己的代码):
- APM工具: SkyWalking、Pinpoint、Zipkin,观察哪个接口、哪个方法消耗时间最长。
- 日志: 观察是否有大量慢日志、GC 日志(Full GC 频率)。
-
中间件层:
- 数据库: 数据库的 QPS、连接数、慢查询数、读写延迟。数据库往往是容量瓶颈。
- 缓存: Redis 的命中率、内存使用、OOM 风险。
- 消息队列: RabbitMQ/Kafka 的堆积情况、消费延迟。
-
基础设施层:
- CPU: 用户态高(代码逻辑)还是内核态高(系统调用/IO)?
- 内存: 是否发生频繁的 Swap 或 GC?
- IO: 磁盘(日志写入过多?)、网络(带宽被打满?)。
第六步:分析结果与报告
压测结束后,产出报告,回答以下问题:
- 极限容量: 在满足服务等级协议的条件下,系统能承载的最大并发用户数或每秒请求数是多少?
- 瓶颈点: 本次压测暴露出的第一个瓶颈是什么?(数据库连接池不够用、某个业务逻辑方法耗时过长、单线程的日志写入导致IO瓶颈)
- 优化建议: 针对瓶颈点给出具体修复方案(如:增加连接池大小、加索引、加缓存、异步化、扩容等)。
- 扩缩容建议: 给出“每增加一个实例,能带来多少容量提升”的参考数据。
常见陷阱与注意事项
- 压测工具本身成为瓶颈: 单台压测客户端可能无法产生足够压力,需要使用分布式压测架构(多台机器同时发压)。
- 冷启动 vs 热启动: 第一次压测(冷)和预热后的第二次压测(热)结果可能相差巨大,建议先进行预热(比如用低并发跑几分钟)。
- 数据隔离: 不要在联调环境压测,建议在预发环境或独立的压测环境进行,避免影响生产用户。
- 数据库数据量: 压测时数据库里的数据量不能太少,如果只有 100 条数据,查询会很快;生产上有 1000 万条数据,性能会完全不同。
- 不要只测极限,要测“健壮性”: 可以在压测过程中,模拟突然关掉一台机器或突然降低数据库连接池,观察系统的熔断、降级、限流机制是否生效。
一个典型的容量压测脚本示例(使用 k6)
// capacity_test.js
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
// 阶梯式加载配置
stages: [
{ duration: '2m', target: 200 }, // 升温阶段
{ duration: '5m', target: 200 }, // 稳定阶段
{ duration: '2m', target: 500 }, // 阶梯上升
{ duration: '5m', target: 500 },
{ duration: '2m', target: 1000 },
{ duration: '5m', target: 1000 },
{ duration: '2m', target: 0 }, // 降温阶段
],
thresholds: {
http_req_duration: ['p(99)<500'], // 99%的请求要在500ms内
http_req_failed: ['rate<0.01'], // 错误率低于1%
},
};
export default function () {
const res = http.get('http://your-api.com/users');
check(res, { 'status is 200': (r) => r.status === 200 });
sleep(1); // 模拟用户思考时间
}
运行命令:
k6 run capacity_test.js
通过这种系统化的方法,你才能真正量化一个系统的容量,并知道它“什么时候会倒下”。
标签: 系统容量
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。