压测用例与验收阈值(MySQL 版本)
适用范围:当前版本服务端(Flask + MySQL),包含 Gogs 外部依赖与资源下载(zip 流式响应)。
1. 目标与原则
- 目标:在峰值并发 500 的前提下,给出可复用的压测用例与“商业化验收”阈值。
- 原则:
- 测试结果必须可复现:固定部署方式、固定数据库与 Gogs 网络条件、固定数据规模。
- “预期 4xx”不计入错误率:如未登录预览被 401、非 VIP 下载被 403;错误率统计非预期 4xx + 5xx + 网络/超时错误。
- Debug 模式禁止用于压测:必须关闭 Debug,使用生产 WSGI(例如 Nginx+Gunicorn/Waitress)。
2. 接口分层(用于设定不同阈值)
按调用链复杂度分 3 类:
- A 类(纯 DB / 轻接口):/me、/plans、/resources、/resources/{id}、/orders
- B 类(DB + Gogs 外部依赖):/resources/{id}/repo/refs、/repo/tree、/repo/file、/repo/commits、/repo/readme
- C 类(重流量下载):POST /resources/{id}/download(写 download_logs + 拉取/生成 zip 并流式返回)
接口定义位置参考:server/routes.py
3. 测试前置(必须满足)
- 服务端:
- Debug=off
- 生产 WSGI:多 worker(压测报告必须记录 worker/threads 配置)
- 数据库:
- MySQL 已切换为主库
- 记录 MySQL 版本、max_connections、slow_query_log 开启情况
- Gogs:
- 记录 base_url、网络位置(同机房/公网)、是否走代理
- 选定 1~3 个稳定仓库用于 repo 接口压测(包含 README 与若干目录/文件)
- 数据规模(建议最低):
- resources:>= 200
- users:>= 100
- download_logs:>= 1000
4. 用例矩阵(必须执行的 5 组)
用例 1:Smoke(上线前冒烟)
- 并发:10
- 时长:5 分钟
- 目标:0 非预期 5xx;关键接口延迟稳定;无数据库连接池相关报错
用例 2:Baseline(日常稳定基线)
- 并发:50
- 时长:20 分钟
- 目标:形成基线;观察 MySQL 连接数与慢查询;为后续优化提供对比
用例 3:Peak(峰值验收)
- 并发:ramp 到 500(建议 5 分钟爬升)+ 稳态 10 分钟
- 目标:满足第 6 节的验收阈值(p95/p99/错误率)
用例 4:Soak(稳定性/泄漏)
- 并发:200
- 时长:60–120 分钟
- 目标:错误率不爬升;内存不持续增长;MySQL 连接不泄漏;Gogs 不被打爆
用例 5:依赖故障(Gogs 降级验收)
- 方法:让 Gogs 延迟显著升高/偶发 5xx/不可达(或压测端注入超时)
- 目标:
- A 类接口仍达标
- B 类接口错误可控且返回明确错误码
- 服务不雪崩(错误率不随着时间持续上升)
5. 流量模型(按真实路径建议)
并发 500 建议拆两类虚拟用户(VU)并行跑,比例可按实际调整:
场景 S1:游客浏览(60% VU)
- GET /resources(35%)
- GET /resources/{id}(20%)
- GET /resources/{id}/repo/tree(15%)
- GET /resources/{id}/repo/file(10%,其中一部分应预期 401)
- GET /resources/{id}/repo/readme(10%)
- GET /me(10%)
场景 S2:登录用户浏览 + 下载(40% VU)
- POST /auth/login(每个 VU 启动时 1 次)
- GET /resources、/resources/{id}、/repo/tree、/repo/refs(同上但比例略降)
- POST /resources/{id}/download(3%–8%,建议从 3% 开始)
- POST /orders(可选 1%)+ GET /orders(可选 2%)
6. 验收阈值(商业化标准)
6.1 全局阈值(所有用例共同)
- 非预期错误率:< 0.1%(按请求数口径)
- 5xx:Peak/Soak 用例中 = 0
- 超时/网络错误:< 0.05%
- 稳定性:无进程崩溃/重启;Soak 期间无持续线性内存增长
6.2 A 类接口(纯 DB / 轻接口)
目标:95 线 < 300ms(并按接口细化)
- GET /me:p95 < 120ms;p99 < 250ms
- GET /plans:p95 < 150ms;p99 < 300ms
- GET /resources(pageSize=12/20):p95 < 250ms;p99 < 450ms
- GET /resources/{id}:p95 < 200ms;p99 < 350ms
- POST /auth/login:p95 < 250ms;p99 < 450ms
6.3 B 类接口(DB + Gogs 外部依赖)
说明:外部依赖主导,阈值放宽但要求稳定与可解释错误。
- GET /resources/{id}/repo/refs:p95 < 900ms;p99 < 1500ms;错误率(依赖 502)< 0.5%
- GET /resources/{id}/repo/tree:p95 < 900ms;p99 < 1500ms;错误率 < 0.5%
- GET /resources/{id}/repo/file(小文件预览):p95 < 1000ms;p99 < 2000ms
- GET /resources/{id}/repo/commits:p95 < 1000ms;p99 < 2000ms
- GET /resources/{id}/repo/readme:p95 < 900ms;p99 < 1500ms
6.4 C 类接口(下载)
下载不建议用“完整下载耗时 p95”作为唯一指标,拆分两段:
- POST /resources/{id}/download:
- 首包时间(TTFB):p95 < 1500ms;p99 < 3000ms
- 失败率:< 0.2%
- 正确性:zip 可解压,内容抽样一致(抽样 >= 20 次)
7. 系统侧观测(必须记录)
- MySQL:
- 峰值活跃连接数不超过 max_connections 的 70%
- slow_query_log 中慢查询占比 < 1%(Peak/Soak)
- 无持续锁等待堆积(重点关注 orders、download_logs 写入)
- 应用:
- CPU:Peak 稳态平均 < 70%(留余量)
- 内存:Soak 期间无持续线性增长
- 日志:无大量数据库断连/重连异常
- Gogs:
- 记录依赖接口失败率与平均耗时;出现异常时是否触发错误放大
8. 报告模板(建议每次压测统一填写)
- 版本信息:commit/构建号、环境(Windows/Linux)、WSGI 方案与参数(workers/threads)
- 数据库:MySQL 版本、连接池参数、max_connections、慢查询配置
- Gogs:base_url、网络环境、选定 repo 列表
- 用例:Smoke/Baseline/Peak/Soak/依赖故障 的并发、时长、流量配比
- 结果(按接口分层给出):
- A 类:p50/p95/p99、吞吐、非预期错误率
- B 类:p50/p95/p99、依赖 502 占比、失败原因 TopN
- C 类:TTFB p95/p99、失败率、平均吞吐、正确性抽样结果