资讯详情

Locust压测实战:从协程并发原理到脚本编写与踩坑指南

📅 2026/10/11 8:18:07 | 华诺云谱 👁 阅读
Locust压测实战:从协程并发原理到脚本编写与踩坑指南
1. 为什么是LocustPython协程并发模型与JMeter线程池的差异做性能测试的人大部分入门用的都是JMeter。我一开始也是界面操作直观录制脚本也方便跑起来之后看聚合报告响应时间、吞吐量、错误率一目了然。但用久了会碰到几个让人不太舒服的地方脚本维护越来越重、参数化逻辑写起来很绕、要跟开发团队协作时脚本没法放到Git里做版本管理更别提用Python写复杂业务逻辑。后来我因为在项目里反复试Locust写压测脚本才真正意识到它跟JMeter是两种完全不同的物种。之所以说“不同物种”核心在于并发模型的差异。JMeter的并发是基于线程池的每一个虚拟用户就是一条Java线程线程有栈、有内存开销跑几千个并发时线程上下文切换的成本会非常明显。Locust完全换了一条路它用的是gevent协程底层基于Greenlet实现在一个操作系统线程里可以挂成千上万个协程。协程切换是用户态的不需要操作系统参与调度所以单机就能模拟出很高的并发数内存占用和CPU开销都更可控。打个比方JMeter像是一家餐厅开了很多个包间每个包间配一个服务员客人多了就得不停加人Locust更像一个大食堂一个服务员同时照看多桌靠记性好来切换注意力桌子再多也不会把人力成本线性拉上去。这引出了一个很重要的实际含义并发数不等于线程数。你在Locust里写--users 5000并不意味着你的压测机要开5000条系统线程。它只是创建了5000个协程任务在事件循环里轮转机器的资源消耗要小得多。我做过一个对比实验同一台4核8G的云主机JMeter跑到2000线程时CPU已经快被打满而Locust用同样的机器跑5000协程CPU占用也就60%上下这还是在脚本里写了业务断言的情况下。还有一个隐性优势是脚本的可读性和可维护性。Locust的测试脚本就是纯Python代码定义HttpUser、定义task列表、用task装饰器标注任务方法逻辑一目了然。对于团队里同时会Python的开发和测试同学来说压测脚本可以直接review直接改直接跑CI。做接口自动化那套的断言、数据驱动、日志打印全都能复用Python生态。相比之下JMeter的.jmx文件是一大坨XML人工维护和代码审查都极其痛苦。当然Locust也不是万能药。它默认是HTTP层面的压测如果你想做JDBC压测、JMS消息压测这类协议Locust支持得不如JMeter开箱即用。虽然也能写自定义client但成本不低。所以我在团队里的建议很简单只要被测服务的入站协议是HTTP或基于HTTP的REST接口并且团队有Python基础直接用Locust。否则老老实实用JMeter别跟工具较劲。这一篇重点面向第一次接触Locust的读者。我会从安装开始带你写第一个压测脚本把命令行和Web UI的常用操作讲透再补充几个高频的进阶写法最后把我实际踩过的坑一并列出来。读完这篇你应该能自己独立跑一个像样的压测任务。2. 环境准备与核心对象安装、HttpUser、任务、等待时间2.1 安装Locust的安装非常无脑它是个纯Python库pip装就行。我建议在任何新项目里都用虚拟环境隔离依赖别一股脑装到系统Python里。具体步骤python3 -m venv locust-env source locust-env/bin/activate pip install locust装完之后直接在命令行验证locust --version如果能看到类似locust 2.x.x from ...的输出说明安装成功了。需要注意的一点是Locust这个项目的迭代速度不慢主版本从1.0到2.0变化挺大很多教程是很多年前的写法。如果你看到网上老教程里的from locust import Locust这种写法在2.x里已经废弃了统一用HttpUser。你装的时候直接装最新稳定版就行我这篇的内容基于2.x版本。如果你是那种连Python环境都不太熟的人也别慌。装Python的时候记得勾选Add Python to PATH虚拟环境激活之后输入locust命令有效就算过了环境这道关。2.2 三个核心概念HttpUser、task、wait_time如果把Locust脚本拆到最简你只需要理解三样东西第一是HttpUser它是虚拟用户的基类。你写一个类继承HttpUser就相当于定义了一种压测用户。这个用户身上带着一个client它的类型是HttpSession底层基于requests库。所以你可以在任务里直接写self.client.get(/api/users)这跟用Python requests发请求没有本质区别只是它自动帮你挂上了统计和上报逻辑。第二是任务用task装饰器标注。一个HttpUser类里可以定义多个任务方法Locust会按权重随机抽取方法去执行这就模拟了真实用户掺杂着做多种操作的行为。比如一个电商项目用户有的在浏览首页有的在搜索商品有的在下单那你就定义三个任务按实际业务占比配权重。第三是wait_time它模拟用户思考时间。真实用户不可能每秒钟都发一个请求他总要看一会儿页面、想一下要点哪里。wait_time就是用来控制两次任务之间停顿多久的。常用的写法是wait_time between(1, 5)表示每次任务执行完后随机等1到5秒再进行下一次。这一条特别重要我见过不少新手不写wait_time结果压测机疯狂发请求把被测服务直接打挂最后还把锅甩到服务头上。没有等待时间的压测更像是一种DDoS攻击而不是模拟真实用户。2.3 一个最小可运行的Demo下面这十几行代码就是Locust压测脚本的最小骨架。把它存成locustfile.py放在当前目录然后直接命令行执行locust它就能跑起来。from locust import HttpUser, task, between class WebsiteUser(HttpUser): wait_time between(1, 5) task(3) def view_homepage(self): self.client.get(/) task(1) def view_item(self): self.client.get(/item/10001)这里task(3)和task(1)是权重。意思是压测过程中每执行3次首页浏览才执行1次商品页浏览。如果你希望两个操作发生的频率差不多权重就写一样如果想让某个操作占比高就把它的权重调大。权重这个机制非常好用你公司的业务后台如果能看到真实的接口调用比例完全可以按比例映射到任务权重上。self.client.get(/)里面的路径是相对路径这是Locust一个很方便的设计。域名和端口不用写在每个请求里而是在启动命令里用--host指定或者直接看Web UI里的输入框。脚本和运行环境解耦同一个脚本测测试环境、预发环境只需要换host参数非常方便。2.4 本地快速验证脚本写完脚本别急着上并发先单用户跑一下确认请求路径没问题。有两种方式一种是在命令行里跑locust --host https://your-api.example.com --users 1 --spawn-rate 1 --run-time 10s --headless另一种是直接在Python环境里手动调用一下task方法做冒烟验证。我在实战中更推荐后者因为某些接口有鉴权、有签名如果脚本里写错了headless跑起来后会刷出一大片失败请求其实问题出在脚本本身而不是服务。手动验证的方式很简单user WebsiteUser() user.client.get(/)不过直接实例化HttpUser在某些版本里会有点小问题更稳妥的方式是先启动环境再执行短时间压测。我通常是这么干的起一个头部无界面模式10秒跑一个并发然后立刻看失败率。失败率是0再放开跑。3. 命令行启动与Web UI监控完整操作链路3.1 命令行参数逐个拆解Locust有两种运行模式无界面模式和Web模式。无界面模式适合在CI或服务器上跑一条命令搞定跑完自动退出并输出结果。我来拆几个最常用的参数。locust -f locustfile.py --host https://api.example.com --users 100 --spawn-rate 10 --run-time 5m --headless-f指定脚本文件默认就会找当前目录下的locustfile.py所以如果文件名就叫这个-f都可以省略。--host指定被测目标的基础地址脚本里的相对URL会拼在这里。--users是最终要达到的并发用户数--spawn-rate是每秒启动多少用户。最需要注意的就是--spawn-rate它的作用不是瞬间拉到几百并发而是让用户数逐步增加。为什么要有这个参数因为压测最忌讳一上来就把全部压力砸过去一方面会对服务造成不必要的冲击另一方面你也看不到系统在爬坡过程中的表现。真实的线上流量是逐渐涨起来的压测也应该模拟这个过程。--run-time指定运行多久格式可以是10s、5m、1h。不加这个参数headless模式会一直跑到你手动CtrlC为止。在CI里跑一定要加否则流水线永远结束不了。还有一对参数容易被忽略--csv和--csv-full-history。它们能把压测中的指标定时写入CSV文件方便事后画图或做报告。比如locust -f locustfile.py --headless --users 200 --spawn-rate 20 --run-time 5m --csvresult --csv-full-history--csvresult的意思是生成一个前缀为result的CSV文件--csv-full-history会在运行过程中每隔几秒保存一次完整快照最终你会得到result_stats.csv、result_stats_history.csv、result_failures.csv等好几个文件。在没有配套监控面板的团队里这组参数是生成压测报告的重要数据来源。3.2 Web UI 到底看什么不传--headless直接跑locust启动后命令行会提示你访问http://localhost:8089。这个内置Web UI是Locust最让人喜欢的地方之一因为压测过程中你能实时看到数据而且可以随时在界面上调整并发数不用重启任务。Web UI里有几个核心区域我建议你重点关注四个指标第一个是Number of Users当前已启动的虚拟用户数。配合曲线图你可以直观看到爬坡过程是否平滑。第二个是Requests per SecondRPS即每秒请求数。这个是吞吐量的核心指标反应服务在处理能力层面的实际表现。很多新手会有个误区以为并发数高RPS就一定高。实际不一定如果单请求耗时很长高并发下RPS反而可能上不去因为请求都堵在排队了。RPS 并发数 / 平均响应时间这个关系比学性能测试的人一定要刻在脑子里。第三个是Response Time曲线重点看95%分位和99%分位的响应时间。算术平均值很容易被极值拉偏一个超时5秒的请求能把整体平均值拉高一大截但95分位能更真实反映大多数用户的感受。接口服务的SLA如果签了95%请求在200ms以内你重点盯的就是这个数。第四个是Failures区域。走上线流程的压测我要求失败率必须为0哪怕0.1%的失败也不能忽略。但要注意失败并不一定都是被测服务的问题。我在后面会专门讲怎么区分网络层失败、脚本层失败和服务层失败。在Web UI上还有个很实用的功能设置界面里可以直接修改Host、Users和Spawn Rate然后点击Start swarming重新开始压测。这意味着你不需要因为调整并发数就去改脚本重启进程这在上线前的压测窗口期非常省时间。3.3 分布式运行基础单机跑Locust虽然已经很省资源但极端情况下还是会有瓶颈。什么情况比如压测单接口的RPS目标要上十万或者被测接口需要很大的测试数据集一台压测机的带宽、CPU、内存不够用。这时候就需要分布式模式。分布式模式的架构很简单一个master节点负责调度和汇总多个worker节点负责实际发请求。启动方式如下master节点locust -f locustfile.py --masterworker节点可以起多台locust -f locustfile.py --worker --master-host192.168.1.10需要注意几点第一所有节点的locustfile.py必须完全一致。这个坑我踩过某个worker节点的脚本版本旧了一点结果跑出来的数据和其他节点不一致整个压测结果直接作废。建议所有机器从同一个Git仓库拉取并固定版本号。第二worker节点不需要你手动指定并发数并发数只定义在master的启动命令里master负责分发任务。第三master和worker之间走的是带外消息通道如果你在云上部署记得安全组把这些端口放开否则worker报一堆Connection to master timed out错误。我在项目里用分布式最多的时候是在做全链路压测20台worker模拟数万用户比单机跑出来的数据可信得多。因为单机撑死能模拟几千到一万用户再多就容易出现压测机本身成为瓶颈的情况那测出来的根本是网络和机器上限不是被测服务的上限。4. 脚本进阶写法权重、参数化、断言与初始化让压测更贴近真实业务4.1 任务权重的真实业务映射前面那节说过task(3)、task(1)的用法但权重设计的合理性比这个语法本身重要得多。我之前做过一个电商项目一开始运营给的日常访问比例是首页:搜索:详情:下单 4:3:2:1。我们按这个权重直接跑了结果压测报告里发现下单接口的QPS远高于真实的日峰值。为什么因为真实用户看十次商品也未必会下单一次而且下单流程里还包含一堆前置校验和跳转不是说点一下提交订单按钮就完事了。后来我们把下单任务里加入了前置请求、加购物车、填写地址等多步操作同时把权重调成20:10:5:1数据才贴近线上。所以权重不是拍脑袋写的最好基于线上监控的接口调用比例来做映射。你的APM平台如果记录了各接口的每分钟调用次数直接拿过去按比例算就行。4.2 参数化别让所有用户都请求同一个URL新手最常见的错误是压测脚本里写死一个ID所有虚拟用户都在请求同一个资源。压测结果看着漂亮但服务端如果做了缓存那测出来的数据全是缓存命中率真实性能要打个大折扣。正确做法是让不同的请求带上不同的参数。最简单的参数化方式是随机从列表里取from locust import HttpUser, task, between import random USER_IDS [10001, 10002, 10003, 10004, 10005] class ApiUser(HttpUser): wait_time between(1, 2) task def get_user_profile(self): uid random.choice(USER_IDS) self.client.get(f/api/user/{uid})稍微复杂一点的场景是压测注册登录类接口。新建用户的账号密码不能全都一样否则数据库唯一索引直接报错。这时可以用循环队列或自增计数器来保证取到不同的值。在协程环境下你得注意多协程并发取同一份数据时的指向问题。我常用的做法是用itertools.countfrom itertools import count import string import random counter count(1) def gen_username(): idx next(counter) return floadtest_user_{idx}因为在同一份脚本里counter是全局对象gevent协程之间切换时next(counter)是线程安全的能保证每个用户拿到不同的用户名。这个设计简单可靠我大量使用于注册接口压测。再进阶一点如果参数需要按顺序循环使用比如测试一批预置的优惠券可以用一个共享队列每次从队尾弹出一个用完再塞回队首from collections import deque coupons deque([COUPON_A, COUPON_B, COUPON_C]) def next_coupon(): coupon coupons.popleft() coupons.append(coupon) return coupon这里有个细节deque的popleft和append在单进程内是原子的不用担心多个协程同时操作导致数据错乱但如果你用了多worker模式每个worker各自维护一份队列就会出现参数重复。这种情况我建议把测试数据提前写到Redis里用一个RPOPLPUSH命令实现跨进程的循环取参数或者直接用--csv参数传入一个外部CSV让每个worker独立读取各自的切片。总之压测数据的一致性设计需要从一开始就考虑进去。4.3 断言不是写个assert就完事了Locust允许你在任务方法里写Python断言失败时会记录成Failure。这个能力很重要因为压测不仅要看接口通不通还要看返回结果对不对。最常用的是检查HTTP状态码和关键字段task def create_order(self): with self.client.post(/api/order, json{goods_id: 101}, catch_responseTrue) as resp: if resp.status_code ! 200: resp.failure(fHTTP {resp.status_code}) elif resp.json().get(code) ! 0: resp.failure(fbusiness error: {resp.json().get(msg)}) else: resp.success()这里有几个关键点需要解释。第一catch_responseTrue表示不让请求库抛异常而是把响应交给你自己判断。用with包裹后你可以手动调用resp.failure()和resp.success()来标记本次事务成功还是失败。不写这个参数的话Locust只按HTTP状态码来判断2xx和3xx都算成功。但实际业务中接口返回200但业务code是5001的情况非常常见如果没有业务断言这种错误会被当成功记录压测报告的失败率接近于零但业务上已经挂了。第二assert关键字本身也可以写但不推荐在catch_response模式下直接assert因为异常会导致这个事务被标红但错误信息不够明确。我更习惯用resp.failure(具体原因)的方式这样在Failure列表里能看到具体是HTTP层失败还是业务code不匹配。第三响应体解析尽量做一次缓存。如果同一个请求的响应体被多处使用只在第一次解析时存一下不要每次断言都重新resp.json()因为性能测试脚本本身也消耗资源脚本写得拖泥带水压测机容易成为瓶颈。4.4 on_start与on_stop用户生命周期钩子on_start方法是虚拟用户启动时的初始化逻辑最常见的用途是登录。想象一下真实场景用户访问系统之前肯定要先登录拿到token之后才能访问后面的接口。在Locust里你不能在全局写一次登录然后让所有用户共享这个token因为每个虚拟用户都是独立个体Locust会为每个虚拟用户调用一次on_start。from locust import HttpUser, task, between class PlatformUser(HttpUser): wait_time between(1, 3) def on_start(self): resp self.client.post(/api/login, json{ username: fuser_{random.randint(10000, 99999)}, password: test123 }) data resp.json() self.token data[token] self.client.headers.update({Authorization: fBearer {self.token}})这段代码的运行顺序是每个虚拟用户被创建时先执行on_start完成登录接着才开始循环执行任务方法。所以后续所有任务里的请求都会自动带上请求头里的Authorization特别方便。on_stop则相反在虚拟用户生命周期结束时调用一般用来做清理工作比如删除测试数据、退出登录、关闭连接等。不过我在实际项目里用得很少因为压测结束后服务端的数据清理大多靠测试环境定期重置或者靠压测脚本本身在on_start里使用数据工厂。你可以把它想成一个善后出口用不用看具体场景不必强求。但这里也有个性能陷阱如果你的登录接口本身需要几十毫秒到几百毫秒那么在大规模压测时on_start的执行时间会显著拖慢爬坡速度。我遇到过一次spawn-rate设为20理论上1分钟能启动1200个用户但实际只启动了400个原因就是登录接口耗时300ms触发协程间阻塞。解决办法是把登录改成更轻量的换取token接口或者减小spawn-rate让用户缓慢建立又或者直接把登录依赖降到最低用预设token代替真实登录。5. 我踩过的坑Locust实战中的六个高频问题与解法5.1 客户端端口耗尽明明服务没挂压测机先扛不住了做高并发压测时最容易忽略的一个瓶颈是压测机自身的TCP端口耗尽。每个TCP连接的源端口是有限的默认范围大约在28000到61000之间大约三万多个。如果你压测的并发数高、每个请求的保持时间又长压测机自己的端口就会耗尽新连接直接失败。这时的现象是服务端负载并不高但失败率突然飙升错误信息显示Connection reset by peer或Address already in use。解法有几种一种是在代码里使用HTTP keep-aliveLocust的HttpSession实际上默认就是复用连接池的所以正常使用问题不大但如果你在脚本里手动创建了新的Session、关闭了连接或者每次请求都用headers{Connection: close}就会疯狂建连接。还有一种更实用的解法是修改系统内核参数扩大本地端口范围sudo sysctl -w net.ipv4.ip_local_port_range1024 65535同时缩短TIME_WAIT的连接回收时间sudo sysctl -w net.ipv4.tcp_fin_timeout15这两个参数在压测机上执行一次端口可用量就从三万多提升到六万左右。但对十万级RPS的压测需求来说这点还不够最稳妥的方案就是上分布式集群让多台worker分摊端口资源。5.2 数据量不足导致缓存覆盖把压力变成读缓存压力有一次我们测一个读多写少的服务脚本里随机读取的总共也就几十条商品记录服务端把热门商品缓存住了Redis命中率直接冲到95%以上压测结果好看到爆。但上线前最后一天真实流量一进来缓存全部穿透数据库被打到CPU 100%。问题根源就是压测数据量太小跟真实数据规模和分布差太远。做压测前先看看线上数据量级。如果线上有十万个商品ID压测脚本至少要准备几千到上万个不同的ID。宁可ID是假的只要数据库查不到就走正常兜底逻辑也好过所有请求都挤在同一个缓存key上。压测脚本里参数化的数据池大小我一般按可见数据集的10%以上来取。比如详情页可能被访问的商品有2万个压测池就预留2000个以上。这样Redis的分片和淘汰策略才能被真实触发。5.3 只看平均值被好看的平均响应时间骗了压测报告里最容易迷惑人的是平均响应时间。假设一个接口100个请求里99个返回20ms1个返回8秒平均响应时间大约是99.8ms看起来非常健康。但实际上有1%的用户经历了8秒的等待已经处于崩溃边缘如果遇上双十一流量那1%绝对用户量也很惊人。我习惯看两个指标95分位和99分位以及最长响应时间。Locust的Web UI里有一个响应时间分布图能直观看到分段延迟。脚本里也可以通过self.client.get(..., nameapi_query)给请求打标签这样每个接口的响应时间分布能分开统计而不是全部堆在一个池子里。另外压测过程中要留意响应时间曲线是否呈锯齿状。如果曲线每隔一段时间就出现一个尖峰很可能是定时任务、GC暂停、日志刷盘等行为在挤占资源。这时候光看并发数是发现不了的得结合响应时间分布和具体时间段来分析。遇到这种情况我的做法是把压测结果按10秒粒度导出CSV然后画折线图看尖峰出现的周期再去服务端找对应时间的日志和监控。5.4 脚本报错信息不明确被泛化的ConnectionError误导Locust报错时Failure列表里经常出现ConnectionError(Connection refused by the server)。看到这个错误我第一反应不是服务挂了而是先区分这个连接是被对端拒绝的还是被本机防火墙拦截的或者是连接池里清理了旧连接。最简单的方法是先用curl手动请求同一个接口curl -v https://api.example.com/api/health如果curl正常再检查压测机的安全组和IP白名单是否放通了压测机的出口IP。我在有一次穿云环境压测时服务端安全组只放行了办公网的IP压测机在另一个VPC里发请求结果全部被拒。排查了很久才发现不是服务问题。后来我养成了一个习惯压测任务开始前先跑一个curl做连通性验证而不是直接跑Locust然后看一堆ConnectionError。5.5 headless模式下忘记带--html压测报告没留存在CI体系里跑压测最后一定要生成一份报告文件留档。我见过不止一个同事跑完压测不保存报告结果需求方问上次压测结果是多少只能再花一晚上重新跑一遍。Locust支持直接导出HTML报告命令很简单locust -f locustfile.py --headless --users 100 --spawn-rate 10 --run-time 5m --host https://api.example.com --htmlreport.html--html会生成一个独立的HTML文件包含总览、图表、统计表可以直接发给团队或归档到流水线制品库。如果还需要原始数据前面说过的--csv参数一并加上报告和数据都要留。5.6 忘了固定Locust版本上次能跑这次全报错Locust版本更新比较快接口变动也不是完全没有。今天跑得好好的脚本过三个月再跑可能因为某个API废弃直接报错。所以我强烈建议在项目里锁定版本范围并且把依赖写进requirements.txtpip freeze | grep locust requirements.txt这样整个团队乃至CI环境都用同一套Locust版本避免在我机器上能跑在CI上报错这类尴尬。升级Locust时走代码审查流程升级完先跑一小轮冒烟测试再上正式压测。6. 压测结果怎么解读RPS、响应时间、失败率的三点经验6.1 以目标为导向反推压测参数拿到压测需求时第一条要问的不是测哪个接口而是我们要验证什么目标。目标不同压测参数完全不同。性能验收类的目标是在300并发下接口P95响应时间低于500ms无错误那压测命令就按300并发跑。容量测试的目标是这台服务器最多能支撑多少QPS那就得用阶梯加压从50并发慢慢加到1000观察RPS和响应时间的拐点。拐点的判断角度很关键。我一般会观察RPS曲线当并发数继续增加但RPS几乎不再增长甚至开始下降同时响应时间急剧抬升时这就是系统的容量上限。继续加并发只会让排队更严重压出来的数字已经不能反映系统的正常能力了。这类结论要写进压测报告里让运维人员知道该在哪里扩容、扩容多少。6.2 响应体大小对RPS的影响被很多人忽略同样的后端逻辑如果接口返回的JSON从50KB变成500KBRPS会差出一个数量级因为网络传输时间在请求总耗时中占比会上升。所以压测报告里一定要记录响应包大小的基线。我在脚本里用了一步记录响应体长度简单粗暴with self.client.get(/api/big_response, catch_responseTrue) as resp: content_length len(resp.content)然后压测前先确认这个长度与线上一致。如果测试环境造数的数据量比线上小很多导致响应体格外小那压测结果会严重偏乐观是个典型的测试环境与生产环境数据差异问题。造数的时候尽量按线上数据量级来别拿几条测试数据做容量测试。6.3 失败分类先分清哪层失败再谈定位看到压测脚本里有失败第一件事不是改服务端而是打开Failures列表看具体错误类型。我通常把失败分成三层第一层是网络层失败表现为ConnectionError、Timeout、ConnectionResetError。这类失败可能出在压测机本身、带宽、网关、负载均衡不一定是对端服务不可用。第二层是HTTP层失败比如4xx、5xx。5xx基本可以判定是服务端问题4xx则要看是不是压测脚本里的参数没传对、签名过期、鉴权失败。后者是脚本问题不算服务缺陷。第三层是业务层失败就是HTTP返回200但业务code不是0。这类最隐蔽但往往是最有价值的信息因为它能发现状态码监控发现不了的逻辑错误。我的做法是给任务里的每次请求在catch_responseTrue模式下完整分类HTTP状态码不是2xx的走HTTP失败分支业务code不为0的走业务失败分支。这样最终压测报告里的每个失败都能直接对应到具体原因而不是让它含糊地汇总成一个总数。6.4 压测结束后的数据清理和复盘压测结束后我还会做两件不太显眼但很有必要的事。一是检查压测产生的脏数据有没有留在被测环境尤其是注册、下单、支付类接口。很多项目压测完不清理导致测试环境数据库里堆积了一堆测试账号和订单后续功能测试跑起来各种撞数据。二是在团队内部花十五分钟复盘压测曲线和失败记录把压测过程中发现的异常点记到wiki或流水线记录中形成历史基线。下次再压测时还能对比这次和上次的曲线差异判断系统是变好了还是变差了。我个人的习惯是压测报告不只贴一张截图而是把命令、参数、脚本版本、环境信息、数据基线都完整记录。因为数据要能和下次压测做横向对比光有截图没有上下文是没法对比的。等到系统上线出了问题时再看压测报告里记录的容量上限和拐点往往能直接辅助定位问题方向。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