7.1 KiB
7.1 KiB
M7 联调、回归、部署与切流执行方案
日期:2026-04-22
归档说明:截至 2026-04-26,Rust 迁移已完成,旧 server-node/ 已删除,M7 阶段性预检包装入口已移除。后续长期检查统一使用 server-rs/scripts/check.ps1、server-rs/scripts/smoke.ps1、server-rs/scripts/oss-smoke.ps1 与 npm run api-server:maincloud。
1. 文档目标
这份文档把 M7:联调、回归、部署与切流任务清单 从高层勾选项细化为可直接执行的工程方案。
M7 的目标不是新增玩法功能,而是在 M0 ~ M6 已迁移的 Rust 后端基础上完成切流前收口:
- 固定本地、灰度、切流前的检查命令。
- 固定
Axum + SpacetimeDB + OSS的部署与回滚口径。 - 固定观测字段、慢请求、上游失败日志与资产任务日志。
- 固定旧
server-node删除后的 Rust 主线回归与部署验证方式。 - 等价拆分
server-rs/crates/spacetime-module/src/lib.rs,避免 SpacetimeDB 主工程继续退化为单大文件。
2. 执行约束
- 不改变现有 HTTP contract、SSE contract、SpacetimeDB 表名、reducer 名、procedure 名和对象键前缀。
- 不把 LLM、OSS、短信、微信等外部副作用移入 SpacetimeDB reducer。
spacetime-module拆分只做物理结构收口,不做 schema 重命名、字段删除、字段重排或 reducer/procedure 改名。server-node/已进入物理删除流程,M7 不再把旧 Node 后端作为运行时回退锚点。- 前端默认指向 Rust
api-server;如需临时覆盖目标,只允许使用RUST_SERVER_TARGET或GENARRATIVE_RUNTIME_SERVER_TARGET指向 Rust 兼容服务。
3. 测试体系
M7 固定四层测试入口:
- Rust crate 级别:
cargo check/test覆盖api-server、spacetime-module、shared-contracts与模块 crate。 - Axum handler 级别:继续复用
api-server内已有build_router + tower::ServiceExt测试,重点覆盖healthz/auth/runtime/assets/custom-world/story的兼容响应。 - SpacetimeDB 模块级别:
cargo check -p spacetime-module作为 schema/reducer/procedure 的最低门禁;需要真实数据库行为时使用spacetime publish --server local --yes后再跑 smoke。 - 端到端主流程:
server-rs/scripts/smoke.ps1与server-rs/scripts/oss-smoke.ps1分别覆盖基础 HTTP contract 与真实 OSS 链路。
推荐本地顺序:
.\server-rs\scripts\check.ps1
.\server-rs\scripts\smoke.ps1
4. 部署准备
Axum 部署方式:
cargo build -p api-server --release生成发布二进制。- 进程环境显式配置
GENARRATIVE_API_HOST、GENARRATIVE_API_PORT、GENARRATIVE_API_LOG。 - 反向代理继续保留
Host、X-Forwarded-For、X-Forwarded-Proto、X-Request-Id。 - SSE 路由必须禁用代理缓冲。
SpacetimeDB 发布方式:
- 本地开发先执行
server-rs/scripts/spacetime-dev.ps1启动 standalone。 - 发布模块使用
spacetime publish genarrative-dev --server local --yes --module-path server-rs/crates/spacetime-module。 - 若需要重置开发库,必须显式加
--clear-database --yes,不得默认清库。 - 生成绑定时使用仓库根目录
spacetime.json中的typescript与rust输出目录。
OSS / CDN / 域名方案:
- 正式对象真相仍为
bucket + object_key。 - bucket 默认私有读写,浏览器不直接匿名读取。
/generated-*旧路径由 Axum 同源代理或 CDN 边缘回源到 Rust API。- CDN 只缓存可公开缓存的派生读结果,不把私有签名 URL 写入业务表。
环境变量最小清单:
GENARRATIVE_API_HOST、GENARRATIVE_API_PORT、GENARRATIVE_API_LOGGENARRATIVE_JWT_ISSUER、GENARRATIVE_JWT_SECRETGENARRATIVE_SPACETIME_SERVER_URL、GENARRATIVE_SPACETIME_DATABASE、GENARRATIVE_SPACETIME_TOKENALIYUN_OSS_BUCKET、ALIYUN_OSS_ENDPOINT、ALIYUN_OSS_ACCESS_KEY_ID、ALIYUN_OSS_ACCESS_KEY_SECRETGENARRATIVE_LLM_PROVIDER、GENARRATIVE_LLM_BASE_URL、GENARRATIVE_LLM_API_KEYDASHSCOPE_BASE_URL、DASHSCOPE_API_KEYSMS_AUTH_ENABLED与短信供应商变量WECHAT_AUTH_ENABLED与微信 OAuth 变量RUST_SERVER_TARGET、GENARRATIVE_RUNTIME_SERVER_TARGET
5. 灰度与切流
灰度环境固定为三段:
preflight:只跑 Rust 预检、smoke 与人工主链验证,不接正式用户流量。limited-rust:小范围账号或灰度域名访问 Rustapi-server,差异必须登记到 M7 验收记录。rust-primary:反向代理或 Vite dev proxy 指向 Rustapi-server,旧 Node 后端不作为运行时入口保留。
前端切换方式:
- 默认使用
RUST_SERVER_TARGET或GENARRATIVE_API_TARGET指向 Rustapi-server。 - 本地或灰度可覆盖
GENARRATIVE_RUNTIME_SERVER_TARGET,但目标仍必须是 Rust 兼容服务。 - 紧急回退优先回滚到上一个 Rust 发布包或反向代理配置,不恢复
server-node/工程目录。
6. API 回归
第一批删除后不再保留 Node/Rust 对比脚本,M7 回归改为 Rust 主线 contract 验证:
server-rs/scripts/check.ps1覆盖 Rust 工作区格式、clippy、构建与测试门禁。server-rs/scripts/smoke.ps1覆盖/healthz、envelope 与 request id 基础 contract。server-rs/scripts/oss-smoke.ps1覆盖真实 OSS 链路。- 新增只读 contract 时优先补进 Rust 侧 smoke 或 handler 测试,不恢复 Node 对比脚本。
带登录、写入、OSS 或 SSE 的主流程仍由专门 smoke、handler 测试和人工验证清单负责。
7. 观测能力
M7 观测字段固定为:
- HTTP 访问日志:
method、uri、status、latency_ms、slow_request、request_id - 错误日志:
request_id、status、error_code - 上游失败:
provider、operation、request_id、status/code、message - 关键 reducer:操作名、主实体 ID、结果状态
- 资产任务:
task_id、character_id/entity_id、asset_kind、status
慢请求阈值默认 1000ms,可通过 GENARRATIVE_SLOW_REQUEST_THRESHOLD_MS 覆盖。
8. 数据迁移与回滚
当前 M7 不做一次性历史数据导入 SpacetimeDB 的危险迁移,采用按主链确认的渐进策略:
- 已迁移主链以 SpacetimeDB 为真相源。
- 未迁移或灰度失败主链必须继续迁入 Rust 主线后再开放,不回退到旧 Node 工程。
- 资产二进制以 OSS 为真相,不回滚到本地
public/generated-*写盘。 - 若 SpacetimeDB schema 需要清库重发,只允许在开发库或明确灰度库执行
--clear-database。 - 生产回滚优先切反向代理目标,不优先改代码。
9. 验收定义
M7 完成时必须满足:
- M7 文档、脚本、任务清单均同步。
api-server和spacetime-module至少通过cargo check。- 基础 smoke 脚本可执行,并覆盖
healthz + envelope + request id。 - Rust 主线预检和 smoke 脚本可执行。
- Vite dev proxy 默认指向 Rust
api-server,仅保留 Rust 目标覆盖开关。 spacetime-module已从单lib.rs拆为按runtime / gameplay / custom_world / asset_metadata / ai组织的文件结构。