forked from wangziqi/gongxue-base
test: record capacity guardrails
This commit is contained in:
@@ -43,7 +43,7 @@
|
||||
- 环境:Windows + Docker Desktop + 本地 Supabase/PostgreSQL + 本地 API 进程。
|
||||
- Docker Desktop 当前资源:20 CPU、约 62.7GB 内存。这个本机结果会高于常见 4 核 16G 云服务器,不能直接作为生产 SLA。
|
||||
- 数据库:PocketBase 真实导入数据,并已包含前期写入压测产生的练习/答题记录。
|
||||
- 当前本地迁移库规模:13 个租户、约 7.4 万道题、3,710 个用户、1,619 个题目合集、3,114 个练习蓝图、3,513 个单词、2,686 条知识手册条目、6.0 万练习 session、26.4 万条答题记录、3.8 万条错题、1,477 个内容资源、468 条权益。后续 `db:smoke-seed`、集成测试和压测会继续写入练习/答题/测试租户数据,因此这里按当前本地观察描述,不把每次测试后的瞬时行数当作生产 SLA 口径。
|
||||
- 当前本地迁移库规模:19 个租户、约 7.4 万道题、3,722 个用户、1,631 个题目合集、3,120 个练习蓝图、3,519 个单词、2,692 条知识手册条目、7.3 万练习 session、30.3 万条答题记录、3.8 万条错题、1,501 个内容资源、472 条权益。后续 `db:smoke-seed`、集成测试和压测会继续写入练习/答题/测试租户数据,因此这里按当前本地观察描述,不把每次测试后的瞬时行数当作生产 SLA 口径。
|
||||
- 排行榜未纳入默认负载,因为产品默认关闭。
|
||||
|
||||
### 2026-07-01 真实迁移库 Docker API 受限资源复核
|
||||
@@ -54,10 +54,10 @@
|
||||
|
||||
| 场景 | 并发 worker | 时长 | 刷题写入比例 | 请求数 | 错误率 | 吞吐 | P95 | P99 | 结论 |
|
||||
| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | --- |
|
||||
| 只读上线门禁 | 30 | 120s | 0% | 42,089 | 0.00% | 349.70 req/s | 202.20 ms | 295.16 ms | 通过 |
|
||||
| 混合读写 | 50 | 60s | 10% | 25,157 | 0.00% | 416.54 req/s | 215.00 ms | 292.56 ms | 舒适 |
|
||||
| 混合读写 | 100 | 60s | 8% | 23,873 | 0.00% | 394.18 req/s | 414.67 ms | 495.91 ms | 可用但延迟偏高 |
|
||||
| 混合读写 | 150 | 60s | 6% | 22,523 | 0.00% | 370.53 req/s | 621.55 ms | 750.70 ms | 压力区 |
|
||||
| 只读上线门禁 | 30 | 120s | 0% | 38,724 | 0.00% | 321.92 req/s | 225.17 ms | 338.35 ms | 通过 |
|
||||
| 混合读写 | 50 | 60s | 10% | 23,810 | 0.00% | 394.19 req/s | 235.96 ms | 320.19 ms | 舒适 |
|
||||
| 混合读写 | 100 | 60s | 8% | 23,384 | 0.00% | 386.14 req/s | 417.12 ms | 498.89 ms | 可用但延迟偏高 |
|
||||
| 混合读写 | 150 | 60s | 6% | 22,314 | 0.00% | 366.79 req/s | 613.15 ms | 744.50 ms | 压力区 |
|
||||
|
||||
混合读写包含真实刷题闭环:创建练习 session、拉取 session detail、提交答案、交卷、读取报告。
|
||||
|
||||
@@ -69,11 +69,11 @@
|
||||
|
||||
按目前常见页面节奏先用 `0.05 到 0.2 req/s/人` 粗略折算:
|
||||
|
||||
- 50 worker 舒适场景 416.54 req/s,约等于 2,080 到 8,330 名活跃在线学生的请求吞吐。
|
||||
- 100 worker 上沿场景 394.18 req/s,约等于 1,970 到 7,880 名活跃在线学生的请求吞吐。
|
||||
- 150 worker 压力场景 370.53 req/s,约等于 1,850 到 7,410 名活跃在线学生的请求吞吐。
|
||||
- 50 worker 舒适场景 394.19 req/s,约等于 1,970 到 7,880 名活跃在线学生的请求吞吐。
|
||||
- 100 worker 上沿场景 386.14 req/s,约等于 1,930 到 7,720 名活跃在线学生的请求吞吐。
|
||||
- 150 worker 压力场景 366.79 req/s,约等于 1,830 到 7,330 名活跃在线学生的请求吞吐。
|
||||
|
||||
当前本地结论:在受限 API 容器下,后端真实刷题读写链路的舒适观察区间约为 416 req/s,折算约 2,080 到 8,330 名活跃在线学生;100 worker 仍可用但 P95 已超过 400ms,150 worker 仍 0 错误但 P95 已超过 600ms,视为压力区,不建议作为生产承诺。受限 API 容器会明显压低上沿,因此上线承诺仍以云端受限资源复测为准。
|
||||
当前本地结论:在受限 API 容器下,后端真实刷题读写链路的舒适观察区间约为 394 req/s,折算约 1,970 到 7,880 名活跃在线学生;100 worker 仍可用但 P95 已超过 400ms,150 worker 仍 0 错误但 P95 已超过 600ms,视为压力区,不建议作为生产承诺。受限 API 容器会明显压低上沿,因此上线承诺仍以云端受限资源复测为准。
|
||||
|
||||
### 2026-07-01 Docker API + DB 显式受限复核
|
||||
|
||||
@@ -81,9 +81,9 @@
|
||||
|
||||
| 场景 | 并发 worker | 时长 | 刷题写入比例 | 请求数 | 错误率 | 吞吐 | P95 | P99 | 结论 |
|
||||
| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | --- |
|
||||
| 只读上线门禁 | 30 | 120s | 0% | 8,029 | 0.00% | 66.50 req/s | 1188.62 ms | 1697.71 ms | 失败,延迟超过门禁 |
|
||||
| 混合读写 | 50 | 60s | 10% | 7,088 | 0.00% | 115.82 req/s | 905.13 ms | 1211.98 ms | 失败,延迟超过观察线 |
|
||||
| 混合读写 | 100 | 60s | 8% | 6,383 | 0.00% | 103.63 req/s | 1720.26 ms | 2101.02 ms | 压力区 |
|
||||
| 混合读写 | 150 | 60s | 6% | 5,640 | 0.00% | 91.52 req/s | 2688.31 ms | 3284.99 ms | 压力区 |
|
||||
| 只读上线门禁 | 30 | 120s | 0% | 8,397 | 0.00% | 69.48 req/s | 1183.29 ms | 1697.59 ms | 失败,延迟超过门禁 |
|
||||
| 混合读写 | 50 | 60s | 10% | 6,640 | 0.00% | 109.61 req/s | 996.01 ms | 1303.45 ms | 失败,延迟超过观察线 |
|
||||
| 混合读写 | 100 | 60s | 8% | 6,381 | 0.00% | 104.13 req/s | 1705.51 ms | 2098.41 ms | 压力区 |
|
||||
| 混合读写 | 150 | 60s | 6% | 5,211 | 0.00% | 83.23 req/s | 3006.71 ms | 3699.64 ms | 压力区 |
|
||||
|
||||
这组结果说明:代码在更严格资源下仍保持 0 错误,但默认 PostgreSQL 参数无法支撑上线延迟门禁。正式对外容量必须等 4 核 16G 云服务器部署、PostgreSQL shared-host 调参、`pg_stat_statements` 和慢 SQL 观察完成后复跑。没有云端复测前,不再把本地 05:57 API-only 观察值当生产容量承诺,只保留为乐观参考;06:26 DB 受限结果则作为未调参下限参考。
|
||||
这组结果说明:代码在更严格资源下仍保持 0 错误,但默认 PostgreSQL 参数无法支撑上线延迟门禁。正式对外容量必须等 4 核 16G 云服务器部署、PostgreSQL shared-host 调参、`pg_stat_statements` 和慢 SQL 观察完成后复跑。没有云端复测前,不再把本地 06:44 API-only 观察值当生产容量承诺,只保留为乐观参考;06:53 DB 受限结果则作为未调参下限参考。
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
6. 公共题库商业化:平台公共/地区题库授权、租户快照采纳、手动同步、自动同步 worker、同步通知、冲突查询、租户自改冲突保护和单条/批量冲突处理已完成基础闭环;还需生产定时调度、失败告警和更完整运营后台消息。
|
||||
7. CRM/销售结算:CRM worker、跟进分配策略、学生批量 CRM 推送、跟进效果统计、销售/代理转化报表、死信失败池、脱敏日志、手动重试/忽略、分佣规则、结算单、审核、打款状态、导出和凭证复核基础闭环已完成;仍缺富卡片模板、外部失败告警升级、真实打款 provider、发票、转化预聚合和更细销售团队看板。
|
||||
8. AI 择校推荐增强:后端 `local_rules` 地基、SVIP 门禁、报告列表/详情、本人报告 Markdown/HTML 导出和 Taro 基础页已完成;仍缺真实 AI provider、prompt 编排、PDF worker 报告和后台运营配置。
|
||||
9. 题目反馈增强:站内通知后端第一版已完成;仍缺前端消息中心、外部订阅消息/短信提醒、问题聚合统计和内容修复闭环。
|
||||
9. 题目反馈增强:站内通知后端第一版、学生独立消息中心和租户反馈运营摘要已完成;仍缺外部订阅消息/短信提醒、更细问题聚合统计和内容修复闭环。
|
||||
10. 积分活动增强:积分兑换、活动任务、优惠券兑换履约、后台配置和积分风控只读报表第一阶段已完成;仍缺活动效果看板和更细系统任务触发。
|
||||
11. 勋章增强:后台维护、手动发放、签到/积分/反馈/活动任务/练习次数/单词掌握/模考成绩自动发放和发放站内通知已有;仍缺前端运营配置体验和更完整活动效果看板。
|
||||
|
||||
|
||||
@@ -95,9 +95,9 @@
|
||||
- 已补 `npm run launch:gate` 生产上线证据门禁和 `docs/refactor/production-launch-evidence.template.json` 模板;最终切换前必须把 readiness、远程 Auth、RLS、PostgreSQL 4c16g 严格调参证据、生产 dry-run、导入校验、`pb:import:sample` 业务抽样、真实数据 API 只读压测、真实数据混合读写压测、API/worker/Taro、运行时审计、`security:repo`、真实 `@codex-security`、备份/回滚/真实抽样/生产 provider 等证据填入本地 `production-launch-evidence.json` 并通过门禁。当前 Codex 环境未暴露可调用的 `@codex-security` 扫描工具时,该项只能标为待补,不能伪造完成。
|
||||
- 确认数据库迁移流程、备份恢复、日志、告警。
|
||||
- 准备 API 容器部署和 Supabase 云端/自托管连接方案。
|
||||
- 已补 `npm run perf:api:local`、`npm run perf:summary`、`npm run perf:postgres:evidence`、`npm run perf:postgres:sql`、`npm run smoke:launch-persona`、`npm run smoke:taro:h5`、`npm run smoke:taro:h5:interaction`、`node scripts/taro-api-contract-test.js`、`node scripts/taro-persona-contract-test.js` 和 `docs/refactor/performance-benchmark-runbook.md`,可在本地或云端对真实迁移数据做只读门禁、混合读写容量观察、PostgreSQL 4c16g profile 调参证据、三类后端角色旅程烟测、三类 Taro 前端角色旅程契约、H5 发布目录启动烟测、真实浏览器关键点击烟测和前端 API 契约检查。2026-07-01 05:57 API-only 受限容器复核中,50 worker/60s/10% 写入为 25,157 请求、0 错误、416.54 req/s、P95 215.00ms、P99 292.56ms;2026-07-01 06:26 进一步显式限制 DB 容器为 2 CPU/8G 后,30 worker 只读为 8,029 请求、0 错误、66.50 req/s、P95 1188.62ms,50 worker/60s/10% 写入为 7,088 请求、0 错误、115.82 req/s、P95 905.13ms,均未通过上线延迟门禁。受限容器系列压测曾抓到自动勋章并发发放唯一键冲突,已修复并新增 `scripts/auto-badge-concurrency-test.js`。当前结论是:本地 API-only 结果只能作为乐观观察,DB 受限未调参结果作为悲观下限;正式容量仍以上云 4 核 16G、PostgreSQL shared-host 调参、真实前端埋点和生产对象存储/CDN 复测为准。
|
||||
- 已补 `npm run perf:api:local`、`npm run perf:summary`、`npm run perf:postgres:evidence`、`npm run perf:postgres:sql`、`npm run smoke:launch-persona`、`npm run smoke:taro:h5`、`npm run smoke:taro:h5:interaction`、`node scripts/taro-api-contract-test.js`、`node scripts/taro-persona-contract-test.js`、`node scripts/product-scope-guardrails-test.js` 和 `docs/refactor/performance-benchmark-runbook.md`,可在本地或云端对真实迁移数据做只读门禁、混合读写容量观察、PostgreSQL 4c16g profile 调参证据、三类后端角色旅程烟测、三类 Taro 前端角色旅程契约、H5 发布目录启动烟测、真实浏览器关键点击烟测、前端 API 契约检查和产品口径防回归检查。2026-07-01 06:44 API-only 受限容器复核中,50 worker/60s/10% 写入为 23,810 请求、0 错误、394.19 req/s、P95 235.96ms、P99 320.19ms;2026-07-01 06:53 进一步显式限制 DB 容器为 2 CPU/8G 后,30 worker 只读为 8,397 请求、0 错误、69.48 req/s、P95 1183.29ms,50 worker/60s/10% 写入为 6,640 请求、0 错误、109.61 req/s、P95 996.01ms,均未通过上线延迟门禁。受限容器系列压测曾抓到自动勋章并发发放唯一键冲突,已修复并新增 `scripts/auto-badge-concurrency-test.js`。当前结论是:本地 API-only 结果只能作为乐观观察,DB 受限未调参结果作为悲观下限;正式容量仍以上云 4 核 16G、PostgreSQL shared-host 调参、真实前端埋点和生产对象存储/CDN 复测为准。
|
||||
- 当前本地 PostgreSQL evidence 仍提示 `jit=on`、`statement_timeout=0`、`idle_in_transaction_session_timeout=0`、`lock_timeout=0`;上云后必须按 `docs/refactor/postgresql-4c16g-tuning.md` 调整参数,执行 `PG_TUNING_PROFILE=shared-host npm run perf:postgres:evidence -- --strict --json` 并通过后,再按 6/30/50/100 阶梯并发复跑容量报告并归档到本地上线证据。
|
||||
- 本轮剩余功能和容量复核已经整理到 `docs/refactor/backend-open-items-and-capacity-20260701.md`。后续不要再把学生头像上传或默认排行榜当作待办;头像只保留男女预设,排行榜仅作为租户显式开启后的活动能力。
|
||||
- 本轮剩余功能和容量复核已经整理到 `docs/refactor/backend-open-items-and-capacity-20260701.md`。后续不要再把学生头像上传、默认排行榜或已完成的学生消息中心当作待办;头像只保留男女预设,排行榜仅作为租户显式开启后的活动能力。`scripts/product-scope-guardrails-test.js` 已纳入 `npm run test:readiness`,用于阻断这些旧口径回流。
|
||||
|
||||
### P1 商用功能完善
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
- 环境:本地 Docker Desktop + 本地 Supabase/PostgreSQL + 本地 API 进程。
|
||||
- 数据:PocketBase 真实导出数据导入新 PostgreSQL 后压测。
|
||||
- 数据规模:当前真实迁移库已包含前期压测写入记录,约 74,117 道题、1,601 个题目合集、3,106 个练习蓝图、3,505 个单词、2,678 条知识手册、3,690 个用户、196,846 条答题记录、38,207 条错题和 466 条权益。
|
||||
- 数据规模:当前真实迁移库已包含前期压测写入记录,约 19 个租户、74,131 道题、1,631 个题目合集、3,120 个练习蓝图、3,519 个单词、2,692 条知识手册、3,722 个用户、72,710 个练习 session、302,585 条答题记录、38,207 条错题、1,501 个内容资源和 472 条权益。
|
||||
- Docker Desktop 资源:当前本机约 20 CPU、62.7GB 内存,高于常见 4 核 16G 云服务器;本地结果只用于观察代码和索引趋势。
|
||||
- 写入流量:混合场景开启真实刷题闭环,包含创建 session、拉取 session detail、提交若干答案、交卷和读取报告。
|
||||
- 商城说明:本地库的订单数据会受 seed、烟测和导入演练影响,当前容量结论聚焦题库读写链路,不用于推断 GMV、支付或订单峰值。
|
||||
@@ -149,11 +149,43 @@
|
||||
|
||||
按 50 worker 混合读写 115.82 req/s 粗略折算,理论请求吞吐约对应 580 到 2,316 名活跃在线学生,但因为该轮未完成 PostgreSQL 调参且只在本地 Docker Desktop 上运行,只能作为“未调参受限资源下限观察”,不能作为首版生产规划值。首版生产规划仍以上云调参后复测为准。
|
||||
|
||||
### 2026-07-01 06:44 Docker API 受限资源复核
|
||||
|
||||
本轮在新增 `scripts/product-scope-guardrails-test.js` 并完成 `npm run test:readiness`、`npm run security:repo`、`npm run audit:runtime`、API/worker/Taro 类型检查、`npm run smoke:taro:h5`、`npm run smoke:taro:h5:interaction` 和 `npm run smoke:launch-persona` 后复跑。压测入口仍为 `npm run perf:api:docker-4c16g`,API 容器限制为 2 CPU/4G,`DB_POOL_MAX=10`,压测鉴权使用 `PERF_AUTH_MODE=app_session`。数据库未额外限制,仍可使用 Docker Desktop 全局资源;排行榜未纳入默认负载。
|
||||
|
||||
| 场景 | 并发 worker | 时长 | 刷题写入比例 | 请求数 | 错误率 | 吞吐 | P95 | P99 | 门禁结论 |
|
||||
| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | --- |
|
||||
| 只读上线门禁 | 30 | 120s | 0% | 38,724 | 0.00% | 321.92 req/s | 225.17 ms | 338.35 ms | 通过 |
|
||||
| 混合读写 | 50 | 60s | 10% | 23,810 | 0.00% | 394.19 req/s | 235.96 ms | 320.19 ms | 通过 |
|
||||
| 混合读写 | 100 | 60s | 8% | 23,384 | 0.00% | 386.14 req/s | 417.12 ms | 498.89 ms | 上沿观察 |
|
||||
| 混合读写 | 150 | 60s | 6% | 22,314 | 0.00% | 366.79 req/s | 613.15 ms | 744.50 ms | 压力区 |
|
||||
|
||||
本轮 `npm run perf:summary` 校验结果:
|
||||
|
||||
- 30 worker 只读门禁通过,满足 `errors=0`、`errorRate<=0.001`、`p95<=300ms`、`p99<=800ms`、`duration>=120s`。
|
||||
- 50 worker 混合读写满足 `P95<=500ms/P99<=1200ms`,仍是当前受限 API 容器下的舒适观察区。
|
||||
- 100/150 worker 均 0 错误,但 P95 已进入上沿/压力区,不作为生产承诺。
|
||||
|
||||
按 0.05 到 0.2 req/s/人的页面节奏粗略折算,50 worker 舒适吞吐约对应 1,970 到 7,880 名活跃在线学生请求吞吐;100 worker 上沿约对应 1,930 到 7,720 名;150 worker 压力区约对应 1,830 到 7,330 名。该数字仍是本地 API 受限、DB 未受限观察值,正式容量必须在目标云服务器和真实前端埋点下复跑。
|
||||
|
||||
### 2026-07-01 06:53 Docker API + DB 显式受限复核
|
||||
|
||||
本轮使用 `BENCHMARK_LIMIT_DB_RESOURCES=true npm run perf:api:docker-4c16g`,API 容器限制为 2 CPU/4G,Supabase PostgreSQL 容器限制为 2 CPU/8G,`DB_POOL_MAX=10`。PostgreSQL 参数仍是本地默认值,并未应用 `docs/refactor/postgresql-4c16g-tuning.md` 的 shared-host profile。
|
||||
|
||||
| 场景 | 并发 worker | 时长 | 刷题写入比例 | 请求数 | 错误率 | 吞吐 | P95 | P99 | 门禁结论 |
|
||||
| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | --- |
|
||||
| 只读上线门禁 | 30 | 120s | 0% | 8,397 | 0.00% | 69.48 req/s | 1183.29 ms | 1697.59 ms | 失败,超过 P95/P99 |
|
||||
| 混合读写 | 50 | 60s | 10% | 6,640 | 0.00% | 109.61 req/s | 996.01 ms | 1303.45 ms | 失败,超过 P95/P99 |
|
||||
| 混合读写 | 100 | 60s | 8% | 6,381 | 0.00% | 104.13 req/s | 1705.51 ms | 2098.41 ms | 压力区 |
|
||||
| 混合读写 | 150 | 60s | 6% | 5,211 | 0.00% | 83.23 req/s | 3006.71 ms | 3699.64 ms | 压力区 |
|
||||
|
||||
结论:资源更严格后系统仍保持 0 错误,但延迟不满足上线门禁。按 50 worker 混合读写 109.61 req/s 粗略折算,理论请求吞吐约对应 548 到 2,192 名活跃在线学生;由于该轮未调 PostgreSQL 参数且只在本地 Docker Desktop 上运行,只能作为“未调参受限资源下限观察”,不能作为首版生产规划值。
|
||||
|
||||
## 初步结论
|
||||
|
||||
- 本地高资源 Docker Desktop 历史结果显示代码和索引在 50/100 worker 下有较高吞吐;只限制 API 容器时,50 worker 混合读写 P95 约 215ms,100 worker P95 约 415ms,150 worker P95 约 622ms;进一步把 DB 容器也限制为 2 CPU/8G 后,30 worker 只读和 50 worker 混合读写均未通过延迟门禁。
|
||||
- 本地高资源 Docker Desktop 历史结果显示代码和索引在 50/100 worker 下有较高吞吐;只限制 API 容器时,最新 50 worker 混合读写 P95 约 236ms,100 worker P95 约 417ms,150 worker P95 约 613ms;进一步把 DB 容器也限制为 2 CPU/8G 后,30 worker 只读和 50 worker 混合读写均未通过延迟门禁。
|
||||
- 最新 DB 显式受限结果说明:不能仅凭本地 Docker API 受限跑分给生产承诺,生产 4C16G 必须先应用 PostgreSQL shared-host 调参并启用 `pg_stat_statements`,再跑正式只读/混合读写矩阵。
|
||||
- 生产如果使用 4 核 16G 单机,首版容量承诺不要再直接沿用 05:57 的 620 到 4,160 人估算;应先以云端调参后复测结果为准。没有云端复测前,可以把 05:57 结果看作“API 受限但 DB 未受限的乐观观察”,把 06:26 结果看作“DB 也受限但未调参的悲观观察”。
|
||||
- 生产如果使用 4 核 16G 单机,首版容量承诺不要直接沿用本地 API-only 的人数估算;应先以云端调参后复测结果为准。没有云端复测前,可以把 06:44 结果看作“API 受限但 DB 未受限的乐观观察”,把 06:53 结果看作“DB 也受限但未调参的悲观观察”。
|
||||
- 正式容量承诺必须在目标 4 核 16G 云服务器、生产 PostgreSQL 参数、对象存储/CDN、真实前端请求节奏和生产网络下复跑。
|
||||
|
||||
## 后续复测
|
||||
|
||||
Reference in New Issue
Block a user