6.0 KiB
6.0 KiB
Supply-Intelligence 生产上线 Runbook(2026-05-10)
状态:当前有效
仓库:/home/long/project/supply-intelligence
适用范围:首版生产上线灰度、回滚与紧急止损
0. 前提假设
- 部署形态:并入 supply-api 主仓运行(独立运行仅为轻量可选形态)
- 数据库:PostgreSQL(与 supply-api 共存或独立实例)
- 当前 consumer:
gateway(本地 apply/ack 语义,真实远端 sub2api 集成待后续补齐) - 网关入口:/internal/supply-intelligence/*(由 supply-api 统一暴露)
1. 上线前检查清单(Checklist)
执行人:DevOps + QA
触发条件:任何生产上线前
| # | 检查项 | 验证命令/方法 | 通过标准 |
|---|---|---|---|
| 1 | 数据库迁移已应用 | psql -c "\dt supply_intelligence_*" |
所有表存在 |
| 2 | 健康检查端点可达 | curl /internal/supply-intelligence/healthz |
HTTP 200 |
| 3 | 核心 metrics 可抓取 | curl :9090/metrics | grep supply_intelligence_ |
有输出 |
| 4 | PostgreSQL 集成测试通过 | go test ./internal/httpapi -run TestPostgresE2E |
PASS |
| 5 | 发布事务测试通过 | go test ./internal/repository -run TestPostgresPublishPackageAtomically |
PASS |
| 6 | 无 pending 高危漏洞 | 查阅 QA_PRODUCTION_GATE_REVIEW | 无 OPEN critical |
| 7 | 回滚脚本可执行 | ./scripts/gateway_closure_rollback.sh --dry-run |
无报错 |
2. 灰度步骤(Rollout)
执行人:DevOps
触发条件:上线前检查全部通过
2.1 第一阶段:影子运行(Shadow / 0% 流量)
- 部署到生产环境,但不对真实用户暴露新路由
- 仅执行内部健康检查和 metrics 抓取
- 观察 5 分钟,确认无 panic / 无异常错误日志
2.2 第二阶段:单账户灰度(1 Account)
- 选择一个测试 account,准备 candidate + draft package
- 执行完整链路:publish → consume-once → ack → admission-state
- 验证 admission-state 返回
gateway_sync_status=applied - 观察 metrics:
supply_intelligence_gateway_events_processed_total有增量
2.3 第三阶段:小批量放量(10% Account)
- 逐步放开 routing_enabled=true 的 account
- 每批放量后观察 10 分钟
- 关键观察指标(见第 4 节)
- 如无异常,继续放量至 50% → 100%
3. 回滚步骤(Rollback)
执行人:DevOps / 值班工程师
触发条件:灰度指标异常、错误率突增、或收到 QA/PM 止损指令
3.1 立即止损
# 1. 暂停 gateway runtime(阻止新事件被消费)
curl -X POST "$BASE_URL/internal/supply-intelligence/gateway/runtime/pause"
# 2. 获取当前 runtime 状态,记录 pending/failed 事件基数
curl "$BASE_URL/internal/supply-intelligence/gateway/runtime-status"
# 3. 停止新 publish 请求(在 LB/网关层切断 /publish/package-event 路由)
3.2 评估影响面
# 查询 pending 事件清单
curl "$BASE_URL/internal/supply-intelligence/gateway/package-changes?consumer=gateway"
# 查询 failed 事件数量
curl "$BASE_URL/internal/supply-intelligence/gateway/runtime-status" \
| python3 -c "import sys,json; d=json.load(sys.stdin); print('failed:', d.get('failed_events',0), 'pending:', d.get('pending_retry_events',0))"
3.3 决策分支
| 场景 | 操作 |
|---|---|
| 仅 gateway consumer 故障,publish 正常 | 暂停 runtime,修复 consumer,恢复后 resume |
| publish 导致脏数据 | 暂停 runtime,DB 回滚到快照,重新放量 |
| 无法快速定位根因 | 全量回滚:下线 supply-intelligence 路由,保持 DB 不变,待修复后重试 |
3.4 回滚后确认
- runtime 处于 paused 状态
- 无新的 gateway event 被消费
- metrics 中
supply_intelligence_gateway_events_processed_total停止增长 - 供应路由回到旧逻辑(supply-api 主仓原有逻辑)
4. 观察指标与止损条件
| 指标 | 来源 | 正常基线 | 止损阈值 |
|---|---|---|---|
| gateway event 处理延迟 | supply_intelligence_gateway_event_latency_seconds P99 |
< 1s | > 5s |
| gateway event 失败率 | failed / processed |
< 1% | > 10% |
| pending retry 事件数 | supply_intelligence_gateway_pending_retry_events |
0-5 | > 50 |
| 发布事务冲突率 | 日志/DB ON CONFLICT |
0 | > 5/分钟 |
| 健康检查失败 | /healthz |
0 | 连续 3 次失败 |
| panic / error 日志 | 日志系统 | 0 | 任何 panic |
5. 上线后巡检(Post-Launch Patrol)
5.1 首 24 小时(高频)
执行人:值班工程师
频率:每 2 小时一次
runtime-status中 failed_events == 0 或已知可控gateway_events_processed_total增长与 publish 频率匹配- 无异常 latency spike
- DB 连接池未耗尽
5.2 首 72 小时(中频)
执行人:值班工程师
频率:每 6 小时一次
- pending retry 事件无积压
- snapshot 与最新 applied event 一致
- admission-state API 响应正常
- 灰度 account 的 probe/admission 链路未受影响
5.3 首周(低频)
执行人:QA / DevOps
频率:每日一次
- 回顾昨日 failed 事件,分类根因
- 检查 metrics 是否有漂移趋势
- 确认无未授权的 consumer 消费事件
6. 已知限制与后续补齐
| 限制 | 影响 | 计划 |
|---|---|---|
| 真实远端 gateway(sub2api)未集成 | consumer apply 为本地 mock | P2-2 / G4 |
| 独立 Redis 未作为首期依赖 | 无分布式锁/缓存 | 当前单实例足够 |
| 向量数据库未接入 | 知识库检索降级为文本匹配 | P2-3 |
| 灰度放量无自动降级开关 | 需人工执行 rollback 脚本 | 后续补自动化 |
7. 紧急联系人
| 角色 | 职责 | 备注 |
|---|---|---|
| 值班工程师 | 立即执行 pause / 回滚 | 7x24 |
| TechLead | 技术根因定位 | 30min 内响应 |
| QA | 判定是否继续放量 | 基于证据包 |
| PM | 业务影响评估 | 对外沟通 |
版本:v1.0 | 创建:2026-05-10