# Node 后端测试、观测与部署基线 日期:`2026-04-08` ## 1. 文档目标 这份文档用于落实 `EXPRESS_BACKEND_PARALLEL_WORKSTREAM_PLAN_2026-04-08.md` 中的任务 9: - 给 Node 后端补最小自动回归 - 给请求链路补最小可追踪基线 - 给部署、回滚、迁移补最小操作清单 当前目标不是一次性把监控平台、CI/CD、容器编排全部做完,而是先确保: - 后端改动后有脚本能快速验证主链路 - 线上或联调失败时能快速定位到具体请求 - 发布前后有统一检查口径 ## 2. 当前基线命令 推荐在仓库根目录执行: ```bash npm run server-node:db:migrate npm run server-node:test:baseline npm run server-node:smoke npm run server-node:smoke:proxy ``` 说明: - `npm run server-node:db:migrate` - 用当前 `DATABASE_URL` 主动校验 PostgreSQL 基线是否可连接、可初始化 - 会确保 `schema_migrations` 和运行时基础表已补齐 - `npm run server-node:test:baseline` - 当前先固定为任务 9 自己维护的观测基线测试 - 已覆盖 `requestId` 回传、访问日志字段、错误日志链路 - `npm run server-node:smoke` - 启动一套基于 `pg-mem` 的临时 Express 服务 - 不依赖本地 PostgreSQL - 走真实 HTTP 调用验证 `healthz -> auth -> runtime save/settings -> logout` - `npm run server-node:smoke:proxy` - 基于已构建的 `dist + server-node/dist` - 自动拉起 `server-node + 同域反向代理 harness` - 用 `pg-mem` 跑同域反向代理链路 smoke - 验证 `web -> reverse proxy -> /api/* -> server-node` 主链路 如果要一口气跑完整发布前基线,可执行: ```bash npm run server-node:check:deploy ``` 补充说明: - `npm run server-node:test` 仍然可以继续作为更大范围的后端接口套件入口 - 但它会跟随其他并行任务一起变化,不应替代任务 9 自己的稳定基线 ## 2.1 任务 9 对照清单 当前按并行任务规划中的任务 9 逐项对照: - 后端接口测试:`npm run server-node:test` - 关键主链路 smoke:`npm run server-node:smoke` - request/response 日志校验:`npm run server-node:test:baseline` - 同域部署基线:本文第 6 节与 `npm run server-node:smoke:proxy` - 反向代理 smoke 测试脚本:`scripts/smoke-same-origin-stack.ts` - 回滚、备份、迁移检查清单:本文第 8 节与 `npm run server-node:db:migrate` - 发布前一键检查:`npm run server-node:check:deploy` ## 3. 当前 smoke 覆盖范围 当前 smoke 脚本验证以下链路: - `GET /healthz` - `POST /api/auth/entry` - `GET /api/auth/me` - `PUT /api/runtime/save/snapshot` - `GET /api/runtime/save/snapshot` - `PUT /api/runtime/settings` - `GET /api/runtime/settings` - `DELETE /api/runtime/save/snapshot` - `POST /api/auth/logout` 当前代理 smoke 额外验证: - `GET /` - `GET /healthz`(本地反向代理健康探针) - `POST /api/auth/entry` 经反代可用 - `GET /api/auth/me` 经反代可用 - `PUT /api/runtime/save/snapshot` 经反代可用 - `GET /api/runtime/save/snapshot` 经反代可用 - `X-Request-Id` 能穿过反向代理返回给调用方 当前 smoke 的定位是: - 优先覆盖后端化后最容易断的基础链路 - 优先覆盖前端最依赖的鉴权和持久化能力 - 不把 AI 上游依赖拉进最小回归集,避免把第三方波动误判成主链路回归 ## 4. 当前观测基线 当前请求链路至少要满足以下约束: - 支持读取外部传入的 `X-Request-Id` - 如果调用方没有传 `X-Request-Id`,后端自动生成 - 响应头回写 `x-request-id` - 访问日志至少包含: - `request_id` - `user_id` - `method` - `path` - `status` - `latency_ms` - 错误日志至少包含: - `request_id` - `user_id` - `err` 当前目的很明确: - 浏览器、反向代理、Node 后端至少有一个共同可追踪的请求标识 - 接口失败后,能从日志里快速找到对应请求 ## 5. 部署前检查清单 发布前至少执行一次: - `npm run check:encoding` - `npm run server-node:db:migrate` - `npm run server-node:test:baseline` - `npm run server-node:smoke` - `npm run server-node:build` - `npm run build` - `npm run server-node:smoke:proxy` 环境变量至少确认: - `DATABASE_URL` - `JWT_SECRET` - `NODE_SERVER_ADDR` - `LOG_LEVEL` - `LLM_API_KEY` 或 `ARK_API_KEY` - `DASHSCOPE_API_KEY` 部署前数据库检查: - 确认目标 PostgreSQL 可连接 - 确认发布账号具备建表或执行初始化所需权限 - 确认已执行 `npm run server-node:db:migrate` 或等效迁移步骤 - 确认现网数据已完成备份 ## 6. 同域部署基线 当前推荐仍然是同域部署: - Web 静态资源:`https://game.example.com/` - Node API:`https://game.example.com/api/*` 最小拓扑: ```text Browser -> Nginx / Caddy -> dist -> server-node ``` 反向代理至少要保留这些头: - `Host` - `X-Forwarded-For` - `X-Forwarded-Proto` - `X-Request-Id` 流式接口还要确保: - `proxy_buffering off` - `X-Accel-Buffering: no` ## 7. 发布后 smoke 清单 发布完成后至少人工或脚本确认一次: 1. `GET /healthz` 返回 `200` 2. 响应头里能看到 `x-request-id` 3. `POST /api/auth/entry` 可正常注册或恢复账号 4. `GET /api/auth/me` 可正常识别 token 5. `PUT /api/runtime/save/snapshot` 和 `GET /api/runtime/save/snapshot` 正常 6. 日志中能用同一个 `request_id` 串起访问记录 如果线上使用反向代理生成请求 ID,还要额外确认: - 代理传入的 `X-Request-Id` 没有在 Node 层丢失 - 同域入口 `/` 与 `/api/*` 可以通过同一个站点域名访问 ## 8. 回滚与备份清单 回滚前先确认: - 当前发布包版本号或 commit 可定位 - 当前数据库备份可恢复 - 当前 `.env` 或 secret 版本可回退 需要回滚时按顺序执行: 1. 停止新版本 Node 进程 2. 切回上一个稳定前端静态包和 Node 构建产物 3. 恢复上一个稳定环境变量版本 4. 如果本次发布包含数据库结构变更,先确认是否需要回滚数据 5. 回滚后重新执行 `healthz + auth + runtime save` 最小 smoke 如果本次发布已经写入了不兼容数据结构: - 不要只回滚代码不验证数据兼容性 - 必须先确认旧版本代码是否还能读取当前数据 ## 9. 后续扩展方向 任务 9 的下一轮可以继续补: - 把 smoke 纳入 CI - 为关键 API 增加结构化 contract 测试 - 给上游 AI 调用补 vendor/model/errorCode 维度日志 - 增加数据库迁移前后的自动检查脚本 - 增加反向代理与正式环境的联调 smoke