test: strengthen launch smoke and capacity guardrails

This commit is contained in:
Codex
2026-07-01 04:10:55 +08:00
parent 3d33c783cd
commit 6bdb2a175a
11 changed files with 494 additions and 39 deletions

View File

@@ -43,17 +43,21 @@
- 环境Windows + Docker Desktop + 本地 Supabase/PostgreSQL + 本地 API 进程。
- Docker Desktop 当前资源20 CPU、约 62.7GB 内存。这个本机结果会高于常见 4 核 16G 云服务器,不能直接作为生产 SLA。
- 数据库PocketBase 真实导入数据,并已包含前期写入压测产生的练习/答题记录。
- 当前库规模3 个租户、3,690 个用户、约 74,117 道题、1,601 个题目合集、3,106 个练习蓝图、3,505 个单词、2,678 条知识手册、196,846 条答题记录、38,207 条错题、466 条权益。
- 压测基线规模:约 7.4 万道题、3,700 个用户、1,600 个题目合集、3,100 个练习蓝图、3,500 个单词、2,600 条知识手册、19.6 条答题记录、3.8 万条错题、466 条权益。后续 `db:smoke-seed`、集成测试和压测会继续写入练习/答题/测试租户数据,因此这里按压测基线描述,不把每次测试后的瞬时行数当作 SLA 口径。
- 排行榜未纳入默认负载,因为产品默认关闭。
### 2026-07-01 最新复核
### 2026-07-01 真实迁移库 Docker API 受限资源复核
本轮使用 `npm run perf:api:docker-4c16g`API 容器限制为 2 CPU/4G、`DB_POOL_MAX=10`、关闭 legacy `x-user-id` 和平台本地 key压测鉴权使用 `PERF_AUTH_MODE=app_session` 的 Bearer session。数据库仍为本机 Docker Desktop Supabase/PostgreSQL未限制为 4 核 16G因此结果更接近“受限 API 容器 + 本机数据库”的预生产观察,不是最终云服务器 SLA。
压测先暴露出一个真实并发缺陷50 worker 混合读写中,交卷触发自动勋章发放时撞到 `user_badges_tenant_id_legacy_id_key`,产生 1 个 500。已修复为自动勋章只使用 `(tenant_id, user_id, badge_id)` 做业务幂等,不再写入自动生成 `legacy_id`;并新增 `scripts/auto-badge-concurrency-test.js`20 个并发触发同一学生同一勋章时只生成 1 条 `user_badges`
| 场景 | 并发 worker | 时长 | 刷题写入比例 | 请求数 | 错误率 | 吞吐 | P95 | P99 | 结论 |
| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | --- |
| 只读上线门禁 | 30 | 120s | 0% | 60,326 | 0.00% | 499.27 req/s | 151.29 ms | 214.61 ms | 通过 |
| 混合读写 | 50 | 60s | 10% | 35,608 | 0.00% | 584.18 req/s | 174.26 ms | 224.04 ms | 舒适 |
| 混合读写 | 100 | 60s | 8% | 33,843 | 0.00% | 554.42 req/s | 326.21 ms | 422.33 ms | 接近舒适区上沿 |
| 混合读写 | 150 | 60s | 6% | 32,364 | 0.00% | 528.81 req/s | 490.38 ms | 662.42 ms | 压力区 |
| 只读上线门禁 | 30 | 120s | 0% | 44,038 | 0.00% | 366.27 req/s | 185.80 ms | 254.08 ms | 通过 |
| 混合读写 | 50 | 60s | 10% | 25,327 | 0.00% | 419.62 req/s | 213.17 ms | 270.94 ms | 舒适 |
| 混合读写 | 100 | 60s | 8% | 25,378 | 0.00% | 417.77 req/s | 383.72 ms | 461.22 ms | 接近舒适区上沿 |
| 混合读写 | 150 | 60s | 6% | 23,444 | 0.00% | 384.39 req/s | 605.89 ms | 743.19 ms | 压力区 |
混合读写包含真实刷题闭环:创建练习 session、拉取 session detail、提交答案、交卷、读取报告。
@@ -65,10 +69,10 @@
按目前常见页面节奏先用 `0.05 到 0.2 req/s/人` 粗略折算:
- 50 worker 舒适场景 584 req/s约等于 2,920 到 11,680 名活跃在线学生的请求吞吐。
- 100 worker 上沿场景 554 req/s约等于 2,770 到 11,080 名活跃在线学生的请求吞吐。
- 150 worker 压力场景 529 req/s约等于 2,645 到 10,580 名活跃在线学生的请求吞吐。
- 50 worker 舒适场景 420 req/s约等于 2,100 到 8,400 名活跃在线学生的请求吞吐。
- 100 worker 上沿场景 418 req/s约等于 2,090 到 8,360 名活跃在线学生的请求吞吐。
- 150 worker 压力场景 384 req/s约等于 1,920 到 7,680 名活跃在线学生的请求吞吐。
当前本地结论:在 20 CPU/62.7GB Docker Desktop 环境下,后端真实刷题读写链路的舒适观察区间约为 550 到 585 req/s折算约 2,700 到 11,600 名活跃在线学生150 worker 仍 0 错误但 P95 接近 500ms视为压力区不建议作为生产承诺。
当前本地结论:在受限 API 容器下,后端真实刷题读写链路的舒适观察区间约为 418 到 420 req/s折算约 2,000 到 8,400 名活跃在线学生150 worker 仍 0 错误但 P95 已超过 600ms视为压力区不建议作为生产承诺。此前未限制 API 容器时本机可观察到约 550 到 585 req/s说明 API CPU/连接池约束会明显影响上沿。
正式对外容量必须等 4 核 16G 云服务器部署后复跑。保守规划时,生产首版建议先按本地折算值的 30% 到 50% 做容量承诺等云端压测、CDN、对象存储和真实前端埋点完成后再上调。