docs: update launch capacity and postgres tuning

This commit is contained in:
Codex
2026-07-01 05:15:31 +08:00
parent 1eb5a13df7
commit c73722202e
8 changed files with 131 additions and 22 deletions

View File

@@ -43,7 +43,7 @@
- 环境Windows + Docker Desktop + 本地 Supabase/PostgreSQL + 本地 API 进程。
- Docker Desktop 当前资源20 CPU、约 62.7GB 内存。这个本机结果会高于常见 4 核 16G 云服务器,不能直接作为生产 SLA。
- 数据库PocketBase 真实导入数据,并已包含前期写入压测产生的练习/答题记录。
- 当前本地迁移库规模:约 7.4 万道题、3,700 个用户、1,600 个题目合集、3,100 个练习蓝图、3,500 个单词、2,600 条知识手册、25.2 万条答题记录、3.8 万条错题、468 条权益。后续 `db:smoke-seed`、集成测试和压测会继续写入练习/答题/测试租户数据,因此这里按当前本地观察描述,不把每次测试后的瞬时行数当作生产 SLA 口径。
- 当前本地迁移库规模: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 口径。
- 排行榜未纳入默认负载,因为产品默认关闭。
### 2026-07-01 真实迁移库 Docker API 受限资源复核
@@ -54,10 +54,10 @@
| 场景 | 并发 worker | 时长 | 刷题写入比例 | 请求数 | 错误率 | 吞吐 | P95 | P99 | 结论 |
| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | --- |
| 只读上线门禁 | 30 | 120s | 0% | 44,692 | 0.00% | 371.62 req/s | 188.91 ms | 275.79 ms | 通过 |
| 混合读写 | 50 | 60s | 10% | 26,815 | 0.00% | 444.49 req/s | 204.08 ms | 268.88 ms | 舒适 |
| 混合读写 | 100 | 60s | 8% | 25,950 | 0.00% | 428.30 req/s | 375.38 ms | 447.47 ms | 接近舒适区上沿 |
| 混合读写 | 150 | 60s | 6% | 23,970 | 0.00% | 394.80 req/s | 574.37 ms | 696.35 ms | 压力区 |
| 只读上线门禁 | 30 | 120s | 0% | 42,982 | 0.00% | 357.28 req/s | 192.25 ms | 287.93 ms | 通过 |
| 混合读写 | 50 | 60s | 10% | 26,086 | 0.00% | 431.78 req/s | 207.10 ms | 283.57 ms | 舒适 |
| 混合读写 | 100 | 60s | 8% | 25,242 | 0.00% | 417.03 req/s | 383.30 ms | 464.22 ms | 接近舒适区上沿 |
| 混合读写 | 150 | 60s | 6% | 24,201 | 0.00% | 398.22 req/s | 567.89 ms | 706.09 ms | 压力区 |
混合读写包含真实刷题闭环:创建练习 session、拉取 session detail、提交答案、交卷、读取报告。
@@ -69,10 +69,10 @@
按目前常见页面节奏先用 `0.05 到 0.2 req/s/人` 粗略折算:
- 50 worker 舒适场景 444 req/s约等于 2,220 到 8,880 名活跃在线学生的请求吞吐。
- 100 worker 上沿场景 428 req/s约等于 2,140 到 8,560 名活跃在线学生的请求吞吐。
- 150 worker 压力场景 395 req/s约等于 1,975 到 7,900 名活跃在线学生的请求吞吐。
- 50 worker 舒适场景 432 req/s约等于 2,160 到 8,640 名活跃在线学生的请求吞吐。
- 100 worker 上沿场景 417 req/s约等于 2,085 到 8,340 名活跃在线学生的请求吞吐。
- 150 worker 压力场景 398 req/s约等于 1,990 到 7,960 名活跃在线学生的请求吞吐。
当前本地结论:在受限 API 容器下,后端真实刷题读写链路的舒适观察区间约为 428 到 444 req/s折算约 2,100 到 8,900 名活跃在线学生150 worker 仍 0 错误但 P95 已接近 600ms视为压力区不建议作为生产承诺。同日本地 API 进程 30 worker/30 秒/10% 写入观察到 15,864 请求、0 错误、513.56 req/s、P95 113.97ms;受限 API 容器会明显压低上沿,因此上线承诺仍以云端受限资源复测为准。
当前本地结论:在受限 API 容器下,后端真实刷题读写链路的舒适观察区间约为 417 到 432 req/s折算约 2,100 到 8,600 名活跃在线学生150 worker 仍 0 错误但 P95 已接近 600ms视为压力区不建议作为生产承诺。同日本地 API 进程 30 worker/30 秒/10% 写入观察到 15,864 请求、0 错误、513.56 req/s、P95 113.97ms;受限 API 容器会明显压低上沿,因此上线承诺仍以云端受限资源复测为准。
正式对外容量必须等 4 核 16G 云服务器部署后复跑。保守规划时,生产首版建议先按本地折算值的 30% 到 50% 做容量承诺等云端压测、CDN、对象存储和真实前端埋点完成后再上调。
正式对外容量必须等 4 核 16G 云服务器部署后复跑。保守规划时,生产首版建议先按本地折算值的 30% 到 50% 做容量承诺,约 630 到 4,300 名活跃在线学生,等云端压测、CDN、对象存储和真实前端埋点完成后再上调。

