forked from wangziqi/gongxue-base
105 lines
12 KiB
Markdown
105 lines
12 KiB
Markdown
# 后端剩余功能与真实数据容量复核
|
||
|
||
更新时间:2026-07-01
|
||
|
||
这份文件用于回答“旧题库功能还有哪些没补齐、当前能支撑多少人同时在线刷题、上线前还要做什么”。结论以当前 Supabase/PostgreSQL 新架构为准,旧 PocketBase 项目只作为功能参考和数据迁移来源。
|
||
|
||
## 功能对齐结论
|
||
|
||
后端主链路已经覆盖旧题库的核心业务:刷题、顺序/随机/全真模拟、答题判分、错题本、收藏夹、背单词、知识手册、分数线、个人中心、会员权益、订单、优惠券、激活码、题目反馈、勋章、站内通知、题目视频、资料下载、题库/单词/手册/分数线/视频导入、题库导出、租户后台内容管理、学生运营、销售/代理/CRM、分佣、平台 SaaS 租户/套餐/账单/用量/公共题库授权。
|
||
|
||
多租户底座已经具备商用联调条件:租户隔离、Supabase Auth JWT 映射、迁移期 session、RLS 测试、平台/租户/学生三类身份边界、租户自定义角色模板、班级/教师/学生范围权限、字段脱敏、审计日志、私有资源短签名和导入/导出 job 审计均已落地。
|
||
|
||
两个产品口径已经定稿,不再作为默认待办反复开发:
|
||
|
||
- 学生头像只支持 `avatarPreset=male/female` 默认资源;不做头像上传、裁剪、第三方头像落库,也不允许租户后台批量导入头像 URL。
|
||
- 排行榜接口保留为租户显式开启后的活动能力;默认不开启,学生端默认不请求、不展示,日常学习激励以后台配置勋章自动发放为主。
|
||
|
||
## 仍需完成
|
||
|
||
当前“仍需完成”不是旧题库核心功能缺口。刷题、背单词、知识手册、分数线、个人中心、会员/订单、错题/收藏、资料/视频、租户后台、平台 SaaS、公共题库、销售/CRM/分佣等后端主链路已经具备前端联调条件。剩余项主要是上云生产环境、真实三方 provider、真实旧数据人工复核、运维安全和体验增强。
|
||
|
||
### 上云生产前 P0
|
||
|
||
1. 真实云端 Auth/JWKS、RLS 和生产配置验收:在预生产/生产执行 `readiness:production`、`readiness:production:db`、`smoke:auth:remote`、`test:rls` 并留档,生产关闭 `x-user-id` 和平台本地 key 兼容入口。
|
||
2. 真实旧数据人工复核:正式切换前处理 7 个已支付缺用户订单、22 个缺所属手册章节,并对题目、权益、订单、错题、资料和视频做人工抽样。
|
||
3. 真实 provider 联调:阿里云 PNVS 短信认证真实手机号 smoke、微信小程序登录、微信网页登录、QQ 登录、微信支付、支付宝、支付/退款回调域名、官方账单格式抽样。传统阿里云/腾讯云短信 adapter 保留兼容路径;当前生产 readiness 已会阻断 mock/未知短信 provider、OAuth/支付回调非 HTTPS、支付缺 `notifyUrl`、公开配置混入密钥和 active provider 缺 `tenant_secrets`。
|
||
4. 对象存储生产安全:配置真实 OSS/COS/Supabase Storage bucket、外部 AV/内容安全扫描、CDN 防盗链、转码/CDN 级水印、生命周期策略和恢复演练。API/worker 已会拒绝 local_dev、未知存储 provider、非 HTTPS 公开 URL 和阿里云 OSS 内网直签。
|
||
5. 生产容量复测:目标云服务器按 4 核 16G 调参文档设置 PostgreSQL,再按 30/50/100 只读和混合读写矩阵复跑,生成 `production-launch-evidence.json` 并通过 `npm run launch:gate`。
|
||
6. 备份、日志、告警、回滚和安全扫描:完成数据库快照、恢复演练、日志告警、Codex Security 真实扫描和上线审批证据。
|
||
|
||
### 商用增强 P1/P2
|
||
|
||
1. Taro 侧继续补小程序真机公式/图片混排、题图资源字段化、状态管理、包体优化、小程序支付容器、分享场景和端到端测试。
|
||
2. 租户后台继续补更细数据范围 UI、成员批量运营、主题素材库、导入操作体验、导出模板精排、财务复核细节和学习督导触达/效果归因。
|
||
3. 平台后台继续补平台在线收款、审计告警升级策略、催缴通知操作台细节、跨租户 BI 和更完整运营消息。
|
||
4. 销售/代理继续补真实打款 provider、发票、批量凭证上传、转化预聚合、团队看板和异常调整单。
|
||
5. AI 择校继续补真实 AI provider、prompt 版本管理、租户后台配置、PDF 报告 worker 和人工复核流程。
|
||
|
||
## 本地真实数据压测
|
||
|
||
### 环境和数据
|
||
|
||
- 环境:Windows + Docker Desktop + 本地 Supabase/PostgreSQL + 本地 API 进程。
|
||
- Docker Desktop 当前资源:20 CPU、约 62.7GB 内存。这个本机结果会高于常见 4 核 16G 云服务器,不能直接作为生产 SLA。
|
||
- 数据库:PocketBase 真实导入数据,并已包含前期写入压测产生的练习/答题记录。
|
||
- 当前本地迁移库规模:19 个租户、74,131 道题、3,722 个平台用户、3,712 个学生资料、1,631 个题目合集、3,120 个练习蓝图、3,519 个单词、2,692 条知识手册条目、81,160 个练习 session、327,925 条答题记录、38,207 条错题、1,501 个内容资源、474 条权益。后续 `db:smoke-seed`、集成测试和压测会继续写入练习/答题/测试租户数据,因此这里按当前本地观察描述,不把每次测试后的瞬时行数当作生产 SLA 口径。
|
||
- 排行榜未纳入默认负载,因为产品默认关闭。
|
||
|
||
### 2026-07-01 08:41 本地真实迁移库 API 进程压测
|
||
|
||
本轮使用本地 Node API 进程自动启动临时端口,数据库为 Docker Desktop 中的本地 Supabase/PostgreSQL,鉴权使用 `PERF_AUTH_MODE=app_session` 的 Bearer session。Docker Desktop 当前分配 20 CPU、约 62.7GB 内存,高于常见 4 核 16G 云服务器;因此这轮是“真实迁移数据 + 本机较高资源”的代码与索引能力观察,不是生产 SLA。
|
||
|
||
| 场景 | 并发 worker | 时长 | 刷题写入比例 | 请求数 | 错误率 | 吞吐 | P95 | P99 | 结论 |
|
||
| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | --- |
|
||
| 只读上线门禁 | 30 | 120s | 0% | 37,520 | 0.00% | 310.34 req/s | 251.08 ms | 388.49 ms | 通过 |
|
||
| 混合读写 | 50 | 60s | 10% | 25,047 | 0.00% | 410.49 req/s | 237.41 ms | 344.51 ms | 舒适 |
|
||
| 混合读写 | 100 | 60s | 8% | 24,116 | 0.00% | 393.56 req/s | 437.37 ms | 533.63 ms | 可用上沿 |
|
||
| 混合读写 | 150 | 60s | 6% | 22,864 | 0.00% | 371.29 req/s | 633.46 ms | 759.62 ms | 压力区 |
|
||
|
||
混合读写包含真实刷题闭环:创建练习 session、拉取 session detail、提交答案、交卷、读取报告。150 worker 仍保持 0 错误,但 P95 已超过 600ms;当前本机可把 100 worker 混合读写视为可用上沿,把 50 worker 混合读写视为舒适区。
|
||
|
||
同轮 `LAUNCH_SMOKE_AUTH_MODE=app_session npm run smoke:launch-persona -- --write docs/refactor/launch-artifacts/launch-persona-smoke.json --write-md docs/refactor/launch-artifacts/launch-persona-smoke.md` 已通过,并生成稳定上线证据 artifact。角色旅程覆盖普通学生 SVIP 后刷题、收藏、错题复习入口,租户管理员 dashboard/主题/学生/销售转化入口,平台管理员租户/套餐/审计入口,以及学生越权后台和跨租户访问拒绝。
|
||
|
||
### 2026-07-01 07:59 真实迁移库 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% | 36,800 | 0.00% | 305.59 req/s | 241.46 ms | 351.17 ms | 通过 |
|
||
| 混合读写 | 50 | 60s | 10% | 24,120 | 0.00% | 398.79 req/s | 231.28 ms | 325.94 ms | 舒适 |
|
||
| 混合读写 | 100 | 60s | 8% | 22,462 | 0.00% | 370.86 req/s | 445.26 ms | 532.32 ms | 可用但延迟偏高 |
|
||
| 混合读写 | 150 | 60s | 6% | 20,708 | 0.00% | 340.74 req/s | 689.67 ms | 833.08 ms | 压力区 |
|
||
|
||
混合读写包含真实刷题闭环:创建练习 session、拉取 session detail、提交答案、交卷、读取报告。
|
||
|
||
同轮 `npm run smoke:taro:h5:interaction` 已通过 32/32,覆盖学生端核心旅程、租户后台真实写操作和平台后台真实写操作;`npm run smoke:launch-persona` 已通过,覆盖普通学生 SVIP 后刷题、收藏、错题复习入口,租户管理员 dashboard/主题/学生/销售转化入口,平台管理员租户/套餐/审计入口,以及学生越权后台和跨租户访问拒绝。
|
||
|
||
### 在线人数折算
|
||
|
||
压测 worker 是无停顿请求流,不等于真实在线学生。刷题学生会读题、思考、翻页和等待网络,前端完成后还需要用真实埋点计算“单个活跃学生平均 RPS”。
|
||
|
||
按目前常见页面节奏先用 `0.05 到 0.2 req/s/人` 粗略折算。本轮本地 API 进程压测的在线吞吐观察为:
|
||
|
||
- 50 worker 舒适场景 410.49 req/s,约等于 2,052 到 8,210 名活跃在线学生的请求吞吐。
|
||
- 100 worker 可用上沿场景 393.56 req/s,约等于 1,968 到 7,871 名活跃在线学生的请求吞吐。
|
||
- 150 worker 压力场景 371.29 req/s,约等于 1,856 到 7,426 名活跃在线学生的请求吞吐。
|
||
|
||
当前本地结论:在真实迁移数据和本机较高资源下,后端刷题读写链路的舒适观察区间约为 410 req/s,折算约 2,052 到 8,210 名活跃在线学生;100 worker 仍满足混合写入观察线但 P95 已超过 400ms,可作为当前本机可用上沿;150 worker 仍 0 错误但 P95 已超过 600ms,视为压力区,不建议作为生产承诺。正式对外容量必须以云端 4 核 16G、PostgreSQL shared-host 参数、真实对象存储/CDN 和前端真实请求节奏复测为准。
|
||
|
||
### 2026-07-01 Docker API + DB 显式受限复核
|
||
|
||
本轮使用同一压测入口,但显式设置 `BENCHMARK_LIMIT_DB_RESOURCES=true`,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 | 失败,延迟超过门禁 |
|
||
| 混合读写 | 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 观察完成后复跑。没有云端复测前,不再把本地 07:59 API-only 观察值当生产容量承诺,只保留为乐观参考;06:53 DB 受限结果则作为未调参下限参考。
|