怎样实现自动生成压测报告

wen 实用脚本 32

本文目录导读:

怎样实现自动生成压测报告

  1. 总体流程
  2. 方案一:基于 JMeter + Ant/Maven/Gradle + Jenkins(最传统,适合 Java 团队)
  3. 方案二:基于 Locust + Python + Pandas + Jinja2 + Matplotlib(最灵活,适合 Python 团队)
  4. 方案三:基于 k6 + Grafana + InfluxDB + Bash(最 DevOps,适合云原生团队)
  5. 方案四:All-in-One 神器:wrk + wrk2 + 自定义 Shell(最轻量,适合 Linux 命令行)
  6. 如何选择?
  7. 最佳实践建议(重要)

实现自动生成压测报告,核心思路是:自动化执行压测 -> 结构化收集结果 -> 模板渲染/可视化 -> 自动分发

下面我会分几种常见的技术栈和场景,给出具体的实现方案。


总体流程

  1. 触发压测:CI/CD 流水线、定时任务或手动触发。
  2. 执行压测:使用压测工具(JMeter, Locust, k6, wrk, ab 等)。
  3. 收集结果:解析工具输出(JTL/CSV/JSON/日志)或直接调用 API。
  4. 计算指标:计算 P50/P90/P99 延迟、TPS、错误率、吞吐量等。
  5. 生成报告:通过模板引擎(HTML/PDF/Markdown)或可视化库(ECharts/Matplotlib)渲染。
  6. 分发报告:上传到内网服务器、发送邮件、发布到 Wiki/钉钉/飞书/企微。

基于 JMeter + Ant/Maven/Gradle + Jenkins(最传统,适合 Java 团队)

这是最成熟、最稳定的方案,适合长期存量的项目。

实现方式:

  1. 编写 JMeter 脚本.jmx)。
  2. 使用 Ant 或 Maven 调用 JMeter(非 GUI 模式)。
    jmeter -n -t test.jmx -l result.jtl -e -o ./report
    • -n 非 GUI 模式
    • -l 输出原始数据文件(.jtl)
    • -e -o 生成 HTML 报告(JMeter 自带 Dashboard Report)
  3. 使用模板引擎增强:如果自带的 Dashboard 不够用,可以写一个 Java 程序解析 .jtl,使用 FreeMarker 或 Thymeleaf 生成自定义报告。
  4. 集成到 Jenkins
    • 安装 Performance PluginJMeter Plugin
    • Pipeline 示例:
      pipeline {
          agent any
          stages {
              stage('Performance Test') {
                  steps {
                      sh 'jmeter -n -t test.jmx -l results.jtl -e -o html-report'
                      publishHTML(target: [reportDir: 'html-report', reportName: 'Performance Test'])
                  }
              }
          }
      }
    • 自动发送:使用 emailext 插件或 Email Extension Plugin 发送报告。

优点:生态成熟,文档丰富,开箱即用。 缺点:重量级,依赖 Java 环境,JTL 文件较大时解析慢。


基于 Locust + Python + Pandas + Jinja2 + Matplotlib(最灵活,适合 Python 团队)

非常适合微服务、REST API 的压测,报告可以高度自定义。

