去年接手了一个供应链管理系统的性能优化项目,系统上线前需要验证核心接口的吞吐量。技术栈是Spring Boot + MySQL + Redis,压测工具选型时对比了JMeter和Locust,最终选了Locust——因为它的脚本用Python写,支持分布式,而且Web UI实时展示指标,对调试和演示都很友好。

目标与场景

目标是测试订单查询接口(GET /api/orders)和创建订单接口(POST /api/orders)的性能。需要模拟不同并发用户数(50、100、200)下的表现,观察响应时间和错误率。我设计了两类场景:一类是纯查询,模拟只读用户;另一类是混合操作,模拟真实用户既查询又创建。同时加入思考时间,让压力更贴近实际。

环境准备

  • Python 3.9+,安装Locust:pip install locust
  • Spring Boot应用已启动,接口可访问(本机或测试环境)
  • 准备一个测试账号和少量测试数据

编写测试脚本

先定义用户行为。使用Locust的TaskSet和HttpUser,设置等待时间模拟思考时间。

from locust import HttpUser, task, between import random class OrderUser(HttpUser): wait_time = between(1, 3) # 每个任务执行后等待1-3秒 @task(3) # 权重:查询任务占比3 def get_orders(self): # 参数化:随机订单ID,模拟不同查询 order_id = random.randint(1000, 9999) with self.client.get(f"/api/orders/{order_id}", name="查询订单", catch_response=True) as resp: if resp.status_code == 200: resp.success() else: resp.failure(f"查询失败: {resp.status_code}") @task(1) # 创建订单任务权重1 def create_order(self): payload = { "userId": random.randint(1, 100), "items": [{"productId": random.randint(1, 500), "quantity": random.randint(1, 5)}], "remark": "" } with self.client.post("/api/orders", json=payload, name="创建订单") as resp: if resp.status_code == 201: resp.success() else: resp.failure(f"创建失败: {resp.status_code}")
核心洞见:使用catch_response参数可以自定义成功/失败条件,不只看HTTP状态码,还能根据响应内容判断业务成功与否。

运行压测与分布式扩展

本地直接运行locust -f locustfile.py,打开http://localhost:8089设置并发数和孵化率。但单机可能成为瓶颈,我使用了分布式模式:一台主控,4台从机。

# 主控机(无Web UI时可用--headless) locust -f locustfile.py --master --host=http://192.168.1.100:8080 # 从机(每台执行) locust -f locustfile.py --worker --master-host=192.168.1.101

我分别跑了50、100、200并发,持续5分钟,每个场景之间间隔1分钟冷却。结果记录如下表。

结果分析与调优

从Locust的Web UI导出CSV报告,主要看三个指标:请求数/秒(RPS)、平均响应时间、错误率。

  • 50并发:RPS=320,平均响应时间=156ms,错误率0%
  • 100并发:RPS=580,平均响应时间=172ms,错误率0.1%(有超时)
  • 200并发:RPS=720,平均响应时间=278ms,错误率3.2%(大量超时和连接重置)

分析发现,瓶颈在数据库连接池。Spring Boot默认HikariCP最大连接数10,200并发时连接等待严重。我把连接池调到50,并开启Redis缓存热点订单数据。调整后,200并发下RPS提升到950,平均响应时间降到141ms,错误率降到0.2%。

调优关键:先看错误类型和响应时间分布,再结合数据库慢查询日志和连接池监控定位瓶颈,避免盲目增加服务器。

常见问题

  • 连接被重置:通常是服务端连接数或文件句柄耗尽,检查ulimit和Nginx配置。
  • 响应时间高但RPS低:检查是否有慢查询或锁竞争,用Arthas或JProfiler分析。
  • 分布式从机负载不均:确保任务分布均匀,可增加从机数量,并检查网络延迟。

总结

Locust用起来很顺手,Python脚本灵活,分布式扩展容易,报告也直观。这次压测帮我找到了连接池这个瓶颈,调优后性能提升明显。如果你也在做接口性能测试,可以试试Locust。我们铭锦数智也提供性能测试服务,有需要可以聊聊。