Files
Genarrative/docs/technical/M7_TEST_DEPLOY_CUTOVER_EXECUTION_PLAN_2026-04-22.md
kdletters a2c71fcb3a
Some checks failed
CI / verify (push) Has been cancelled
chore: remove maincloud configuration
2026-05-02 17:04:11 +08:00

7.1 KiB
Raw Permalink Blame History

M7 联调、回归、部署与切流执行方案

日期:2026-04-22

归档说明:截至 2026-04-26Rust 迁移已完成,旧 server-node/ 已删除M7 阶段性预检包装入口已移除。后续长期检查统一使用 server-rs/scripts/check.ps1server-rs/scripts/smoke.ps1server-rs/scripts/oss-smoke.ps1npm run api-server

1. 文档目标

这份文档把 M7联调、回归、部署与切流任务清单 从高层勾选项细化为可直接执行的工程方案。

M7 的目标不是新增玩法功能,而是在 M0 ~ M6 已迁移的 Rust 后端基础上完成切流前收口:

  1. 固定本地、灰度、切流前的检查命令。
  2. 固定 Axum + SpacetimeDB + OSS 的部署与回滚口径。
  3. 固定观测字段、慢请求、上游失败日志与资产任务日志。
  4. 固定旧 server-node 删除后的 Rust 主线回归与部署验证方式。
  5. 等价拆分 server-rs/crates/spacetime-module/src/lib.rs,避免 SpacetimeDB 主工程继续退化为单大文件。

2. 执行约束

  1. 不改变现有 HTTP contract、SSE contract、SpacetimeDB 表名、reducer 名、procedure 名和对象键前缀。
  2. 不把 LLM、OSS、短信、微信等外部副作用移入 SpacetimeDB reducer。
  3. spacetime-module 拆分只做物理结构收口,不做 schema 重命名、字段删除、字段重排或 reducer/procedure 改名。
  4. server-node/ 已进入物理删除流程M7 不再把旧 Node 后端作为运行时回退锚点。
  5. 前端默认指向 Rust api-server;如需临时覆盖目标,只允许使用 RUST_SERVER_TARGETGENARRATIVE_RUNTIME_SERVER_TARGET 指向 Rust 兼容服务。

3. 测试体系

M7 固定四层测试入口:

  1. Rust crate 级别:cargo check/test 覆盖 api-serverspacetime-moduleshared-contracts 与模块 crate。
  2. Axum handler 级别:继续复用 api-server 内已有 build_router + tower::ServiceExt 测试,重点覆盖 healthz/auth/runtime/assets/custom-world/story 的兼容响应。
  3. SpacetimeDB 模块级别:cargo check -p spacetime-module 作为 schema/reducer/procedure 的最低门禁;需要真实数据库行为时使用 spacetime publish --server local --yes 后再跑 smoke。
  4. 端到端主流程:server-rs/scripts/smoke.ps1server-rs/scripts/oss-smoke.ps1 分别覆盖基础 HTTP contract 与真实 OSS 链路。

推荐本地顺序:

.\server-rs\scripts\check.ps1
.\server-rs\scripts\smoke.ps1

4. 部署准备

Axum 部署方式:

  1. cargo build -p api-server --release 生成发布二进制。
  2. 进程环境显式配置 GENARRATIVE_API_HOSTGENARRATIVE_API_PORTGENARRATIVE_API_LOG
  3. 反向代理继续保留 HostX-Forwarded-ForX-Forwarded-ProtoX-Request-Id
  4. SSE 路由必须禁用代理缓冲。

SpacetimeDB 发布方式:

  1. 本地开发先执行 server-rs/scripts/spacetime-dev.ps1 启动 standalone。
  2. 发布模块使用 spacetime publish genarrative-dev --server local --yes --module-path server-rs/crates/spacetime-module
  3. 若需要重置开发库,必须显式加 --clear-database --yes,不得默认清库。
  4. 生成绑定时使用仓库根目录 spacetime.json 中的 typescriptrust 输出目录。

OSS / CDN / 域名方案:

  1. 正式对象真相仍为 bucket + object_key
  2. bucket 默认私有读写,浏览器不直接匿名读取。
  3. /generated-* 旧路径由 Axum 同源代理或 CDN 边缘回源到 Rust API。
  4. CDN 只缓存可公开缓存的派生读结果,不把私有签名 URL 写入业务表。

