3. 性能基准测试:使用 wrk/locust 进行接口压测,建立基线

在优化延迟之前,必须建立可量化的性能基线。本章将指导你使用 wrk(轻量级 HTTP 压测工具)和 Locust(分布式负载测试框架)对模型评分接口进行压测,并记录关键指标作为后续优化的参照基准。

3.1 为什么需要性能基线

没有基线,优化就是盲目的。基线提供了三个核心价值:

  • 量化起点:明确当前接口的 P50/P95/P99 延迟、吞吐量(RPS)和错误率。
  • 回归检测:每次代码变更后,通过对比基线判断是否引入性能退化。
  • 容量规划:根据基线数据推算单机承载能力,为扩缩容提供依据。
基线记录规范:每次压测结果应记录到版本控制系统的 perf/ 目录下,命名格式为 baseline_{日期}_{版本号}.json,确保可追溯。

3.2 工具选型对比

特性 wrk Locust
定位 单机高并发压测 分布式、场景化压测
协议支持 HTTP/1.1, HTTPS HTTP, gRPC, WebSocket
脚本语言 Lua(可选) Python
实时监控 命令行输出 Web UI + 图表
适用场景 快速获取延迟分布 模拟复杂用户行为

3.3 使用 wrk 建立快速基线

wrk 适合在开发环境快速验证接口性能。以下命令对评分接口进行 30 秒压测,使用 8 个线程、64 个连接:

wrk -t8 -c64 -d30s --latency \
  http://localhost:8080/v1/score \
  -s post.lua

其中 post.lua 脚本内容如下:

wrk.method = "POST"
wrk.body   = '{"features": [0.1, 0.2, 0.3, 0.4, 0.5]}'
wrk.headers["Content-Type"] = "application/json"

典型输出示例:

Latency Distribution (HdrHistogram - Recorded Latency)
 50.000%    8.12ms
 75.000%   12.45ms
 90.000%   18.76ms
 99.000%   34.21ms
 99.900%   52.80ms

Requests/sec:  1245.67
Transfer/sec:  1.23MB
关键指标解读:
- P50 (8.12ms):半数请求在 8ms 内完成,代表典型体验。
- P99 (34.21ms):1% 的请求超过 34ms,是长尾延迟的衡量标准。
- Requests/sec (1245.67):当前配置下的吞吐量上限。

3.4 使用 Locust 进行场景化压测

Locust 通过 Python 脚本定义用户行为,适合模拟真实调用模式。以下脚本模拟 100 个用户以 10 的生成率启动,持续 5 分钟:

from locust import HttpUser, task, between
import json

class ScoreUser(HttpUser):
    wait_time = between(0.5, 2.0)

    @task(3)
    def score_normal(self):
        payload = {"features": [0.1]*10}
        self.client.post("/v1/score",
                         json=payload,
                         headers={"Content-Type": "application/json"})

    @task(1)
    def score_batch(self):
        payload = {"instances": [[0.1]*10 for _ in range(5)]}
        self.client.post("/v1/score_batch",
                         json=payload,
                         headers={"Content-Type": "application/json"})

启动命令:

locust -f locustfile.py --host=http://localhost:8080 \
  --users=100 --spawn-rate=10 --run-time=5m \
  --headless --csv=baseline_report

生成的 baseline_report_stats.csv 包含每个时间点的平均响应时间、RPS 和失败率,可直接导入图表工具。

3.5 基线记录模板

每次压测后,将以下信息记录到基线文档中:

指标 值 说明
测试日期 2025-03-20 —
服务版本 v1.2.3 Git commit hash
硬件配置 4C8G, SSD CPU/内存/磁盘
并发用户数 100 Locust 峰值
P50 延迟 8.12 ms 中位数
P99 延迟 34.21 ms 长尾
吞吐量 (RPS) 1245.67 每秒请求数
错误率 0.02% 4xx/5xx 占比

3.6 压测流程与基线建立步骤

  1. 环境准备:确保服务独立部署,关闭日志输出、监控采集等干扰项。
  2. 预热:先发送 1000 个请求,让 JIT 编译和缓存达到稳态。
  3. 正式压测:使用 wrk 获取延迟分布,使用 Locust 获取场景化吞吐量。
  4. 数据收集:保存 wrk 的 HdrHistogram 输出和 Locust 的 CSV 报告。
  5. 基线归档:将结果存入 perf/baseline/ 目录,并更新 README。
常见陷阱:
- 不要在压测机上运行其他高负载进程(如浏览器、IDE)。
- 确保压测机与目标服务在同一内网,避免网络延迟干扰。
- 每次基线测试前,重启服务以清除前次测试的缓存影响。

3.7 基线建立流程示意图

下图展示了从环境准备到基线归档的完整流程:

性能基线建立流程 性能基线建立流程 环境准备 预热 (1000请求) wrk 延迟分布 Locust 场景压测 数据收集 基线归档 关键检查点 1. 关闭日志输出 2. 禁用监控采集 3. 内网压测避免干扰 4. 重启服务清缓存 5. 保存 HdrHistogram 6. 保存 Locust CSV 7. 更新 perf/baseline/ 8. 记录硬件配置 9. 标记 Git commit

3.8 基线对比与异常判定

建立基线后,后续每次优化迭代都应重新压测并与基线对比。以下表格给出异常判定阈值:

指标 正常波动范围 需关注 严重退化
P50 延迟 ±10% +20% +50%
P99 延迟 ±15% +30% +80%
吞吐量 (RPS) ±10% -20% -40%
错误率 ≤0.1% 0.5% ≥1%
自动化建议:将基线数据写入 Prometheus 或 InfluxDB,配合 Grafana 设置告警规则。当新版本的 P99 延迟超过基线 30% 时,自动触发 CI 流水线回滚。