工具链:

  • 压测:Locust(locustfile.py
  • 结果收集:Locust 支持 CSV 导出(--csv=report
  • 数据处理:Pandas, Numpy
  • 图表绘制:Matplotlib, Plotly
  • 报告模板:Jinja2(HTML 模板)
  • 自动化:Python 脚本 + Crontab / Airflow / Jenkins

核心实现代码:

# generate_report.py
import pandas as pd
import matplotlib.pyplot as plt
from jinja2 import Template
import json, base64, io
# 1. 加载压测结果(Locust 输出的 CSV 文件:stats、exceptions、failures)
stats_df = pd.read_csv('report_stats.csv')
# 2. 计算关键指标
result = {
    "total_requests": stats_df['Request Count'].sum(),
    "failures": stats_df['Failure Count'].sum(),
    "avg_response_time": round(stats_df['Average Response Time'].mean(), 2),
    "p50": round(stats_df['50%'].mean(), 2),
    "p90": round(stats_df['90%'].mean(), 2),
    "p99": round(stats_df['99%'].mean(), 2),
    "rps": round(stats_df['Requests/s'].sum(), 2),
}
# 3. 生成图表(并转为 base64 嵌入 HTML)
fig, ax = plt.subplots()
ax.plot(stats_df['Name'], stats_df['Average Response Time'], label='Avg')
ax.plot(stats_df['Name'], stats_df['90%'], label='P90')
plt.xticks(rotation=45, ha='right')
plt.legend()
buf = io.BytesIO()
plt.savefig(buf, format='png')
buf.seek(0)
img_base64 = base64.b64encode(buf.read()).decode('utf-8')
# 4. Jinja2 模板渲染
template_str = """
<html>
<head><title>压测报告</title></head>
<body>
<h1>压测报告</h1>
<table border="1">
<tr><td>总请求数</td><td>{{ result.total_requests }}</td></tr>
<tr><td>失败数</td><td>{{ result.failures }}</td></tr>
<tr><td>平均响应时间</td><td>{{ result.avg_response_time }}ms</td></tr>
<tr><td>P50</td><td>{{ result.p50 }}ms</td></tr>
<tr><td>P90</td><td>{{ result.p90 }}ms</td></tr>
<tr><td>P99</td><td>{{ result.p99 }}ms</td></tr>
<tr><td>RPS</td><td>{{ result.rps }}</td></tr>
</table>
<img src="data:image/png;base64,{{ img }}" />
</body>
</html>
"""
template = Template(template_str)
html_output = template.render(result=result, img=img_base64)
# 5. 保存报告
with open('performance_report.html', 'w') as f:
    f.write(html_output)

优点:代码 100% 可控,可以集成任意 Python 库(NLP、异常检测等)。 缺点:需要自己写比较多的代码,压测性能略低于 Go/Rust 工具。


基于 k6 + Grafana + InfluxDB + Bash(最 DevOps,适合云原生团队)

k6 是一个现代化、轻量级的压测工具,自带 JavaScript 脚本引擎,非常适合 CI/CD 集成。

架构:

  • 压测k6 run script.js
  • 存储:InfluxDB(时序数据库)
  • 可视化:Grafana(直接连接 InfluxDB,自动生成仪表盘)
  • 自动化:k6 输出 JSON 统计结果,或直接调用 Grafana API 截图导出

实现方式:

  1. 编写 k6 脚本

    // script.js
    import http from 'k6/http';
    import { check, sleep } from 'k6';
    import { htmlReport } from "https://raw.githubusercontent.com/benc-uk/k6-reporter/main/dist/bundle.js";
    export const options = {
      vus: 10,
      duration: '30s',
    };
    export default function () {
      const res = http.get('http://test.k6.io');
      check(res, { 'status was 200': (r) => r.status == 200 });
      sleep(1);
    }
    export function handleSummary(data) {
      return {
        'report.html': htmlReport(data), // 使用社区插件生成美观的 HTML 报告
      };
    }
  2. 运行并生成报告

    k6 run script.js
    # 或者通过 --summary-export 输出 JSON
    k6 run --summary-export=summary.json script.js
  3. 集成 Grafana(自助式报告):

    • 安装 k6 插件 /grafana/k6
    • 将 k6 实时数据推送到 InfluxDB
      k6 run --out influxdb=http://localhost:8086/k6 script.js
    • 在 Grafana 创建仪表盘,设置自动刷新
    • 自动截图:使用 Grafana Image Renderer 插件
      curl "http://admin:admin@localhost:3000/render/d-solo/1/performance?orgId=1&from=now-5m&to=now&width=1000&height=500" --output report.png
    • 将图片嵌入运维周报或 CD 流水线。

优点:性能极高,云原生友好,Grafana 可视化无敌。 缺点:需要维护 InfluxDB + Grafana 基础设施(不过现在 Grafana Cloud 有免费额度)。


All-in-One 神器:wrk + wrk2 + 自定义 Shell(最轻量,适合 Linux 命令行)

适合快速、纯后端的单接口压测。

实现方式:

#!/bin/bash
# auto_benchmark.sh
URL="https://yourapi.com/endpoint"
DURATION="30s"
THREADS=4
CONNECTIONS=100
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
REPORT_FILE="report_$TIMESTAMP.html"
# 1. 执行 wrk 压测
wrk_output=$(wrk -t$THREADS -c$CONNECTIONS -d$DURATION --latency $URL 2>&1)
# 2. 解析关键指标
avg_latency=$(echo "$wrk_output" | grep 'Latency' | awk '{print $2}' | head -1)
requests_sec=$(echo "$wrk_output" | grep 'Requests/sec' | awk '{print $2}')
# 3. 生成简易报告
cat > $REPORT_FILE <<EOF
<html>
<head><title>Wrk Benchmark Report</title></head>
<body>
<h1>Benchmark Summary</h1>
<pre>$wrk_output</pre>
</body>
</html>
EOF
# 4. 发送到 API 或存储
curl -X POST "http://your-report-server/api/upload" -F "file=@$REPORT_FILE"
echo "Report generated: $REPORT_FILE"

优点:零依赖,极其轻量。 缺点:报告简陋,不支持复杂场景(有状态、多步骤 API 不行)。


如何选择?

对比维度 方案一(JMeter) 方案二(Locust) 方案三(k6+Grafana) 方案四(wrk+Shell)
团队语言 Java Python JS/Go 任意
协议支持 几乎所有协议 HTTP/WebSocket HTTP/gRPC/WebSocket HTTP
报告美观度 中等(Dashboard Report) 高(自定义) 极高(Grafana)
CI/CD 友好 中等(需 Jenkins 插件) 极高(Docker/无头模式) 极高
可扩展性 中等 中等
学习成本 低(但调优复杂) 极低
推荐场景 传统企业、全链路 微服务、REST API 云原生、DevOps 快速验证、单体服务

最佳实践建议(重要)

  1. 标准化输出:无论用哪种工具,都尽量把统计结果转换为统一的 JSON 格式(如 {tps: 100, p99: 200ms}),方便后续统合和比较。
  2. 版本控制:每次压测报告都应该标记 Git commit / 版本号,便于性能回归分析。
  3. 趋势图:把每次压测的 TPS 和延迟存入 InfluxDB / Prometheus,用 Grafana 展示长周期趋势,比只看单次 HTML 报告更有价值。
  4. 阈值断言:在自动化流水线中,压测脚本应包含断言(如 P99 < 500ms),未通过则标记流水线失败,防止性能劣化上线。

如果你能告诉我具体的技术栈(Java/Python/Golang)、使用场景(CI 流水线/日常巡检/对外交付)、以及团队规模,我可以帮你进一步细化方案。

抱歉,评论功能暂时关闭!