环境变量最小清单:

  1. GENARRATIVE_API_HOSTGENARRATIVE_API_PORTGENARRATIVE_API_LOG
  2. GENARRATIVE_JWT_ISSUERGENARRATIVE_JWT_SECRET
  3. GENARRATIVE_SPACETIME_SERVER_URLGENARRATIVE_SPACETIME_DATABASEGENARRATIVE_SPACETIME_TOKEN
  4. ALIYUN_OSS_BUCKETALIYUN_OSS_ENDPOINTALIYUN_OSS_ACCESS_KEY_IDALIYUN_OSS_ACCESS_KEY_SECRET
  5. GENARRATIVE_LLM_PROVIDERGENARRATIVE_LLM_BASE_URLGENARRATIVE_LLM_API_KEY
  6. DASHSCOPE_BASE_URLDASHSCOPE_API_KEY
  7. SMS_AUTH_ENABLED 与短信供应商变量
  8. WECHAT_AUTH_ENABLED 与微信 OAuth 变量
  9. RUST_SERVER_TARGETGENARRATIVE_RUNTIME_SERVER_TARGET

5. 灰度与切流

灰度环境固定为三段:

  1. preflight:只跑 Rust 预检、smoke 与人工主链验证,不接正式用户流量。
  2. limited-rust:小范围账号或灰度域名访问 Rust api-server,差异必须登记到 M7 验收记录。
  3. rust-primary:反向代理或 Vite dev proxy 指向 Rust api-server,旧 Node 后端不作为运行时入口保留。

前端切换方式:

  1. 默认使用 RUST_SERVER_TARGETGENARRATIVE_API_TARGET 指向 Rust api-server
  2. 本地或灰度可覆盖 GENARRATIVE_RUNTIME_SERVER_TARGET,但目标仍必须是 Rust 兼容服务。
  3. 紧急回退优先回滚到上一个 Rust 发布包或反向代理配置,不恢复 server-node/ 工程目录。

6. API 回归

第一批删除后不再保留 Node/Rust 对比脚本M7 回归改为 Rust 主线 contract 验证:

  1. server-rs/scripts/check.ps1 覆盖 Rust 工作区格式、clippy、构建与测试门禁。
  2. server-rs/scripts/smoke.ps1 覆盖 /healthz、envelope 与 request id 基础 contract。
  3. server-rs/scripts/oss-smoke.ps1 覆盖真实 OSS 链路。
  4. 新增只读 contract 时优先补进 Rust 侧 smoke 或 handler 测试,不恢复 Node 对比脚本。

带登录、写入、OSS 或 SSE 的主流程仍由专门 smoke、handler 测试和人工验证清单负责。

7. 观测能力

M7 观测字段固定为:

  1. HTTP 访问日志:methoduristatuslatency_msslow_requestrequest_id
  2. 错误日志:request_idstatuserror_code
  3. 上游失败:provideroperationrequest_idstatus/codemessage
  4. 关键 reducer操作名、主实体 ID、结果状态
  5. 资产任务:task_idcharacter_id/entity_idasset_kindstatus

慢请求阈值默认 1000ms,可通过 GENARRATIVE_SLOW_REQUEST_THRESHOLD_MS 覆盖。

8. 数据迁移与回滚

当前 M7 不做一次性历史数据导入 SpacetimeDB 的危险迁移,采用按主链确认的渐进策略:

  1. 已迁移主链以 SpacetimeDB 为真相源。
  2. 未迁移或灰度失败主链必须继续迁入 Rust 主线后再开放,不回退到旧 Node 工程。
  3. 资产二进制以 OSS 为真相,不回滚到本地 public/generated-* 写盘。
  4. 若 SpacetimeDB schema 需要清库重发,只允许在开发库或明确灰度库执行 --clear-database
  5. 生产回滚优先切反向代理目标,不优先改代码。

9. 验收定义

M7 完成时必须满足:

  1. M7 文档、脚本、任务清单均同步。
  2. api-serverspacetime-module 至少通过 cargo check
  3. 基础 smoke 脚本可执行,并覆盖 healthz + envelope + request id
  4. Rust 主线预检和 smoke 脚本可执行。
  5. Vite dev proxy 默认指向 Rust api-server,仅保留 Rust 目标覆盖开关。
  6. spacetime-module 已从单 lib.rs 拆为按 runtime / gameplay / custom_world / asset_metadata / ai 组织的文件结构。