
1. 先厘清概念性能、负载、压力到底差在哪我先说一个这些年面试和带人时反复遇到的场景一说到性能测试十个人里有八个会把性能测试负载测试压力测试混着用。问你们做过压力测试吗回答做过就是拿 JMeter 压了一下接口看下吞吐量。再问那你压到系统崩溃了吗崩溃点在哪对方就愣住了。这三个词的关系我用一个做饭的类比讲清楚性能测试是问这口锅一次能炒几个菜、炒多久、味道稳不稳定负载测试是问同时来十桌客人后厨能不能接住、上菜速度会不会掉压力测试是问如果来了五十桌客人后厨是先出不了菜还是直接着火。所以你看负载和压力其实都是性能测试的子集但它们的观测目标和结束条件完全不同。性能测试Performance Testing核心词是达标。在预期负载下验证系统的响应时间、吞吐量、资源占用是否满足业务指标。比如线上 SLA 要求接口 95 线在 200ms 以内性能测试就是验证这个。负载测试Load Testing核心词是渐进。逐步增加并发数观察系统性能曲线的变化趋势找到性能开始劣化的拐点。它回答的是系统在多少负载下依然能保持稳定。压力测试Stress Testing核心词是极限。持续加压直到系统崩溃或性能不可接受找到系统的承载上限和失败模式。它回答的是系统最多能扛多少扛不住的时候是优雅降级还是直接雪崩。这里有一个很容易犯的误区很多人以为压力测试就是负载测试的加强版多压几倍并发就完事。但真正的压力测试还要关注恢复能力——系统在被压垮之后撤掉压力能不能自动恢复。这个细节在你做面试准备或者真刀真枪做压测的时候非常加分。提示性能测试是验证达标负载测试是寻找拐点压力测试是探明上限与失败模式。三者目标不同设计场景的方式就完全不同这是整篇文章的地基。2. 从测试计划到落地的完整执行链路概念清楚了接下来是实操层面的东西。我见过太多测试同学拿到 JMeter 就直接开跑结果压出来的数据根本没法看。完整链路应该包含下面五步每一步都有隐藏的坑。2.1 测试计划先定义什么算性能达标不要一上来就填并发数。第一步是找开发、产品、运维对齐三个数字线上真实峰值 QPS比如大促期间的每秒请求数可接受的响应时间上限比如核心接口 500ms允许的失败率一般 0.1%但金融类业务要求更严这三个数字就是你的验收标准。我见过一个反面案例测试团队花了一周压测数据很好看结果一问业务方人家说大促峰值预估是每秒 2 万请求他们只压到了 2000。整个测试白做。2.2 脚本与场景设计并发模型是灵魂脚本设计不是录个脚本跑起来就完事。你要理解每个接口的业务权重。比如一个电商系统浏览商品接口可能占了 70% 的流量但下单接口只占 5%。如果你用 JMeter 的默认线程组把每个接口都配成相同并发压出来的结果完全没有参考价值。我习惯的做法是先用线上日志做流量模型分析统计各接口的调用占比和平均耗时然后按比例设计脚本。如果没有日志权限至少要和开发确认接口的重和轻。2.3 测试数据准备压测结果失真的头号原因很多人压测结果不忍直视不是系统不行而是数据准备不到位。典型的坑有两个所有线程共用同一批测试数据导致数据库缓存命中率虚高压测结果全都偏乐观关联数据没做好比如 token、订单号、用户ID 是写死的导致服务器端逻辑走了同一个分支测的是幸运路径而非真实路径正确做法是准备足够大、足够脏的数据池。比如压测用户登录接口至少准备几千上万个真实格式的账号密码压测订单查询接口每个用户要有不同状态的订单未支付、已支付、已退款等。2.4 监控与指标采集二分法看性能压测过程中客户端指标TPS、响应时间、错误率和服务端指标CPU、内存、磁盘 IO、网络带宽、GC 频率、数据库连接池占用率必须同时采集。只看一端都无法定位问题。客户端 TPS 上不去你就得看服务端瓶颈在哪。CPU 打满那多半是计算密集考虑优化代码或扩容。数据库连接池等待时间长那是 DB 连接数不够。GC 频繁那是堆内存设置或对象创建有问题。一个很实用的技巧把监控采集做成自动化脚本压测结束后自动拉取整个时间段的曲线图。不然压测跑完监控数据没落盘复盘的时候啥也拿不出来等于白测。2.5 执行策略稳定性测试是必选项除了常规的阶梯加压务必安排稳定性的长时间测试。这个测试很简单取 70%~80% 的预估峰值负载持续跑 3~4 小时甚至 24 小时观察是否存在内存泄漏、连接池耗尽、日志文件写爆磁盘等问题。我遇到过一次非常典型的例子接口压测 10 分钟一切正常TPS 稳定在 3000但跑到 50 分钟的时候 TPS 直接掉到 500一看监控Metaspace 一直在缓慢增长最后触发 Full GC。这种问题短时压测根本暴露不出来必须靠长时间稳定性测试。3. 工具选型实操JMeter 和 Locust 到底怎么选现在的压测工具生态很丰富很多人纠结该学哪个。我的建议是JMeter 和 Locust 必须要会一个但最好两个都掌握因为它们代表着两种完全不同的设计哲学。3.1 JMeterGUI 派的扛把子JMeter 是 Apache 旗下开源工具Java 生态以 GUI 操作为主也支持命令行模式。它的优势在于上手门槛低录制脚本、配置线程组、加断言都是可视化操作新手半天就能跑起第一个压测脚本插件生态丰富比如 Throughput Shaping Timer 插件可以自定义吞吐量曲线做负载测试时非常方便协议支持全面HTTP、HTTPS、WebSocket、JDBC、JMS 等都能压JMeter 的性能测试步骤大概是这样的创建测试计划添加线程组配置并发数、Ramp-Up 时间、循环次数添加 HTTP 请求默认值配置协议、服务器 IP、端口添加 HTTP 请求采样器填写接口路径、请求方法、Body 数据添加 HTTP 头管理器Content-Type、Authorization 等添加监听器查看结果树、聚合报告、用 ServerAgent 监控服务器资源用命令行模式跑压测jmeter -n -t test.jmx -l result.jtl -e -o report_dir一个很容易忽略的细节JMeter 本身的性能瓶颈。用 GUI 模式跑高并发压测时JMeter 进程自身会消耗大量资源导致压测结果不准。线上压测一定要用命令行模式并且把压力机和被测服务器分开部署。如果你压的是 Web 应用可以在测试计划里添加ServerAgent来监控服务器 CPU、内存、磁盘 IO。配置方法很简单在被测服务器上启动 ServerAgent 的 startAgent.sh然后在 JMeter 里添加 jpgc - PerfMon Metrics Collector 监听器填上服务器 IP 和端口即可。3.2 Locust代码派的效率之王Locust 是 Python 生态所有压测场景都是写 Python 代码定义。它的优势在于压测场景表达能力强复杂的业务流比如先登录、再下单、再支付用代码写出来比在 JMeter 里拖组件清晰得多协程机制单机并发能力极强一个 Locust 进程可以模拟成千上万的并发用户而 JMeter 每个线程都对应一个 Java 线程太高的并发需要多台压力机分布式的方案配合 Python 生态好调试数据构造、断言逻辑、动态参数用代码处理起来很灵活下面是一个简单的 Locust 压测脚本示例from locust import HttpUser, task, between class WebsiteUser(HttpUser): wait_time between(1, 5) task(3) def view_item(self): self.client.get(/item/1001) task(1) def add_to_cart(self): self.client.post(/cart, json{item_id: 1001, count: 1})启动方式locust -f locustfile.py --hosthttps://your-api.example.com --web-port8089然后在浏览器打开http://localhost:8089就能看到 Web 控制台设置并发用户数和产生速率后实时观察 TPS、响应时间、失败率曲线。3.3 我的选型建议团队里测试同学多、开发参与少或者被测协议比较单一选 JMeter维护成本低压测场景复杂需要条件判断、数据流转、团队成员写代码没压力选 Locust灵活度更高两个都不满足直接用云压测平台比如阿里云 PTS、腾讯云压测大师好处是压力机资源不用自己准备秒级拉起百万级并发坏处是要花钱提示工具只是执行层决定压测质量的是你的场景设计和数据分析能力。别在工具上内耗把时间花在理解系统架构上收益更大。4. 性能瓶颈定位从 TPS 曲线到根因的完整排查链路压测数据出来以后最考验功底的就是根因定位。这一章我梳理一条我自己反复使用的排查路径你按这个思路走基本不会跑偏。4.1 第一步看 TPS 和响应时间曲线定方向拿到聚合报告先看 TPS 曲线的形状TPS 平稳上升直到达到预期值后趋于平缓——恭喜系统没太大问题TPS 先升后降出现明显的驼峰——系统存在资源瓶颈需要看服务端指标TPS 震荡剧烈、响应时间随之大幅抖动——大概率存在阻塞或排队问题比如数据库连接池打满、队列表被锁、线程池拒绝再用响应时间的变化趋势辅助判断响应时间如果像爬坡一样越来越慢优先怀疑内存泄漏或资源未释放如果是突然变慢优先怀疑某个中间件Redis、数据库、MQ的瓶颈。4.2 第二步分层排查服务端指标按照应用层 → 中间件层 → 基础设施层的顺序排查。应用层看 JVM 的 GC 日志是否出现 Full GC 频繁看线程池状态是否有大量线程处于 BLOCKED/WAITING 状态。用jstack抓线程快照看看线程都在等什么。中间件层数据库看慢查询日志、连接数占用率Redis 看命中率、内存淘汰情况、慢日志MQ 看消费积压量和消费耗时。基础设施层CPU 使用率是 user 高还是 sys 高user 高说明是业务计算密集sys 高说明是系统调用频繁比如频繁的上下文切换磁盘 IO 的 await 是否过高网络带宽是否打满。我给一个经验值参考不同业务有差异Press 到 70% 峰值并发时CPU 利用率超过 85% 就要警惕数据库连接池使用率超过 80% 就需要扩容或优化连接释放逻辑。4.3 第三步用排除法定位而不是猜很多人定位瓶颈全靠猜一会儿怀疑代码慢、一会儿怀疑数据库慢最后搞半天发现是监控系统本身拖慢了被测服务。我的习惯是一次只改一个变量控制变量法排查。比如 TPS 上不去且 CPU 打满先看是不是 GC 频繁导致的。如果是调整 JVM 堆参数或者优化对象创建如果不是用arthas或async-profiler抓 CPU 热点看看具体是哪个方法耗 CPU。改完一处重新压测观察 TPS 是否提升。反复迭代直到找到最终根因。4.4 排障过程中的经典案例说一个我之前做过的真实案例。某个订单查询接口压测到 500 并发时 TPS 只有 800响应时间从 50ms 飙升到 1500ms。监控数据拿过来一看应用服务器 CPU35%不高数据库 CPU65%偏高但在合理范围数据库连接池占用率98%异常基本锁定数据库连接池是瓶颈。再查连接池配置最大连接数是 50而应用部署了 4 个节点每个节点 50 个连接。一看应用日志发现有个定时任务每 5 分钟会把连接池里的连接全部占用导致业务线程全部在等连接。定位后把定时任务改成独立连接池重新压测500 并发下 TPS 直接到了 4000问题解决。这个案例想说明的是压测排障数据先行。没有完整的监控链路你只能靠猜有了数据根因往往自己就浮出来了。5. 压测数据模型设计并发用户、QPS、响应时间不是一回事正在转行或准备面试性能测试岗位的朋友这一章值得多看两遍。很多人张口闭口我要压 10000 并发但你要问他这 10000 并发对应多少 QPS他算不出来。这俩概念搞不清楚压测设计就是空中楼阁。5.1 并发用户数 ≠ QPS并发用户数是同一时间点有多少个活跃用户在做操作QPS / TPS是每秒系统处理的请求数或事务数。它们之间就差一个关键参数用户操作间隔时间think time。公式是QPS 并发用户数 / (平均响应时间 思考时间)举个例子系统平均响应时间是 200ms用户的思考时间是 2 秒用户看完页面再点下一个请求那么 1000 并发用户对应的 QPS 大概是1000 / (0.2 2) ≈ 454 QPS所以你在设计压测场景的时候先得想清楚你要的是满足多少用户同时在线的负载还是满足多高的每秒请求量的负载。这两个目标对应的线程组配置完全不同。5.2 阶梯加压与容量预估做负载测试时我强烈建议使用阶梯加压的方式而不是一上来就压满目标值。JMeter 可以用Stepping Thread Group插件实现阶梯并发比如每 30 秒增加 100 并发直到达到目标值并在每个梯度维持 1 分钟左右。阶梯加压的好处是能观察系统在每个并发梯度下的性能表现更精准地找到性能拐点。比如 300 并发时 TPS 是 1500400 并发时 TPS 还是 1500 且响应时间开始上涨那可以判断这系统的性能上限大概就在这个区间接着细看资源指标定位瓶颈。教你一个估算单节点性能上限的经验先压单节点找到该节点性能开始劣化的并发拐点记录拐点处的 TPS 和响应时间用这个数据反推集群需要多少节点支撑预期峰值流量比如单节点 300 并发时 TPS 1500线上大促预估峰值 QPS 是 15000那 15000 / 1500 10 个节点再留 50% 的冗余大概需要 15 个节点。这个估算法虽然粗糙但比拍脑袋可靠得多。5.3 从热词jmeter性能测试步骤看最常见的学习痛点最近看到很多人在搜jmeter性能测试步骤这类关键词说明有大量新人卡在第一步——不知道怎么把工具用起来。我在这里把最常见的 JMeter 性能测试流程整理成了一份可以直接照做的清单用 JMeter 5.x 版本为例安装 JDK1.8 均可配置 JAVA_HOME从官网下载 JMeter 二进制包解压后进入bin目录运行jmeter启动 GUI 模式右键测试计划 → 添加 → Threads → 线程组。线程数填 100Ramp-Up 时间填 10表示 10 秒内启动完 100 个线程循环次数勾选永远右键线程组 → 添加 → 配置元件 → HTTP 请求默认值。协议填 http服务器名称或 IP 填被测地址端口填 8080右键线程组 → 添加 → 取样器 → HTTP 请求。路径填/api/login请求方法选 POST在 Body Data 里填 JSON 参数右键线程组 → 添加 → 定时器 → 常数吞吐量定时器。配置吞吐量让请求频率更贴近真实场景右键线程组 → 添加 → 监听器 → 聚合报告。这个报告会给出平均响应时间、中位数、90% 线、95% 线、错误率、吞吐量等核心指标点击绿色启动按钮开始压测压测结束后保存聚合报告数据结合服务端监控数据进行综合分析跑完这一步一个最基本的压测流程就算跑通了。进阶的玩法包括使用 CSV 数据文件做参数化、用逻辑控制器实现业务流分支、使用正则表达式提取器做登录 token 关联等这些我在后面章节单独展开。6. 性能测试面试高频题型与现场思路拆解从热搜词里看到性能测试面试题、性能测试岗位常见面试题被频繁搜索这章节我给准备面试的朋友划几个最常被问的重点顺带分析面试官到底想听什么。6.1 如何确定压测的并发用户数这是送命题也是最容易暴露水平的题。标准套路是三段式回答依据业务目标和产品、运营对齐业务峰值目标。比如大促峰值目标是 10 万 DAU那核心链路的并发用户数可以根据核心链路日活占比 × 峰值同时在线率来计算参考历史数据如果系统已上线查看历史监控找出过去一段时间内真实的最高 TPS 和并发数作为压测目标的基础结合容量规划目标并发数 预估峰值 QPS × 平均响应时间 × 系数。系数一般取 1.5~2用于保留冗余把这三段说出来面试官就知道你既有理论框架又懂实际操作。6.2 性能测试和负载测试、压力测试的区别高频这个题考察的是你有没有真正理解概念之间的关系而不是背定义。我的回答框架性能测试是目标验证看系统在既定负载下能否达到性能指标负载测试是拐点探索通过逐步加压找到系统性能变化的规律和临界点压力测试是上限探测通过持续加压找到系统的极限并且关注系统崩溃后的恢复能力负载测试和压力测试都属于性能测试的范畴只是测试目的和看待负载的方式不同关键要加上一句真正的压测项目中这三者往往是混合使用的同一个测试计划中先做负载测试找拐点再做压力测试打极限。6.3 压测过程中发现 TPS 上不去你怎么排查这是一个综合题考察的是排障方法论。按我之前第 4 章总结的客户端 → 服务端 → 中间件分层分析法来答先确认压力机自身没有成为瓶颈CPU、内存、网络带宽是否打满再看应用层JVM GC 是否频繁、线程池是否打满、日志里是否有大量报错再看中间件数据库连接池、Redis 连接数、MQ 积压情况最后看基础设施CPU、磁盘 IO、网络带宽用控制变量法一次改一个配置逐层优化重新压测验证回答这道题时最好是结合一个自己做过的真实案例来讲哪怕是个很小的案例也比干巴巴说步骤要有说服力得多。提示面试官判断你是否有性能测试实战经验往往不是听你背概念而是听你讲排查问题的链路。你能把从发现现象到定位根因的完整过程讲清楚就已经赢了大多数人。7. 硬盘压力测试工具实操以固态硬盘为例热搜词里有一条固态硬盘压力测试用什么软件这个场景比接口测试更贴近日常也经常被忽略。这里单独讲一部分。在评估一块新硬盘的性能和稳定性时我常用的工具是CrystalDiskMark跑基准性能和HD Tune Pro做文件基准测试和错误扫描。但这只能算跑分不是真正的压力测试。做硬盘压力测试核心动作是持续写入大文件并观察掉速和温度。Windows 下可以用AIDA64的磁盘测试模块持续全盘写入 10 分钟以上观察写入速度曲线是否平稳、掉到多少、温度是否过高macOS/Linux 下可以用fio工具这个更专业一些。下面是一个 SSD 随机写的压力测试命令fio --namerandwrite --ioenginelibaio --iodepth32 --rwrandwrite --bs4k --direct1 --size1G --numjobs4 --runtime60 --time_based --group_reporting重点看两个指标IOPS 是否稳定、写入延迟的 99 分位是否飙升。如果写入速度出现断崖式下跌且温度已经超过官方工作温度上限说明散热或者固件温控策略有问题这个型号的硬盘在高强度下不靠谱。提示硬盘压力测试时间不宜太短至少持续写入 30 分钟以上才能让主控的磨损均衡、垃圾回收GC机制介入。短时间测试往往只覆盖了 SLC 缓存的性能测不出真实水平。8. 全景路线图三类测试如何组合使用最后补充一个全局视角把这三种测试在整个研发生命周期里的位置理清楚。很多团队把性能测试当作上线前的一次性大检这是不对的。合理做法是把它们穿插到不同的阶段阶段推荐测试类型主要观测点开发自测阶段轻量性能测试核心接口是否满足 SLA是否有明显的慢 SQL功能冻结后负载测试了解系统在当前架构下的性能基线和拐点上线前压力测试 稳定性测试探明系统极限和失败恢复能力验证限流降级预案大促前全链路压测验证整条调用链路的真实承载能力上线后定期负载测试发现代码演进带来的性能退化你会发现真正落到日常的是负载测试因为它在每个版本迭代中都能给出系统比上版本快还是慢的信号。而压力测试适合在架构调整、大促备战等关键节点集中做。我自己在项目里习惯用一套基线压测数据做版本对比每两周跑一次相同的负载测试把 TPS、P95 响应时间、错误率记录成基线出了性能回归马上就能发现。这个习惯比临时抱佛脚式的上线前压一下要有效得多。另外也想提醒一点网上很多教程喜欢强调工具的操作步骤但真正决定性能测试价值的是对被测系统的理解深度。你能说出系统都有哪些外部依赖、哪些接口是重逻辑、数据落在哪个存储引擎比你会操作十个压测工具重要得多。工具可以短期学会系统理解和性能分析能力只能靠一个个项目积累出来。如果你现在正准备投身性能测试方向我的建议是先找一条最简单的链路比如登录接口完整地走一遍脚本设计 → 数据准备 → 执行压测 → 监控采集 → 瓶颈定位 → 出具报告的全流程。走完这一遍你对性能测试的认知会有一个质的飞跃。