这是面向运维、把签名 BitzOrcas 候选版本在目标环境提升到 GA 的操作流程。它假设生产就绪清单是最新的,且可选适配器在显式满足其生产前置条件前保持禁用。0002-production-adapter-readiness.json 中的 ProductionBlocker 会阻止切换。
1. 切换前门禁
在安排窗口之前,确认:发布构建(0 错误)、XML 文件/注释检查通过、架构 + 应用 + API-shell + Docker 契约测试通过、report-acceptance.sh 硬门禁通过、git diff --check 干净、CI fast-gate 与 integration-docker 已配置、verify-template.sh 通过,且签名候选产物 + provenance.json 在精确候选 commit 上通过针对可信发布/认证工作流的 --artifact-only 验证。
发布工作流共享一个不可取消的并发组。首次商业提升之前:保护 commercial-release-builder 环境,配置签名证书 secret 与 trusted-signer/vulnerability/license 变量,并记录 Feed staging/promote 证据或一次精确 hash 可恢复性演练。
**硬停止条件:**缺失值即为发布停止——仅仓库代码不构成真实证书、时间戳权威、私有 Feed 或受保护工作流成功运行存在的证据。不要带着 ProductionBlocker 切换,也不要在 Chat__Realtime__Enabled=true 已部署且 Operations 报告 SignalRChatRealtimeAdapter 之前宣布 Chat 实时。
2. 配置与密钥
从部署 secret store 加载生产值。必需的失败关闭基线:
ASPNETCORE_ENVIRONMENT=ProductionRateLimiting__Enabled=trueWebhook__Delivery__Enabled=falseWebhook__Delivery__IpAllowlist__Enabled=falseWebhook__Delivery__RateLimit__Enabled=false必需的生产依赖:SQL Server(ConnectionStrings__Default 或 SqlSugar__ConnectionString)、RabbitMQ、Redis、S3 兼容文件存储(FileStorage__DefaultProvider=Minio)、OTLP collector 端点(OTEL_EXPORTER_OTLP_ENDPOINT),以及仅来自 secret store 的 JWT 签名材料。绝不提交已解析的 secret、生产 .env 文件、证书或私钥。
3. 迁移与数据准备
确认 DB 目标是生产且备份是最新的。绝不在 Staging 或 Production 中使用 EF Core EnsureCreated、自动 --reset-schema 或 BITZORCAS_ASPIRE_RESET_SCHEMA。仅在 schema 初始化或版本化迁移成功后才运行必需的 seed 步骤。在启动 Web 运行时之前验证 CAP 表存在且 RabbitMQ 健康。记录部署的 commit SHA、模板版本、DB 备份标识、迁移当前版本/校验和与配置版本。
EF Core 发布顺序
迁移过程仅需 Persistence__Provider=EfCore 与 ConnectionStrings__Default——不要仅为让 DB 命令启动而注入 RabbitMQ、JWT 或 Runtime License。
归属澄清:
--migrate-schema plan|status|apply是 EF Core 模板生成的客户宿主命令(BitzConsumer.Api);主线仓库的 BitzOrcas.Api 只有 —init-schema/—seed-demo/—seed-only/—reset-schema/—init-quartz-schema。本节请针对模板产物宿主执行。
# 把 plan、审批、apply 和最终 status 分成四个可留证的步骤。dotnet BitzOrcas.Api.dll --migrate-schema plan # 评审,允许 pending,exit 0dotnet BitzOrcas.Api.dll --migrate-schema status # 门禁:0=当前,4=pending,5=driftdotnet BitzOrcas.Api.dll --migrate-schema apply # 仅在 plan 批准 + 备份之后dotnet BitzOrcas.Api.dll --migrate-schema status # Web 启动前必须返回 0| Exit code | 含义 |
|---|---|
0 | schema 当前 |
4 | 待处理迁移 |
5 | history/checksum drift——发布停止 |
日志仅携带迁移 id、name、state 与 SHA-256——绝不携带 SQL 文本或连接串。在 exit 5 时,不要编辑已应用的 SQL 资源或重写 dbo.__BitzOrcasEfSchemaHistory;排查 DB 错误,恢复已评审脚本,并在决定再次 apply 是否安全前重新运行 status。
SqlSugar 发布顺序
使用 --init-schema --no-seed 流程配合 DBA 评审过的 scripts/database/migrations/。SqlSugar CodeFirst 是幂等的表初始化,不是 EF 迁移历史;Staging 与 Production 仍拒绝自动 reset。--init-schema 只建缺表、补可空无默认列。库中其余结构差异由 /host/schema 审阅;API Host 启动后的 operations-schema-drift-notify 循环会把残留推给 Host-Admin。若 schema 初始化失败,停止切换并让流量留在前一版本。
4. 健康检查
部署新版本后,在路由用户流量之前:
| 探针 | 端点 | 预期 |
|---|---|---|
| Liveness | GET /health/live | healthy |
| Readiness | GET /health/ready | 已启用依赖均为 healthy |
| Full health | GET /health | 无意外 unhealthy 检查 |
Readiness 必须暴露数据库、RabbitMQ/CAP、Redis、文件存储与 Webhook 生产交付(启用时)的依赖状态。一个许可的 Host 还暴露 GET /health/license;见 Runtime License。
5. 运维验证
使用认证的 Operations 调用方:
| 检查 | 端点 | 预期 |
|---|---|---|
| 适配器状态 | GET /api/operations/adapters | DB/CAP/Redis/FileStorage 为生产适配器;无意外 Default/Unavailable 关键端口 |
| 配置诊断 | GET /api/operations/config | 必需生产键存在,无 secret 值 |
| 作业可见性 | GET /api/operations/jobs | 审计保留与工作流定时计划可见 |
| 审计可见性 | 审计查询端点 | 后端启用时安全/请求/CAP/作业/Webhook 交付记录可见 |
生产中任何关键 InMemory*、Memory*、Null* 或 Unavailable* 适配器都是发布停止,除非存在显式记录的失败关闭约束。
6. Webhook 运维演练
在设置 Webhook__Delivery__Enabled=true 之前运行。演练覆盖:缺失配置(readiness unhealthy,名称缺失 key)、CIDR 拒绝(交付被失败关闭拒绝并带结构化警告)、Redis 不可用(交付被失败关闭拒绝)、触发限制(第一次允许,第二次拒绝)与健康启用(readiness healthy)。每个启用的订阅必须带显式有效的 CIDR/IP 白名单条目;空或无效的白名单会拒绝交付。
生产启用要求:
Webhook__Delivery__Enabled=trueWebhook__Delivery__IpAllowlist__Enabled=trueWebhook__Delivery__RateLimit__Enabled=trueWebhook__Delivery__RateLimit__PermitLimit=<positive-integer>Webhook__Delivery__RateLimit__WindowSeconds=<positive-integer>7. 流量切换
- 部署发布产物并挂载生产配置与密钥。
- 等待
/health/live与/health/ready通过。 - 验证 Operations 适配器状态与配置诊断。
- 把一小部分流量路由到新版本。
- 观察 HTTP 5xx 速率、
/health/ready、CAP outbox 积压、Redis 连通性、Webhook 拒绝日志与审计写入健康。 - 仅在门禁保持绿色时以受控步长增加流量。
- 完全切换后,保留前一版本与 DB 备份可用,直到回滚窗口关闭。
8. 回滚
触发条件:/health/ready 连续三次探针失败;HTTP 5xx 速率超过严重阈值(每 5 分钟 >5%);CAP outbox 积压越过严重阈值(>1000 行);Redis 故障禁用 HMAC nonce store 或 Webhook 限流器;适配器守卫报告意外默认适配器;或一次迁移产生正确性/租户隔离风险。
**步骤:**停止增加流量并把所有流量路由到前一健康版本;仅在需要诊断时保持失败版本运行且不写入不安全数据;若事件是交付专属的,设置 Webhook__Delivery__Enabled=false;保留审计日志、验收报告、部署日志与健康快照;仅在事件 owner 确认损坏或不兼容 schema 写入时从批准的备份恢复数据;记录事件,含 commit SHA、配置版本、首个失败的健康检查与回滚时间。
9. 事件处理
| 症状 | 首要动作 | 说明 |
|---|---|---|
| 缺失或弱 secret | 移除流量、轮换、重新部署 | 把已提交 secret 视为事件;清理历史 |
webhook-delivery-production unhealthy | 保持交付禁用 | 检查 Redis、正数限流值、白名单标志 |
| CIDR 拒绝了预期交付 | 验证 DNS 结果与订阅白名单 | 每个解析的目标 IP 必须在白名单内 |
| Redis 不可用 | 保持限流特性失败关闭 | HMAC 重放保护与 Webhook 限流器需要 Redis |
| CAP 积压 | 暂停非关键发布者,检查 RabbitMQ | 不要绕过 outbox |
意外 Null* 适配器 | 除非记录了失败关闭否则停止发布 | 覆盖前检查 production-adapter-readiness.json |
10. 切换后记录
记录:commit SHA + 产物标识;验收报告路径;CI 运行 URL;DB 备份标识;配置版本 + secret-store 版本;前后的健康快照;Operations 适配器报告;以及 Webhook 交付状态(包括生产交付是否仍禁用或已通过演练)。