docs: document migration and quota safeguards
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
237899745
2026-07-26 05:48:14 +08:00
parent 910e60ab59
commit f8f5da04db
3 changed files with 22 additions and 9 deletions

View File

@@ -13,6 +13,8 @@
Debian 13、4 核 CPU、8GB 内存的起始值建议为 `WORKER_TASK_CONCURRENCY=2``WORKER_CONCURRENCY=2``IMAGE_PROCESSING_CONCURRENCY=2`8 核应用服务器可从 `4/2/4` 开始。三者分别表示同时处理的任务数、单任务内文件数和单进程 CPU 图片处理上限。最后一项是全局 CPU 闸门,因此不要把它设置为 CPU 核数的数倍。任务并发提高后,数据库连接池建议至少为 `WORKER_TASK_CONCURRENCY * WORKER_CONCURRENCY + 4`,生产示例使用 16。
8 核 16GB 应用服务器的 ZIP 起始值为 `ZIP_BUILD_CONCURRENCY=2``ZIP_MAX_ENTRIES=200``ZIP_MAX_UNCOMPRESSED_BYTES=2147483648`。ZIP 使用 stored 模式,构建时同时存在下载源和归档文件,按两个 2 GiB 构建估算应至少保留约 8 GiB 临时磁盘余量;磁盘较小时应先降低总字节或并发,而不是提高 HTTP 超时。
生产 Compose 默认按 8 核 16GB 主机设置可覆盖的资源上限API 3GB、Worker 8GB、PostgreSQL 2GB、Redis 1GB对应变量为 `API_MEMORY_LIMIT``WORKER_MEMORY_LIMIT``POSTGRES_MEMORY_LIMIT``REDIS_MEMORY_LIMIT`。Redis 的 `REDIS_MAXMEMORY` 默认 768MB达到上限后返回写入错误而不是继续挤占宿主机内存。
### 首次启动
@@ -55,7 +57,7 @@ curl --fail http://127.0.0.1:8080/metrics
### 更新与回滚
更新代码后保留 `.env.production` 和命名卷。包含迁移 `017``019` 的版本不能直接让旧、新 Worker 并行滚动:先备份数据库并停止旧 Worker再构建新镜像。
更新代码后保留 `.env.production` 和命名卷。包含迁移 `017``022` 的版本不能让旧、新 API 或 Worker 并行滚动:旧 API 不理解 ZIP 构建租约,旧 Worker 不理解任务 attempt fencing。先备份数据库并停止旧 API/Worker再构建新镜像。
迁移 `017` 会在发现重复 Customer 或同用户多条未取消 Stripe 订阅时主动失败,迁移 `019` 会在发现同一 Stripe 发票对应多行时主动失败。部署前先检查并人工对账,三个查询都必须返回 0 行:
@@ -83,26 +85,27 @@ HAVING COUNT(*) > 1;
```bash
git pull --ff-only
docker compose --env-file .env.production -f docker/docker-compose.prod.yml stop worker
docker compose --env-file .env.production -f docker/docker-compose.prod.yml stop api worker
docker compose --env-file .env.production -f docker/docker-compose.prod.yml build api
docker compose --env-file .env.production -f docker/docker-compose.prod.yml up -d postgres redis api
docker compose --env-file .env.production -f docker/docker-compose.prod.yml up -d worker
```
新 API 启动后会消费迁移 `018` 创建的 Stripe 对账队列。启动 Worker 前应确认 API 健康、`STRIPE_SECRET_KEY` 可用且服务器能访问 `STRIPE_API_BASE_URL`;对账可以后台继续,但必须监控失败项:
新 API 启动后会消费迁移 `018` 创建的订阅对账队列。迁移 `020` 为历史发票写入待对账哨兵,发票不主动批量拉取,而是在首个后续事件到达时取 Stripe 快照。启动 Worker 前应确认 API 健康、`STRIPE_SECRET_KEY` 可用且服务器能访问 `STRIPE_API_BASE_URL`订阅对账可以后台继续,但必须监控失败项:
```sql
SELECT status, COUNT(*)
FROM stripe_subscription_reconciliations
GROUP BY status;
SELECT provider_object_id, reconciliation_reason, updated_at
SELECT object_type, requires_reconciliation, COUNT(*)
FROM provider_object_event_watermarks
WHERE provider = 'stripe' AND requires_reconciliation = true
ORDER BY updated_at;
WHERE provider = 'stripe'
GROUP BY object_type, requires_reconciliation
ORDER BY object_type, requires_reconciliation;
```
`failed` 会指数退避重试;持续失败通常表示 Stripe 凭据、网络、Customer/Price 映射不完整。上线验收要求 `pending/processing/failed` 最终归零,且 `requires_reconciliation=true` 为 0。生产镜像应使用不可变的 `IMAGEFORGE_TAG`。数据库迁移已应用后,不能只回滚旧二进制;应保留新 schema并使用兼容该 schema 的修复镜像。
`failed` 会指数退避重试;持续失败通常表示 Stripe 凭据、网络、Customer/Price 映射不完整。上线验收要求订阅队列的 `pending/processing/failed` 最终归零,且 subscription 水位不再待对账invoice 水位在对应发票首个后续事件到达前保持 `requires_reconciliation=true` 属于预期状态。生产镜像应使用不可变的 `IMAGEFORGE_TAG`。数据库迁移已应用后,不能只回滚旧二进制;应保留新 schema并使用兼容该 schema 的修复镜像。
### 反向代理