View File

@@ -94,7 +94,7 @@
- 已补 `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 04:44 受限 API 容器真实迁移库复核中30 worker/120s 只读为 44,692 请求、0 错误、371.62 req/s、P95 188.91ms、P99 275.79ms50 worker/60s/10% 写入为 26,815 请求、0 错误、444.49 req/s、P95 204.08ms、P99 268.88ms100 worker/60s/8% 写入为 25,950 请求、0 错误、428.30 req/s、P95 375.38ms、P99 447.47ms150 worker/60s/6% 写入为 23,970 请求、0 错误、394.80 req/s、P95 574.37ms、P99 696.35ms。受限容器系列压测曾抓到自动勋章并发发放唯一键冲突已修复并新增 `scripts/auto-badge-concurrency-test.js`。当前 Docker Desktop 给了 20 CPU/约 62.7GB 内存,但 API 容器限制为 2 CPU/4G舒适观察区暂按 50 到 100 个无停顿 worker 估算150 worker 已是压力区;按单学生 0.05 到 0.2 req/s 粗略折算约为 2,100 到 8,900 名活跃在线学生的本机吞吐观察区间,正式容量仍以上云 4 核 16G 复测为准。
- 已补 `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:05 受限 API 容器真实迁移库复核中30 worker/120s 只读为 42,982 请求、0 错误、357.28 req/s、P95 192.25ms、P99 287.93ms50 worker/60s/10% 写入为 26,086 请求、0 错误、431.78 req/s、P95 207.10ms、P99 283.57ms100 worker/60s/8% 写入为 25,242 请求、0 错误、417.03 req/s、P95 383.30ms、P99 464.22ms150 worker/60s/6% 写入为 24,201 请求、0 错误、398.22 req/s、P95 567.89ms、P99 706.09ms。受限容器系列压测曾抓到自动勋章并发发放唯一键冲突已修复并新增 `scripts/auto-badge-concurrency-test.js`。当前 Docker Desktop 给了 20 CPU/约 62.7GB 内存,但 API 容器限制为 2 CPU/4G舒适观察区暂按 50 到 100 个无停顿 worker 估算150 worker 已是压力区;按单学生 0.05 到 0.2 req/s 粗略折算约为 2,100 到 8,600 名活跃在线学生的本机吞吐观察区间,正式容量仍以上云 4 核 16G 复测为准。
- 当前本地 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`。后续不要再把学生头像上传或默认排行榜当作待办;头像只保留男女预设,排行榜仅作为租户显式开启后的活动能力。

View File

@@ -238,7 +238,7 @@ npm run perf:api:local
npm run launch:gate
```
`launch:gate` 会强制检查一条真实数据读路径压测证据
`launch:gate` 会强制检查真实数据只读压测和混合读写压测两条证据。只读证据用于基础上线门禁
```json
{
@@ -285,6 +285,37 @@ npm run perf:summary -- --input docs/refactor/performance-reports/api-benchmark-
使用 `--allow-writes` 时,摘要工具输出 `capacityObservation`,不输出 `launchGateCheck`;不要把写入场景误填进生产上线门禁的 `performance.api-real-data-read`
更高的 50/100 并发、写入混合场景和容量结论仍应作为人工容量报告归档;门禁只负责挡住明显不达标的基础读路径。
混合读写证据用于确认“创建练习 session -> 拉题 -> 答题 -> 交卷 -> 报告”的真实写入链路在上线容量基线内:
```json
{
"id": "performance.api-real-data-mixed",
"status": "pass",
"command": "PERF_START_SERVER=false PERF_API_BASE=https://api.example.com PERF_DURATION_SECONDS=120 PERF_CONCURRENCY=50 PERF_RAMP_SECONDS=15 PERF_INCLUDE_WRITES=true PERF_PRACTICE_FLOW_RATIO=0.1 PERF_AUTH_MODE=app_session npm run perf:api:local > docs/refactor/launch-artifacts/api-real-data-mixed-benchmark.log",
"completedAt": "2026-06-30T10:49:00+08:00",
"artifact": "launch-artifacts/api-real-data-mixed-benchmark.log",
"summary": {
"errors": 0,
"errorRate": 0,
"p95Ms": 0,
"p99Ms": 0,
"concurrency": 50,
"durationSeconds": 120,
"includeWrites": true
}
}
```
混合读写上线门槛:
- `errors = 0`
- `errorRate <= 0.001`
- `p95Ms <= 500`
- `p99Ms <= 1200`
- `concurrency >= 50`
- `durationSeconds >= 60`
- `includeWrites = true`
更高的 100/150 并发和更长时间压测仍应作为人工容量报告归档;门禁负责挡住基础读路径和刷题写入闭环明显不达标的情况。
证据中只记录报告路径、并发矩阵、P95/P99、错误率和结论不保存真实 token、支付密钥、用户隐私或完整响应。

View File

@@ -12,7 +12,7 @@
- PostgreSQL 官方 WAL/Checkpointhttps://www.postgresql.org/docs/current/runtime-config-wal.html
- PostgreSQL 官方 Connectionshttps://www.postgresql.org/docs/current/runtime-config-connection.html
说明postgresqlco.nf 的页面可作为参数分类和调参入口参考;具体参数语义、重启要求风险以 PostgreSQL 官方文档为准。当前 Codex 环境访问 `https://postgresqlco.nf/tuning-guide` 会返回 403因此落地值不直接抓取该站页面而是把它作为导航来源并以 PostgreSQL 官方文档本项目真实压测结果共同校验。
说明postgresqlco.nf 的 tuning guide 适合作为 `postgresql.conf` 参数分类和调参入口参考;具体参数语义、重启要求风险边界和版本差异仍以 PostgreSQL 官方文档为准。当前 Codex 环境直接访问 `https://postgresqlco.nf/tuning-guide` 会返回 403因此落地值不直接抓取该站页面而是把它作为导航来源并以 PostgreSQL 官方文档本项目真实压测结果和上线可观测性共同校验。
## 适用前提
@@ -45,6 +45,12 @@
| `idle_in_transaction_session_timeout` | `60s` | `60s` | 防止后台或脚本长事务占锁 |
| `statement_timeout` | `30s` | `30s` | API 请求不应长期占用数据库;导入脚本用会话级覆盖 |
| `lock_timeout` | `5s` | `5s` | 防止普通请求长时间等锁 |
| `temp_file_limit` | `4GB` | `8GB` | 给报表/导入留出空间,同时避免异常 SQL 无限落临时文件 |
| `log_temp_files` | `128MB` | `128MB` | 记录大临时文件,定位排序/哈希溢出和缺索引问题 |
| `log_checkpoints` | `on` | `on` | 记录 checkpoint便于把延迟波动和 WAL/checkpoint 压力关联起来 |
| `track_io_timing` | `on` | `on` | 压测和灰度期定位读写 I/O 耗时 |
| `track_wal_io_timing` | `on` | `on` | 定位答题、订单、导入等写入场景的 WAL I/O 压力 |
| `max_parallel_workers_per_gather` | `1` | `2` | 4 核 OLTP/API 场景避免单个查询吃掉过多并行 worker |
## 证据采集脚本
@@ -75,6 +81,8 @@ PG_TUNING_PROFILE=shared-host npm run perf:postgres:evidence -- --strict --json
- `jit=off`
- `statement_timeout``idle_in_transaction_session_timeout``lock_timeout` 不得为 0。
- `track_io_timing=on``track_wal_io_timing=on``log_checkpoints=on`
- `temp_file_limit``log_temp_files``max_parallel_workers_per_gather` 必须落在 profile 范围内。
- 所有 profile 参数必须在允许范围内。
- `pending_restart` 必须为 0。
- `pg_stat_statements` 必须可用。
@@ -122,7 +130,13 @@ where name in (
'log_min_duration_statement',
'idle_in_transaction_session_timeout',
'statement_timeout',
'lock_timeout'
'lock_timeout',
'temp_file_limit',
'log_temp_files',
'log_checkpoints',
'track_io_timing',
'track_wal_io_timing',
'max_parallel_workers_per_gather'
)
order by name;
```
@@ -154,10 +168,16 @@ alter system set log_min_duration_statement = '500ms';
alter system set idle_in_transaction_session_timeout = '60s';
alter system set statement_timeout = '30s';
alter system set lock_timeout = '5s';
alter system set temp_file_limit = '4GB';
alter system set log_temp_files = '128MB';
alter system set log_checkpoints = 'on';
alter system set track_io_timing = 'on';
alter system set track_wal_io_timing = 'on';
alter system set max_parallel_workers_per_gather = '1';
select pg_reload_conf();
```
以下参数需要重启 PostgreSQL 才会生效:`max_connections``shared_buffers``wal_buffers`。执行后用下面语句确认:
以下参数需要重启 PostgreSQL 才会生效:`max_connections``shared_buffers``wal_buffers``track_io_timing``track_wal_io_timing``log_checkpoints``log_temp_files``temp_file_limit``max_parallel_workers_per_gather` 通常可 reload但仍以后续 `pending_restart` 检查为准。执行后用下面语句确认:
```sql
select name, setting, unit, pending_restart
@@ -278,6 +298,12 @@ alter system reset log_min_duration_statement;
alter system reset idle_in_transaction_session_timeout;
alter system reset statement_timeout;
alter system reset lock_timeout;
alter system reset temp_file_limit;
alter system reset log_temp_files;
alter system reset log_checkpoints;
alter system reset track_io_timing;
alter system reset track_wal_io_timing;
alter system reset max_parallel_workers_per_gather;
select pg_reload_conf();
```