-
Notifications
You must be signed in to change notification settings - Fork 0
44 v1 release operations runbook
状态:开发前发布设计基线,尚未创建迁移脚本、农业队列配置或执行任何发布
更新时间:2026-07-30
本文档定义 SmartFarm V1 从制品构建、数据库升级、进程发布、灰度开放到故障恢复的标准操作。它是发布负责人、后端、四端前端、DBA、运维、测试和业务值班共同使用的 Runbook,不表示当前环境已经具备文中所有能力。
本文使用以下事实标记:
| 标记 | 含义 |
|---|---|
现状已核对 |
已从当前源码或配置只读确认,可作为当前事实 |
V1 冻结要求 |
开发和发布必须实现的目标设计 |
实施前核验 |
当前无法从源码确认,必须在开发完成后、进入对应发布闸门前取得证据;未核验不得猜测执行 |
法律、税务、会计科目和运营资质不在本文范围内。本文只处理技术发布、交易事实、库存、业务账本、系统资金映射和运行可靠性。
- 所有发布以唯一
release_id和五个项目的 Git SHA 为身份,不以“最新代码”作为版本描述。 - 数据库变更只能前向兼容。新应用发布前先扩展结构,旧应用必须能够忽略新增表和可空扩展列。
- 任何订单、支付、退款、库存、持仓、账本、入账、生产、履约或溯源事实产生后,禁止通过删表、删流水或缩列回退。
- 资金和库存异常只能执行“查看事实 → 生成预演 → 审核 → 按原结果键修复”,禁止直接修改余额、库存汇总或历史账本。
- 关闭用户入口不等于关闭补偿链。支付/退款回调、未支付释放、Outbox、差异修复和对账必须继续运行。
- 发布过程中所有密钥只记录密钥标识、版本和校验结果,不记录明文。
- 数据库升级、应用部署、前端切换、特性开关和恢复操作均需双人复核,并保留时间、操作者和结果证据。
- 任何标为“实施前核验”的项目未完成时,所在闸门自动失败,不能用口头确认替代。
| 项目 | 当前事实 | 发布影响 |
|---|---|---|
| PHP |
composer.json 要求 PHP >=8.0,并要求 JSON、OpenSSL、GD、Redis、ZIP、PDO、cURL、BCMath、Mbstring、Ctype、Swoole 等扩展 |
生产镜像必须逐项校验扩展;当前本机 PHP 8.2.9 不是生产版本证明 |
| 依赖 | 存在 composer.lock;topthink/think-queue 锁定为 v3.0.12
|
制品必须从 lock 文件重建,禁止生产机临时更新依赖 |
| Composer 脚本 | 仅有 post-autoload-dump,执行 think service:discover 和 think vendor:publish
|
当前没有项目级“生产构建”脚本;生产 Composer 命令和参数为“实施前核验” |
| Docker |
Dockerfile 基于 leekay0218/crmeb-mer,当前未固定镜像 digest,代码 ADD 被注释,入口为 /entrypoint.sh
|
基础镜像 digest、代码如何进入镜像以及 entrypoint 行为必须在 C1 前冻结 |
| Swoole 进程 | Supervisor 程序 mer_s 使用 php think swoole restart,单进程 |
这是当前唯一已核对命令;新发布方式不得在未验证时替换命令语义 |
| 默认队列进程 | Supervisor 程序 mer_q 使用 php think queue:work --tries 2,单进程 |
只消费默认队列,不能承载 V1 四队列隔离 |
| 队列连接 |
config/queue.php 默认连接为 Redis,队列名来自 queue_name,默认 default
|
当前没有 farm-critical 等四条逻辑队列 |
| 失败任务 |
config/queue.php 的 failed.type=none
|
V1 关键失败必须由 eb_farm_job_run、消费日志和告警任务保存;发布前验证不得静默丢失 |
| Swoole 内置队列 |
config/swoole.php 可消费默认队列和 swoole_task;是否启用取决于 APP_DEBUG
|
PROD 默认应由独立 Supervisor worker 消费农业队列;不得同时重复消费同一队列 |
| Timer |
swoole.workerStart 触发 CreateTimerListen,再触发 create_timer;TimerService 仅在当前 Swoole 实例的 worker 0 注册 tick |
多应用实例仍可能各自调度,V1 必须依靠 job_name + run_key 租约防重 |
| 日志 |
config/log.php 当前为文件日志、非 JSON、按级别拆分、单文件 10MB、最多 30 个文件 |
中央采集和结构化字段尚未确认,C1 前必须完成采集验证 |
| 农业发布文件 | 当前不存在 config/farm.php、install/upgrade/farm_v1/ 和农业 Timer/Job 配置 |
未创建并通过审计前不得进入 C2 |
当前 Dockerfile 的 Supervisor 日志每个标准输出/错误文件仅配置 2MB。V1 的日志轮转、集中采集和保留策略必须由部署环境覆盖,不能把 Dockerfile 当前值当作生产容量。
| 项目 | 锁定工具事实 | 当前真实构建命令 | 当前输出契约 | 结论 |
|---|---|---|---|---|
smartfarm_admin |
package-lock.json v3;Node >=18、npm >=8;Vue CLI 3.5.3
|
npm run build |
dist/system.html、dist/system/,关闭生产 source map |
可由 CI 构建 |
smartfarm_mer |
package-lock.json v3;Node >=18、npm >=8;Vue CLI 3.5.3
|
npm run build |
dist/mer.html、dist/mer/,关闭生产 source map |
可由 CI 构建 |
smartfarm_service |
package-lock.json v3;Node >=18、npm >=8;Vue CLI 3.5.3
|
npm run build:prod |
dist/ser.html、dist/ser/,关闭生产 source map |
脚本使用 POSIX 环境变量语法,构建 Runner 必须验证 |
smartfarm_user |
package-lock.json v3;仅声明 uni-app 依赖 |
无构建脚本;唯一脚本是失败的占位 test
|
H5、小程序输出目录和发布命令未冻结 |
实施前核验,未补齐前阻断 C1 |
补充事实:
- 三个 Vue 管理端当前都没有 Dockerfile。
- 管理端和商户端 README 中出现的
build:prod/build:stage与当前package.json不一致;发布只以package.json为准。 - 后端
route/zroot.php直接读取public/system.html、public/mer.html和public/ser.html。 - 用户 H5 由后端
View::h5()读取public/index.html,静态资源当前位于public/static/。 - 前端制品不能逐文件覆盖在线目录。HTML 与其带 hash 的资源必须作为一个原子版本切换。
- 用户端 HBuilderX 版本、CLI/GUI 构建方式、H5 输出路径、微信小程序 AppID/体验版/正式版流程均为“实施前核验”;本文不编造命令。
角色名称是职责,不要求由不同自然人担任;但生产资金、数据库和密钥操作至少需要两人复核。
| 角色 | 主要职责 | 不得单独完成 |
|---|---|---|
发布负责人 Release Owner
|
建立 release manifest、主持 C0-C6、决定暂停或继续 | 单独批准资金/数据库高风险操作 |
| 后端负责人 | 后端制品、API 兼容、事件/Job/Timer、补偿链 | 直接改生产余额或库存 |
| 平台端负责人 | 平台端构建、菜单权限、发布后冒烟 | 绕过后端权限执行写操作 |
| 商户端负责人 | 商户端构建、供货和货款流程冒烟 | 使用其他商户数据验收 |
| 服务端负责人 | 客服/现场端构建、扫码/草稿/范围冒烟 | 关闭原客服回归 |
| 用户端负责人 | H5/小程序制品、支付回跳、分包和版本发布 | 在未确认后端兼容时发布正式小程序 |
| DBA | M01-M12、备份、恢复、慢 SQL、锁和容量 | 无备份执行不可逆 DDL |
| 运维/SRE | 镜像、Supervisor、Swoole、队列、日志、监控、灰度 | 在无业务确认时停关键补偿任务 |
| 密钥管理员 | Secret 注入、版本、轮换、最小权限 | 把明文写入 Git、日志或发布证据 |
| 支付负责人 | 支付/退款渠道配置、真实小额验收、渠道对账 | 单独执行账本冲正 |
| 测试负责人 | P0、REG、PERF、DR、UAT 证据 | 以口头确认替代报告 |
| 财务业务复核 | 五段对账、账本/入账/回购差异确认 | 直接修改最终余额 |
| 业务值班 | 活动、供货、农场、履约和用户影响判断 | 越权执行技术修复 |
事故指挥 Incident Commander
|
故障定级、止损、分工、沟通和恢复决策 | 同时充当所有操作复核人 |
生产联系人、电话、即时通信群、升级顺序和值班日期不写入 Git;由组织值班系统维护。C1 必须记录本次发布各角色的真实人员和可达性测试结果。
| 环境 | 目的 | 数据与第三方 | 拓扑要求 | 发布门 |
|---|---|---|---|---|
DEV |
开发自测 | 可重建专用库、专用 Redis DB/前缀、受控支付适配器 | 可单实例;允许较少 worker | 不得连接 PROD 凭据 |
SIT |
API、事件、跨端和并发集成 | 固定 Fixture、第三方 Stub/沙箱、独立文件目录 | 四逻辑队列全部存在;可故障注入 | P0 集成和幂等通过 |
UAT |
角色业务验收 | 接近真实配置;受控真实小额支付/退款 | 四端均使用候选制品 |
UAT-001~008 通过 |
PRE |
发布、恢复和容量演练 | 不使用生产用户数据;配置结构与 PROD 一致 | 与 PROD 同类 Swoole、Supervisor、Redis、数据库、对象存储和前端发布方式 | C0-C6 全流程及 DR-001~008 通过 |
PROD |
正式业务 | 禁止模拟回调和测试账号;只注入生产 Secret | 多实例数、worker 数、负载均衡和备份能力按 PRE 证据冻结 | 仅发布已签名制品 |
所有环境固定业务时区 Asia/Shanghai。数据库、PHP、Swoole、Redis、Node、npm、Composer、Web Server、Supervisor、HBuilderX 和微信开发者工具的精确版本必须进入 release manifest。当前只读事实中的 MySQL 8.0.45 和本机 PHP 8.2.9 不能自动代表未来 PRE/PROD。
环境隔离最低要求:
- 数据库实例或 schema 独立。
- Redis DB、Key 前缀和四队列名独立。
- 对象存储 bucket/目录独立。
- 支付商户号、回调域名和退款证书独立。
- 短信、模板消息、地图和物流额度独立或具备环境标识。
- H5 域名、小程序版本和 WebSocket 地址独立。
- 日志、告警、测试证据和发布制品不得跨环境混写。
- Secret 只能来自批准的 Secret Manager、CI Secret 或部署平台密钥注入。
- 数据库中的敏感系统配置由现有加密/掩码能力管理;后台响应不得返回完整值。
- Git、Markdown、截图、Figma、构建日志、错误堆栈和测试报告不得出现明文 Secret。
- release manifest 只记录
secret_id、版本、更新时间、Owner 和联通校验结果。 - 轮换生产 Secret 时不得自动回退到旧 Secret;回滚应用前先确认旧应用兼容当前 Secret。
- Swoole 常驻进程使用静态配置时,配置轮换后必须按受控方式重载并验证;具体缓存刷新/重载语义为“实施前核验”。
| 类别 | 配置/Secret | 存储位置 | Owner | 发布验证 |
|---|---|---|---|---|
| 应用 | APP_KEY |
后端环境变量 | 密钥管理员/后端 | 各实例一致,不输出到日志 |
| 应用 |
APP_DEBUG、INSTALLED、DEFAULT_TIMEZONE
|
后端环境变量 | 运维 | PROD 为安全值;Timer 能正常注册 |
| 数据库 | Host、Port、Database、Username、Password、Prefix、Charset | 后端环境变量 | DBA/密钥管理员 | 只读连通、前缀、字符集、SQL mode、权限最小化 |
| Redis | Host、Port、Password、DB | 后端环境变量 | 运维/密钥管理员 | 缓存、锁、四队列隔离和故障告警 |
| Swoole | Host、Port、worker 数、queue/task worker 参数 | 环境变量与 config/swoole.php
|
运维/后端 | PRE 压测后冻结,避免与独立农业 worker 重复消费 |
| 农业队列 | 四队列名、连接、批量、超时、租约 | 未来 config/queue.php、config/farm.php、环境变量 |
后端/运维 | 与 32、Supervisor 完全一致 |
| 自动入账 | 用户单笔 10000.00、日累计 50000.00、商户结单 100000.00
|
004_config_seed.sql 初始化,后台受控配置 |
财务/超级管理员 | 金额、币种、审计和缓存版本一致 |
| 商户结单 | 02:00 Asia/Shanghai |
系统配置 | 财务/后端 | 只归集上一自然日 |
| 入账租约 | 默认 300 秒 |
系统配置 | 后端/运维 | 不短于实际事务和故障抢占需要 |
| 业务默认值 | 选择期、自提期、观察期、在途宽限、回购比例、提醒节点、批量上限 |
config/farm.php 与系统配置 |
产品/业务 Owner、后端 | 与 12、22、32 一致;历史订单读快照 |
| 前端 API |
ENV、VUE_APP_BASE_API、VUE_APP_WS_URL
|
三个 Vue 项目的环境文件/CI | 各前端/运维 | 域名、HTTPS/WSS、跨域和版本环境正确 |
| 用户端 | API 基址、H5 域名、微信小程序 AppID、版本和合法域名 | uni-app 配置/发布平台 | 用户端/密钥管理员 | H5、体验版、正式版分别验证 |
| 腾讯地图客户端 | 现有 tx_map_key
|
系统配置 | 地图/平台运营 | 仅客户端展示,域名/小程序白名单有效 |
| 腾讯地图服务端 |
farm_tencent_map_server_key、farm_tencent_map_server_sk
|
后端 Secret/掩码配置 | 密钥管理员/后端 | 不进入前端产物;超时和降级通过 |
| 支付 | 微信、支付宝、余额及退款所需商户号、证书和回调 Secret | 现有 CRMEB 支付配置/Secret | 支付负责人/密钥管理员 | 支付、重复回调、主动退款、迟到退款闭环 |
| 消息 | 微信模板/订阅消息、短信账号与模板 | 现有 CRMEB 消息配置/Secret | 消息运营/密钥管理员 | 失败不回滚业务;站内信降级 |
| 物流 | 快递查询、电子面单、配送接口凭据 | 现有 CRMEB 物流配置/Secret | 仓储运营/密钥管理员 | 人工单号降级可用 |
| 文件 | 本地/OSS/COS/Qiniu/OBS/UCloud/S3 等实际启用存储凭据 | 现有存储配置/Secret | 运维/密钥管理员 | 上传、短时访问、备份、恢复和权限 |
| 二维码 | 签名/公开码配置 | 后端 Secret/配置 | 后端/密钥管理员 | 不编码内部主键,旧公开码稳定 |
| 扫码库 |
@zxing/browser@0.1.5、@zxing/library@0.21.3
|
服务端前端 lock 文件 | 服务端负责人 | 依赖尚未写入;旧构建链和真机 Spike 通过后才能进入 C1 |
config/farm.php、农业环境变量名和动态配置缓存刷新方式当前尚不存在。开发完成后必须形成“键名、类型、默认值、是否 Secret、是否需重启、Owner、审计方式”六列配置登记表;缺一项即 C1 失败。
release_id
release_title
change_ticket
release_owner
planned_window
smartfarm_sha
smartfarm_admin_sha
smartfarm_mer_sha
smartfarm_service_sha
smartfarm_user_sha
composer_lock_sha256
admin_package_lock_sha256
merchant_package_lock_sha256
service_package_lock_sha256
user_package_lock_sha256
backend_image_digest
frontend_artifact_sha256[]
user_h5_artifact_sha256
mini_program_version
migration_script_sha256[]
schema_version_before
schema_version_after
config_schema_version
secret_versions[]
feature_flag_snapshot_before
feature_flag_snapshot_after
backup_restore_point_id
test_run_ids[]
dr_run_ids[]
approvers[]
started_at
completed_at
rollback_release_id
Manifest 不保存 Secret 明文、真实支付报文、用户隐私或数据库备份文件本身。
| 制品 | 内容 | 完整性检查 |
|---|---|---|
| 后端制品 | 应用代码、vendor、配置模板、迁移脚本、版本文件 | Git SHA、Composer lock、镜像 digest、PHP 扩展列表 |
| 平台端 |
system.html 与 system/
|
同一构建 ID、文件 hash、资源 200、无 source map/Secret |
| 商户端 |
mer.html 与 mer/
|
同上 |
| 服务端 |
ser.html 与 ser/
|
同上;原客服路由回归 |
| 用户 H5 |
index.html 与对应静态资源 |
输出路径“实施前核验”;支付回跳和分包资源可用 |
| 微信小程序 | 体验版/正式版包及版本说明 | HBuilderX/工具版本、AppID、代码版本、体验版证据 |
| 数据库 |
install/upgrade/farm_v1/ 全部脚本 |
文件 hash、顺序、幂等/停止条件、before/after 输出 |
| Supervisor |
process/supervisor-farm.conf.example + 环境覆盖 |
四队列、日志、停止超时、进程数和命令证据 |
| 配置 |
config/farm.php、.example.env、配置 seed |
无 Secret;默认值与文档一致 |
制品必须先在 PRE 使用同一 hash 完成发布和恢复演练。PROD 不允许重新执行一次未留证据的“相同构建”。
V1 冻结目录如下,当前尚未创建:
install/upgrade/farm_v1/
000_preflight_normalize.sql
001_schema_up.sql
001_schema_down.sql
002_indexes_up.sql
002_indexes_down.sql
003_menu_seed.sql
004_config_seed.sql
verify_before.sql
verify_after.sql
README.md
process/
supervisor-farm.conf.example
001/002 必须以清晰的 M02 至 M11 段落和独立校验查询组织。若最终拆成更多文件,README.md 和 manifest 必须保持 M01-M12 的唯一顺序,不能改变迁移语义。
- 在升级副本和全新空库分别执行完整升级。
- 每组执行前记录数据库版本、表前缀、当前结构摘要、脚本 hash 和开始时间。
- 每组执行后运行该组校验,保存行数、索引、列类型、唯一键、孤儿引用和
EXPLAIN证据。 - 脚本必须满足“重复执行安全”或“明确检测已完成并停止”之一,禁止重复创建半套结构。
- 任一组失败立即停止后续组,不跨过失败继续。
- 无法证明某组是否完成时,不猜测重跑;恢复到发布前副本或由 DBA 根据校验事实决定。
- 业务事实产生前才允许执行 down;事实产生后只允许前滚修复。
- 金额扩容列不自动缩回;账号唯一约束不自动移除;历史快照和审计不回写。
- 90 张农业表不建立物理外键,发布校验必须显式执行逻辑引用和孤儿扫描。
| 组 | Up 内容 | 必须验证 | 无业务事实时的回退 | 有业务事实后的处理 |
|---|---|---|---|---|
M01 |
兼容预检;检查 CRMEB 金额列、表前缀、字符集、SQL mode、服务账号空值/重复;经审批后规范化空白账号 | 所有预检为通过;非空重复账号为 0;备份点存在 | 纯预检无需回退;规范化若需撤销只能依据备份和审批 | 不自动恢复空白值,不移除已依赖唯一约束 |
M02 |
幂等、Outbox、消费日志、Job run、审计、状态迁移、异步操作等核心支撑 | 唯一键、租约索引、状态扫描 EXPLAIN、空表 |
M02 表为空且无下游时按 down 移除 |
保留;前滚修复 |
M03 |
服务/管理员范围、服务档案、现场证据附件 | 空范围拒绝、过期范围、唯一关系、附件归属 | 无正式附件和授权事实时移除 | 保留授权/附件历史;关闭农业工作区 |
M04 |
农场、区域、地块、仓库/库位、自提点、作物、栏舍、品种、动物和养殖批次 | 编号唯一、GCJ02 成对坐标、停用引用、容量索引 | 无主数据和引用时移除 | 主数据只停用,不删除 |
M05 |
商品农业资料、材料、供货、交付、验收、退回、平台承接 | 来源 SKU、责任快照、数量守恒、退回/承接结果键 | 无供货/材料事实时移除 | 停止新供货,保留实物与责任链 |
M06 |
云仓活动、活动商品/SKU、额度、批次、池余额、库存流水、二次库存 | 发布快照、SKU 稳定 ID、活动/供货库存守恒 | 无发布/占用/库存流水时移除 | 关闭新活动,保留批次和流水 |
M07 |
订单绑定、首次明细、运费/退款、自提/核销、持仓、二次分配/退款/进度 | 创建/支付/取消/退款、单一去向、唯一绑定和结果键 | 无订单/支付/持仓事实时移除 | 关闭新下单,继续回调、释放、履约和退款 |
M08 |
用户/商户账本、结单/明细、posting、调整、回购 | 金额精度、入账唯一键、固定算例、账户映射 | 无账本/结单/posting 时移除 | 禁止删表;暂停新自动入账,保留修复和对账 |
M09 |
租地/认养订单、占用/分配、生产、任务和过程记录 | 5 分钟预留、容量并发、替换历史、订单绑定 | 无权益/生产事实时移除 | 关闭新购买,继续已购分配、生产和异常处理 |
M10 |
产出、库存流水、分配、履约、明细、包裹和农业运费 | 数量方程、多包裹、地址快照、运费和退款 | 无产出/履约事实时移除 | 停止新分配时仍须完成已生成履约 |
M11 |
统一异常、影响、方案、步骤、替换关系和溯源四表 | 版本、步骤结果键、稳定公开码、材料有效性 | 无异常/发布版本时移除 | 保留异常和公开历史;错误版本走撤回 |
M12 |
平台/商户菜单、按钮权限、配置项 | route name、页面文件、权限矩阵、默认值、Secret 空占位 | 删除本次空配置和菜单 seed,不能影响原菜单 | 只停用入口;不得通过删菜单清业务事实 |
DR-006 要求每个 M 组具备以下证据:
-
not_started:前置对象不存在。 -
completed:全部对象和校验均符合当前脚本 hash。 -
partial:只完成部分语句或校验失败,必须停止。 -
conflict:存在非本版本对象、列或索引,必须人工评审。
续跑只允许:
-
completed直接跳过; -
not_started从组首执行; -
partial/conflict先恢复或发布修正脚本,再以新 release manifest 执行。
禁止手工补一列后把原组标记成功。任何人工 DDL 都要成为版本化修正脚本。
仅在确认没有业务事实时,按 M12 → M11 → ... → M02 逆序执行 down 和校验;M01 只按备份与审批处理。只要 M05-M11 任一事实表已有真实业务记录,默认回退模式立即切换为:
关闭新入口
→ 保留扩展结构
→ 回退到兼容该结构的应用版本,或前滚修复
→ 保持回调、Outbox、修复和对账
→ 完成五段对账
- 校验 Git SHA、工作树、
composer.lockhash 和 PHP 扩展。 - 使用组织批准的 Composer 生产安装命令从 lock 文件构建。当前仓库没有冻结该命令,具体
--no-dev、autoload 优化和脚本执行参数必须在 PRE 证明后写入流水线,属于“实施前核验”。 - 运行静态检查、单元/集成测试、路由/操作码/事件/表集合审计。
- 将
install/upgrade/farm_v1、配置模板和 Supervisor 示例纳入同一后端制品。 - 构建镜像时固定基础镜像 digest,并证明代码是 COPY 入镜像还是由部署卷提供;当前 Dockerfile 的注释不能作为发布机制。
- 记录镜像 digest、PHP/Swoole/Composer 版本和扩展清单。
- 在无生产 Secret 的条件下执行镜像启动、自检和只读健康检查。
锁文件未变化时使用 lock 文件一致性安装;具体 npm 缓存和镜像源由 CI 管理,不得改变依赖解析结果。
smartfarm_admin: npm run build
smartfarm_mer: npm run build
smartfarm_service: npm run build:prod
构建后必须检查:
- 构建命令退出码为 0。
- 输出文件与
vue.config.js的 HTML/资源目录一致。 - HTML 只引用本制品内存在的资源。
- 无
.map、服务端地图 Key/SK、支付密钥、Token、内网密码或绝对本机路径。 - API、WebSocket、公共路径和 HTTPS/WSS 正确。
- 最长路由直接刷新可由后端 fallback 返回对应 HTML。
- 平台、商户、服务端原 CRMEB 页面冒烟通过。
服务端构建脚本使用 NODE_OPTIONS='--openssl-legacy-provider' 的 POSIX 写法;Windows Runner 不能直接假定可用。C1 前必须固定 Linux/容器 Runner 或经验证的等价执行方式。
当前没有可执行的 npm 构建脚本,因此 C1 前必须补齐并签字以下内容:
- HBuilderX 精确版本和插件版本。
- H5 构建入口、命令或受控 GUI 步骤。
- 微信小程序构建入口、命令或受控 GUI 步骤。
- H5 和小程序输出目录。
- H5
index.html/static到后端public/的原子发布方式。 - 小程序体验版上传、审核、正式发布、版本回退和操作权限。
-
manifest.json中 AppID、权限、地图和支付配置的环境替换方式。 - 构建日志、制品 hash 和可重复构建证据。
未完成上述核验时,只允许发布后端和三个管理端的兼容版本,不允许开放 V1 用户入口。
当前后端直接读取固定文件名,发布平台必须提供以下任一种经过 PRE 验证的原子方式:
- 版本目录 + 原子软链接切换;
- 同文件系统 staging 目录 + 原子重命名;
- 具备版本化回源的对象存储/CDN 切换。
不允许先覆盖 HTML、后复制 chunk,或反向操作。切换后保留至少一个上一稳定制品,直到 C6 完成。
- 建立 C0 manifest,冻结全部制品。
- 完成备份和
verify_before。 - 执行 M01-M12,并保持所有 V1 入口关闭。
- 发布兼容新结构的后端。
- 启动/重启 Swoole、四农业队列和 Timer,先验证空扫描及补偿能力。
- 发布平台端、商户端、服务端。
- 发布用户 H5;小程序先体验版,正式版按灰度门推进。
- 运行
verify_after、健康检查、普通商城冒烟和五段对账。 - 按灰度阶段逐项开放。
| 逻辑队列 | 任务范围 | 并发原则 | 不得被谁阻塞 |
|---|---|---|---|
farm-critical |
支付/退款事实修复、用户/商户正式入账、回购、异常执行 | 低并发、严格锁、最高优先级 | 通知、报表、大列表 |
farm-business |
活动、供货、批次、分配、履约和一般领域任务 | 有界并发、按业务键租约 | 通知渠道 |
farm-notification |
站内信、微信、短信和提醒 | 可独立扩容、允许渠道退避 | 核心业务事务 |
farm-maintenance |
对账、缓存/二维码修复、临时附件清理、失败告警 | 限速、分片;关键告警不得整体暂停 | 报表和低优先任务 |
43 中早期的下划线队列名不是当前冻结值;实施以 32 和本表的连字符名称为准。
当前锁定的 think-queue v3.0.12 支持:
php think queue:work [connection] --queue=<queue> --delay=<seconds>
--memory=<MB> --timeout=<seconds> --sleep=<seconds> --tries=<count>
四队列目标命令骨架为:
php think queue:work redis --queue=<farm-logical-queue> <environment-reviewed-options>
以下参数不能在本文中凭空固定,必须依据 32 的 Job 最大超时和 PRE 压测写入环境覆盖:
numprocs--memory--timeout--sleep--tries- Supervisor
stopwaitsecs
约束:
- worker
timeout必须大于该队列最长 Job 的业务超时;farm-maintenance包含最长 900 秒对账任务。 -
stopwaitsecs必须大于 worker timeout,并允许当前事务安全结束。 - 框架尝试次数与
eb_farm_job_run的 5 段业务退避不得叠加成无界重试;最终策略须通过故障注入。 -
farm-critical初始低并发,资金/库存业务键必须串行;扩容靠分片,不绕过锁。 - 当前默认
mer_q可以继续承载原 CRMEB 队列,但不得同时消费四农业队列。
每个农业队列一个独立 program,至少包含:
- 稳定 program 名和
process_name。 - 已验证的 queue command。
-
directory=/var/www/或环境实际应用根。 -
autostart/autorestart/startsecs/startretries。 -
numprocs环境覆盖。 -
stopasgroup/killasgroup和足够的stopwaitsecs。 - 标准输出/错误独立日志和轮转。
- 非 root 运行用户;若当前基础镜像暂不能满足,标为风险并在 PRE 验证。
- 环境变量只引用 Secret,不写明文。
process/supervisor-farm.conf.example 只是模板。PROD 实际配置 hash、Supervisor 版本、加载结果和进程 PID 必须进入发布证据。
swoole.workerStart
→ CreateTimerListen
→ app/event.php 的 create_timer
→ crmeb/listens/farm/timer/*Listen.php
→ 抢占 eb_farm_job_run(job_name + run_key)
→ 投递 crmeb/jobs/farm/*Job.php
→ 领域 Service
发布验证:
-
INSTALLED=true。 -
app/event.php中每个32的农业 Timer Listen 恰好注册一次。 - 每个 Listen 只投递,不执行批量业务。
- 同一 Swoole 实例只有 worker 0 注册 tick。
- 多实例同时触发时只有一个实例取得
job_name + run_key租约。 - 重启后出现新的
eb_farm_job_run心跳/空扫描证据。 - Timer 停机两个周期触发告警。
- Timer 恢复后从游标继续,不重置业务结果键。
这里的“不可关闭”是指:即使对应业务入口、特性开关或灰度流量已经关闭,处理既有业务事实的任务仍不得停止。
| 任务族 | 为什么必须继续 | 可暂停边界 |
|---|---|---|
| 支付成功/退款回调适配 | 外部渠道仍可能重试或迟到 | 不可因业务入口关闭而停 |
FarmOutboxDispatch |
已提交事实需要至少一次投递 | 不可停;仅短时受控切换 |
CloudUnpaidRelease、CloudPaidRepair
|
释放未支付库存、补齐已付事实 | 不可停 |
| 云仓/农业运费支付修复和退款 | 迟到款必须原路退款,不能抢回去向 | 不可停 |
| 二次分配释放、退款同步 | 已有普通订单仍会取消或退款 | 不可停 |
FarmFinancialPostingRepair |
已进入 processing/retry 的入账必须闭合 | 不可停;可关闭“新自动入账资格” |
CloudReconciliation、供货库存对账 |
关闭入口后仍需确认无悬挂 | 不可停 |
| 地块/资产预留过期与已付未分配修复 | 旧预留会占容量,已付订单需履行 | 不可停 |
| 异常已审核步骤、确认超时 | 已对用户形成承诺 | 不可整组停;新方案可暂停审核 |
| 到期、所有权切割和已审核回购 | 已存在批次到期事实 | 不可遗忘;可暂停新的审核执行并转人工 |
| 失败任务告警 | 其他补偿失败需要被发现 | 不可停 |
外部营销通知可降级或暂停发送,但通知事实、内部告警和用户可查询状态必须保留。
下表中的 FF-* 是语义 ID,不表示当前已有同名配置键。具体键名、存储位置、动态刷新和审计方式为“实施前核验”。
| 语义 ID | 控制范围 | 默认 | 关闭时行为 |
|---|---|---|---|
FF-ENTRY-ADMIN |
平台农业菜单/入口 | 关 | 已有详情可按权限只读,补偿任务不受影响 |
FF-ENTRY-MERCHANT |
商户供货入口 | 关 | 已有供货和履约继续可处理 |
FF-ENTRY-SERVICE |
服务农业工作区 | 关 | 原客服 /kefu/dashboard 不受影响 |
FF-ENTRY-USER |
用户农业/云仓入口 | 关 | 已有订单中心、退款、履约不得被隐藏到不可处理 |
FF-CLOUD-ORDER-CREATE |
新云仓首次下单 | 关 | 浏览可开,只阻止新订单 |
FF-AGRI-ORDER-CREATE |
新租地/认养下单 | 关 | 已购权益继续生产和履约 |
FF-MERCHANT-SUPPLY-SUBMIT |
新供货提交 | 关 | 已批准/在途/待检供货继续闭合 |
FF-RESALE-ALLOCATE |
新二次订单分配 | 关 | 既有分配、完成、退款继续推进 |
FF-FINANCE-AUTO-POST |
新账本自动正式入账 | 关 | 转人工审核;已 processing 的 posting 继续修复 |
FF-BUYBACK-EXECUTE |
新审核回购执行 | 关 | 到期和预案仍生成;已执行中按原键修复 |
FF-EXTERNAL-NOTIFY |
微信/短信等外部通知 | 关 | 站内状态和通知日志保留 |
开关必须区分“阻止新事实”和“完成旧事实”。不得用一个总开关直接让旧订单、退款、履约和回购失去处理入口。
| 阶段 | 开放内容 | 允许对象 | 晋级条件 | 回退动作 |
|---|---|---|---|---|
G0 暗部署 |
Schema、后端、四队列、Timer、前端制品,所有入口关闭 | 无用户流量 | verify、空扫描、普通商城回归通过 | 回退应用或前滚修复 |
G1 内部只读 |
平台/服务端只读工作台、监控和对账 | 内部白名单 | 权限、范围、日志和无泄露通过 | 关内部入口 |
G2 供应链准备 |
平台主数据、选定商户供货、验收 | 指定 merchant_id/farm_id
|
供货数量守恒、履约责任和对账通过 | 关闭新提交,闭合已有供货 |
G3 用户浏览 |
农场、套餐、云仓活动只读展示 | 内部/小流量用户 | 页面、地图降级、公开溯源通过 | 关闭用户入口 |
G4 小额交易 |
一个农场/一个活动 SKU、小库存、限定用户 | 明确 allowlist | 支付、稍后选择、三去向、退款和五段对账通过 | 停新单,保持回调/补偿 |
G5 二次代销 |
开放 FEFO 二次销售和批次进度 | 单活动/单批次 | 观察期、有效销售、节点账本无差异 | 关闭新分配,处理既有订单 |
G6 财务自动化 |
自动入账和已审核回购 | 小额阈值内 | 真实小额入账、退款冲正、回购和日结周期通过 | 关新自动入账,转人工 |
G7 全量 |
按运营范围扩大 | 正式目标范围 | 至少一个完整 02:00-03:30 日周期无 S0/S1 | 回到上一阶段 |
灰度 allowlist 的具体存储、匹配优先级和缓存刷新当前未设计完成,必须在 PRE 证明“后端强制、可审计、不会仅靠前端隐藏”后才能使用。
- 所有制品 hash 已冻结。
- PRE 拓扑和配置结构与 PROD 等价。
- M01-M12 在全新库和升级副本通过。
- 四队列、Timer、Outbox、失败告警和日志采集可观测。
- 固定 Fixture、测试时钟和角色账号可用。
- 支付、退款、地图、消息、物流和文件 Stub/沙箱已配置。
- 恢复点已建立且验证可读。
| 编号 | 场景 | 必须观察 |
|---|---|---|
PRE-001 |
支付回调重复、乱序和延迟 | 唯一付款事实、唯一库存结果、Outbox 可恢复 |
PRE-002 |
支付事务提交后进程中断 | 已付核心订单由修复任务补齐农业状态 |
PRE-003 |
同明细并发选择三种去向 | 只形成一种最终去向 |
PRE-004 |
运费成功、运费超时和选择截止并发 | 邮寄或自动代销唯一;迟到款退款 |
PRE-005 |
迟到支付、重复回调和退款 Job 重跑 | 固定退款单号且只退一次 |
PRE-006 |
活动结束、未支付释放、库存闭合并发 | 未抢库存按来源退回/承接,数量闭合 |
PRE-007 |
二次订单跨两个批次 FEFO | 分配、支付、取消和退款数量守恒 |
PRE-008 |
二次完成后部分/全量退款 | 有效销售、进度和账本按原分配冲正 |
PRE-009 |
一次进度跨多个节点 | 只生成最高节点的一组真实累计差额 |
PRE-010 |
回购与最后一笔二次销售并发 | 所有权切割、整数未售量和回购唯一 |
PRE-011 |
用户/商户 posting 中断和重跑 | 账户行锁、唯一 posting、余额和流水一致 |
PRE-012 |
地块、个体资产、批次份额最后容量并发 | 无超分配,过期预留只释放一次 |
PRE-013 |
产出不足、替换、补发和退款 | 恒等式闭合,异常步骤幂等 |
PRE-014 |
材料到期与供货/活动发布并发 | 新资格关闭,历史快照不改 |
PRE-015 |
管理员范围并发保存和即时撤权 |
scope_set_version 生效,旧页面提交失败 |
PRE-016 |
四队列停机、积压、恢复和人工原键重放 | 队列隔离、租约、游标和告警有效 |
PRE-017 |
Timer 多实例同时触发 | 单个 run_key 只有一个执行者 |
PRE-018 |
前端 HTML 与 chunk 版本切换/回退 | 无混合资源和危险旧 API 写入 |
PRE-019 |
数据库恢复与应用回退 |
DR-001~008 全部通过 |
PRE-020 |
全部农业入口关闭 |
REG-001~012 普通商城完整可用 |
每项证据至少包含 release_id、测试运行 ID、开始/结束时间、操作者、请求/业务号、日志/Trace、数据库断言、截图和结论。没有证据的“演练成功”不算通过。
平台页面按已冻结的五组展示:首次订单、库存、二次零售、业务账本、资金入账。支付和退款事实贯穿首次订单及二次零售,不单独制造第六套事实。
| 段 | 核对来源 | 核心等式/唯一性 | 差异示例 |
|---|---|---|---|
R1 首次订单/支付/退款 |
CRMEB group/order/product、farm_order_binding、云仓首次明细、支付渠道事实、首次退款影响、运费支付/退款 |
一条订单明细一个绑定;渠道成功金额=本地应付;退款单号和渠道事实唯一 | 渠道已付但农业待付、重复交易号、退款成功未冲业务 |
R2 供货/活动/去向库存 |
供货数量链、活动占用、批次池、不可变库存流水、邮寄/自提/代销迁移 |
33 的供货、活动和批次恒等式全部成立 |
未支付未释放、退回实物未完成却恢复来源库存 |
R3 二次零售 |
CRMEB 二次订单/退款、云仓 resale stock、FEFO allocation、观察期、有效销售和进度 | 订单明细分配量=各批次分配和;有效销售净额与退款闭合 | 已完成未生效、退款未释放、跨批次悬挂 |
R4 业务账本/结单 |
持仓、用户本金/收益/回购账本、商户供货账本、结单、回购、调整 | 累计应得-历史已结=本期;结单明细只归集一次;尾差按固定规则 | 节点重复账本、结单漏项、回购池与明细不等 |
R5 正式入账/账户 |
farm_financial_posting、CRMEB UserBill、用户余额、商户余额、farm_supply_settlement 财务流水 |
一个 posting_key 一次正式入账;账户变动=对应最终流水 |
posting 成功无账户流水、余额变化无 posting、重复入账 |
- 每日
02:10 Asia/Shanghai由CloudReconciliationJob分片运行。 - 每次发布在灰度前运行一次。
- C6 前至少覆盖一个完整自然日结单/入账周期。
- 支付、退款、库存或 posting 故障恢复后立即运行受影响范围对账。
- 数据库恢复和应用回退后必须运行全量五段对账。
- 区分正常时间差、可重试技术差异和业务恒等式错误。
- 正常时间差必须有预计闭合时间和对应 Job,不允许无限挂起。
- 金额、库存或所有权硬差异立即冻结受影响对象的新动作。
- 使用
CW_RECONCILIATION_PREVIEW生成不可变差异方案,不改业务事实。 - 财务/技术双人审核,确认来源版本未变化。
- 使用
CW_RECONCILIATION_EXECUTE按批准动作和原结果键执行。 - 可恢复失败使用同一 operation/result key 重试。
- 修复后重跑五段对账和普通商城受影响回归。
- 历史账本、库存流水和 posting 不覆盖;通过补记、冲正或补事件恢复。
发布通过线:
- 支付金额冲突、重复退款、库存恒等式、重复账本、重复 posting 差异为 0。
- 允许存在的时间差全部有 owner、截止时间和可观测任务。
- 任何未解释差异均阻断 C5/C6。
- 当前应用日志是非 JSON 文件日志。
- 当前 Supervisor 日志容量很小。
- 当前没有可确认的 Prometheus/OpenTelemetry/APM 接入。
- 当前默认队列不保存框架 failed job。
- 当前没有农业健康检查和业务仪表盘。
以上能力的具体产品、采集 Agent、指标协议和告警平台属于“实施前核验”;Runbook 只冻结必须观测的信号和告警语义。
| 层 | 指标 |
|---|---|
| HTTP/Swoole | 请求量、2xx/4xx/5xx、P50/P95/P99、活跃连接、worker 数、重启数、内存、协程/连接池等待 |
| MySQL | 连接、事务、死锁、锁等待、慢 SQL、复制延迟、磁盘、binlog、备份状态 |
| Redis | 可用性、延迟、内存、连接、阻塞、淘汰、每队列深度和最老消息年龄 |
| Supervisor | 每个 program 的状态、PID、重启次数、异常退出和日志写入 |
| 文件/对象存储 | 上传失败、读取失败、签名失败、容量、备份和孤儿临时附件 |
| 第三方 | 支付/退款、地图、短信/微信、物流成功率、超时、限流和配额 |
| 前端 | 制品版本、JS 错误、资源 404、API 失败、白屏、H5/小程序版本分布 |
- 核心已支付但农业仍待付款数量和最老年龄。
- 已过选择截止仍待选择数量。
- 运费
paying/late/refund_pending数量和金额。 - 供货、活动和批次库存恒等式失败数。
- 材料已过期仍具新供货资格商品数。
- 二次订单未分配、观察期已过未生效、退款未冲正数量。
- 达节点未生成账本数量。
- 用户/商户待入账超时、失败、冻结数量和金额。
- posting 租约超时、重复幂等命中、事务回滚和待追偿金额。
- 到期未完成所有权切割/回购数量和金额。
- 已付未分配地块/资产、过期预留、已验收未分配产出数量。
- Outbox pending/retry/final failed、消费失败、Job 积压和通知失败。
- 每日五段对账各段差异数量和金额。
以下为 V1 初始目标,必须在 PRE 用真实周期校准后冻结:
| 条件 | 建议等级 |
|---|---|
| 支付金额/交易号冲突、重复退款、重复 posting、账户差异 | SEV-1 |
| 任一资金/库存恒等式失败 | SEV-1 |
farm-critical 最老消息超过 5 分钟或连续两个周期未下降 |
SEV-2;超过 15 分钟升 SEV-1
|
Timer 两个应运行周期无 job_run
|
SEV-2 |
| Outbox 超过两个 dispatch 周期未投递 | SEV-2 |
| 最终失败 Job 大于 0 | 资金/库存为 SEV-1,其他为 SEV-2/3
|
| API 5xx 5 分钟超过 1% 或 P95 连续三窗超测试基线 | SEV-2 |
| 外部通知失败率 10 分钟超过 10% |
SEV-3,业务事实不回滚 |
| 地图不可用 |
SEV-3,启用地址/示意图降级 |
| 备份失败、binlog 中断或恢复点过期 | SEV-1 |
V1 农业日志至少带:
timestamp
level
environment
release_id
instance_id
trace_id
request_id
operation_code
event_id
consumer_name
job_name
run_key
aggregate_type
aggregate_id
business_no
actor_type
result
error_code
duration_ms
禁止记录 Token、密码、支付密钥、完整回调报文、完整地址、身份证件、完整手机号、富文本和附件永久 URL。当前非 JSON 日志若不改格式,必须提供可靠解析规则并验证字段完整;否则在开发阶段增加独立结构化农业日志通道。
| 对象 | 保护方式 | 恢复依据 |
|---|---|---|
| MySQL | 发布前一致性全量备份 + 持续 binlog/PITR | backup ID、binlog 位点/时间、校验和 |
| Redis | 配置/持久化按现有运维策略;农业正确性不把 Redis 当唯一事实 | MySQL Outbox、Job run、业务结果键重建 |
| 对象存储 | 版本化/跨区域或等价备份、对象清单和 hash | attachment ID、storage path、content hash |
| 应用制品 | 不可变镜像和前端制品仓库 | release manifest 和 SHA256 |
| 配置 | 脱敏配置快照、Secret 版本引用、菜单/权限导出 | config schema version 和审计 |
| 监控/日志 | 集中存储、只读事故证据 | trace/release/operation ID |
下列是设计目标,不是当前环境承诺;必须经 PRE 实测后签字:
| 对象 | RPO 目标 | RTO 目标 | 状态 |
|---|---|---|---|
| MySQL 交易事实 | ≤5 分钟 |
≤60 分钟 |
实施前核验 |
| Redis 农业队列/缓存 | 不以 Redis 作为唯一事实 |
≤30 分钟 重建/恢复消费 |
实施前核验 |
| 后端和三个 Web 制品 |
0,不可变制品 |
≤30 分钟 |
实施前核验 |
| 用户 H5/小程序 | H5 0;小程序受平台发布机制限制 |
H5 ≤30 分钟,小程序另测 |
实施前核验 |
| 对象存储证据 | ≤1 小时 |
≤4 小时 |
实施前核验 |
| 配置与 Secret 版本 | 0 |
≤30 分钟 |
实施前核验 |
- 确认备份任务健康、上次恢复演练有效。
- 在发布前创建专用恢复点,记录 backup ID 和数据库时间。
- 记录支付渠道、队列、Outbox 和进行中高风险 operation 的水位。
- 导出脱敏结构/配置/菜单摘要和 Secret 版本引用。
- 校验备份大小、校验和、可读性和存储位置。
- 不在
02:00~03:40的结单、posting、对账、溯源材料和附件清理密集窗口安排未经压测的重型全量备份。 - 备份工具、具体命令、加密、保留周期和跨区域策略由生产平台确定,C2 前必须完成“实施前核验”。
- 事故指挥批准恢复目标时间,冻结新交易入口。
- 保留支付/退款回调接收证据;若无法正常处理,必须安全落盘/排队,不能丢弃。
- 在隔离环境恢复全量备份和目标时间前的 binlog。
- 注入隔离 Secret,禁止隔离环境向真实用户、支付、短信和物流发送副作用。
- 运行
verify_after、90 表完整性、逻辑孤儿扫描和五段对账。 - 对恢复点之后已被外部渠道确认的支付/退款事实建立差异清单,按原业务号补偿。
- 发布与恢复库兼容的应用和四队列,先只读验证。
- 经 DBA、后端、支付、财务和发布负责人共同批准后切换。
- 切换后继续保持新交易关闭,先清 Outbox/关键队列并复跑对账。
- 灰度恢复写入,完成普通商城和农业冒烟。
禁止只恢复数据库而让旧应用、旧缓存和新支付回调继续混用。
| case_id | 演练步骤 | 通过条件 | 证据 | Owner |
|---|---|---|---|---|
DR-001 |
建立恢复点;隔离恢复 MySQL;运行 verify_after、孤儿扫描和五段对账 |
恢复点可用,结构/数据/账本/资金无未解释差异 | backup ID、耗时、SQL 输出、对账报告 | DBA/财务 |
DR-002 |
关闭农业入口;回退后端到上一兼容制品;保留扩展表和补偿链 | 普通商城可用,旧版本不误写农业事实 | 镜像 digest、开关快照、REG 报告 | 运维/后端 |
DR-003 |
停四队列;制造积压;恢复 worker 并按原键重放 | 积压在目标时间内清空,无重复事实 | 队列曲线、job_run、业务断言 | 运维/后端 |
DR-004 |
中断 Outbox 分发;业务事务继续写事实;恢复扫描 | 事实不丢,至少一次投递,消费者幂等 | outbox/consume log、结果键 | 后端 |
DR-005 |
重放支付/退款回调并制造迟到支付 | 最终状态唯一,迟到款按固定单号退款 | 渠道沙箱、订单、退款、对账 | 支付/后端 |
DR-006 |
在 M01-M12 不同位置模拟失败并续跑/恢复 | 能判定完成状态;重复执行安全或明确停止 | 每组状态、脚本 hash、恢复日志 | DBA |
DR-007 |
回退三个 Web 制品、用户 H5/CDN,验证缓存和旧 API | HTML/chunk 版本一致,无危险旧写入 | 制品 hash、浏览器网络记录、截图 | 前端/运维 |
DR-008 |
全部农业入口关闭,保留补偿任务 | 商品、营销、下单、支付、退款和客服冒烟通过 |
REG-001~012 报告 |
测试/各端 |
演练频率:
- 每个首次 PROD 发布前完整执行。
- 迁移、支付适配、队列架构、备份平台或前端发布机制变化后重新执行相关 DR。
- 正式运行后至少按组织灾备周期重复;具体周期为“实施前核验”。
| 等级 | 定义 | 响应目标 | 发布/业务动作 |
|---|---|---|---|
SEV-1 |
资金/库存错误、重复扣款/入账、数据泄露、不可恢复数据风险、核心全站不可用 | 5 分钟确认,立即召集事故组 | 停新相关写入,保持回调/补偿,准备回退或恢复 |
SEV-2 |
P0 主流程不可用、关键队列积压、单端大面积不可用、恢复目标受威胁 | 15 分钟确认 | 降级或回到上一灰度阶段 |
SEV-3 |
有替代路径的局部故障、通知/地图/报表异常 | 30 分钟确认 | 启用降级,核心交易可继续 |
SEV-4 |
无即时用户影响的告警、容量趋势或低风险缺陷 | 下一个工作时段 | 建单跟踪 |
响应目标需由实际组织和值班能力在 C1 前确认。不能达到目标时应调整承诺,不得在文档中保留虚假 SLA。
每次交接至少说明:
- 当前 release ID 和灰度阶段。
- 活动、供货、批次、回购和农业生产中的高风险对象。
- 四队列深度、最老消息、最终失败任务。
- 未闭合支付/退款/运费、posting 和五段对账差异。
- 当前特性开关和临时降级。
- 最近备份/恢复点和可用性。
- 未关闭事故、负责人和下一检查时间。
- 发现:确认告警真实,关联 release/trace/business ID。
- 定级:事故指挥确定 SEV、影响端、对象、金额和数量范围。
- 止损:关闭产生新风险的具体入口,不关闭回调和补偿。
- 保全证据:记录开关、队列水位、日志、数据库快照和第三方事实。
- 诊断:按五段定位首次不一致位置,不从最终余额倒猜。
- 预演修复:生成受影响集合、动作、金额/数量和版本。
- 审批执行:按原结果键修复;禁止直接 SQL 改最终值。
- 验证:重跑对账、P0 冒烟和受影响回归。
- 恢复:按灰度顺序恢复,不一次全开。
- 复盘:记录根因、时间线、影响、修复、监控缺口和永久行动项。
| 故障 | 立即动作 | 必须保留 | 恢复依据 |
|---|---|---|---|
| 支付重复/金额冲突 | 关闭新相关下单,冻结受影响明细 | 回调接收、渠道查询、支付修复 | 渠道事实 + R1 对账 |
| 退款积压/迟到支付 | 保持固定退款单号,不新建第二单 | 退款 Job、渠道回调、告警 | 退款最终状态 + R1/R5 |
| 库存恒等式失败 | 冻结活动/批次/供货的新分配 | 库存流水、对账预演 | R2/R3 等式为 0 差异 |
| 重复账本/入账差异 | 关闭新自动 posting,冻结来源 | posting repair、账户流水和审计 | R4/R5 |
| 四队列/Redis 故障 | 停新高风险写入,恢复连接/worker | MySQL Outbox、job_run、业务事实 | 积压清空且无重复 |
| Timer 停止 | 检查 Swoole worker 和注册;恢复调度 | 已存在队列和业务结果键 | 两周期内 job_run 恢复 |
| 数据库故障 | 冻结写入,协调支付回调,执行隔离恢复 | 备份、binlog、外部渠道事实 | DR-001 |
| 前端白屏/资源混版 | 关对应入口,原子回退制品 | 后端补偿和旧订单入口 | DR-007 + API 兼容 |
| 地图/短信/物流故障 | 启用地址、站内信、人工单号降级 | 核心订单/履约事实 | 降级流程可完成 |
- C2-C5 任一闸门校验失败。
- 出现 S0/S1 测试缺陷或
SEV-1生产事故。 - 支付金额、交易号、退款或 posting 唯一性失败。
- 库存/权益恒等式失败且影响继续扩大。
- M01-M12 出现
partial/conflict。 - 关键队列无法在约定窗口恢复。
- 新版本破坏普通商城
REG-001~012。 - 前端与 API 不兼容并产生危险写入风险。
| 模式 | 适用 | 动作 |
|---|---|---|
R-A 制品回退 |
Schema 向后兼容,尚无新事实或旧应用能安全忽略 | 关闭入口,原子回退前端/后端,保留结构 |
R-B 入口停用 + 前滚修复 |
已有订单、库存、账本或生产事实 | 停新事实、保留补偿链、发布修正版本 |
R-C 数据库恢复 |
数据库损坏或不可用,且具备完整恢复方案 | 隔离恢复、补外部渠道事实、整体切换 |
R-D 单端前端回退 |
后端保持兼容,某端制品故障 | 回退该端完整制品,不单独回退 HTML/chunk |
- 事故指挥宣布暂停,记录触发原因和时间。
- 保存当前 release/开关/队列/对账/数据库水位。
- 关闭产生新风险的最小入口。
- 保持支付/退款回调、Outbox、释放、修复和对账。
- 判断有无 V1 业务事实,选择
R-A/B/C/D。 - 回退前端时确认旧前端与当前 API/Schema 兼容。
- 回退后端时确认旧后端会忽略新表、新事件版本和新配置。
- 只有“无任何业务事实”且 down 演练通过时才逆序回退 M12-M02。
- 运行
verify_after、五段对账和REG-001~012。 - 按灰度阶段恢复;原失败 release 不得重新标记成功。
- 生产交易后执行删表 down。
- 缩回已扩容的金额列。
- 删除库存流水、账本、posting、审计或 Outbox 来“消除差异”。
- 直接改用户/商户余额。
- 关闭回调后忽略渠道已成功事实。
- 以清空 Redis 队列替代业务补偿。
- 回退一个 HTML 文件但保留另一个版本的 chunk。
- 在未完成五段对账前重新全量开放。
| 闸门 | 目标 | 必需证据 | 阻断条件 | 签字角色 |
|---|---|---|---|---|
C0 变更冻结 |
范围、SHA、任务、风险和回退清楚 | release manifest 草案、测试/UAT/DR 报告、变更和依赖清单 | SHA 未冻结、S0/S1、核心规则未定 | 发布、产品、测试、各技术 Owner |
C1 制品与配置 |
五项目制品可重复、配置和 Secret 就绪 | 制品 hash、镜像 digest、构建日志、配置表、Secret 版本、值班表 | 用户端命令未冻结、Secret 泄露、基础镜像浮动、四队列模板缺失 | 发布、运维、密钥、各端 |
C2 备份与预检 |
可恢复且数据库兼容 | 恢复点、verify_before、M01 结果、容量/账号冲突报告 |
备份不可恢复、重复账号、列容量/字符集/SQL mode 冲突 | DBA、运维、后端 |
C3 数据升级 |
M02-M12 全部完成且可验证 | 每组日志、hash、verify_after、90 表/索引/配置/菜单集合 |
任一组 partial/conflict、孤儿引用、唯一键/索引缺失 | DBA、后端、发布 |
C4 应用与进程 |
后端、四端、Supervisor、Timer 正常且入口关闭 | 进程/PID、四队列、Timer、健康检查、制品版本、普通商城冒烟 | 重复消费者、Timer 无心跳、前端混版、REG 失败 | 运维、各端、测试 |
C5 灰度验证 |
小范围真实闭环无硬差异 | 支付/退款/三去向/二次销售/履约/账本/五段对账、监控曲线 | 未解释支付/库存/账本差异、SEV-1/2 | 发布、支付、财务、业务、测试 |
C6 全量与结项 |
完成全量观察和一个日周期 | 02:00 结单、02:05 posting、02:10 对账及后续任务证据,最终 manifest | 日周期未跑、差异未闭合、补偿任务异常 | 发布、运维、财务、业务 |
任一闸门只有“通过/失败”两种结果,不使用“先上线再补证据”。失败后必须建立新 release ID 或明确恢复同一 release 的条件和审批。
- 五项目 SHA 和 lock 文件已冻结。
- P0、REG、PERF、DR、UAT 报告关联本次 SHA。
- 数据库变更与 M01-M12 映射完成。
- API 前后兼容和前端原子切换方案完成。
- 回滚模式、触发阈值和事故指挥确定。
- 后端镜像 digest 和基础镜像 digest 已记录。
- 平台/商户/服务端/H5/小程序制品 hash 已记录。
- 用户 uni-app 构建与回退流程已核验。
- 四农业队列 Supervisor 实际配置通过 PRE。
- 配置/Secret Owner、版本和连通性通过。
- 日志、指标、告警和值班可达性通过。
- 发布前恢复点已建立并校验。
-
verify_before.sql和 M01 通过。 - M02-M12 按顺序执行,无 partial/conflict。
-
verify_after.sql、90 表、索引、逻辑引用、菜单和配置通过。 - 所有 V1 入口仍关闭。
- 后端版本/镜像正确。
- Swoole 仅运行预期实例。
- 四逻辑队列各自消费,无重复消费者。
- Timer 每项恰好注册一次且有租约证据。
- 平台、商户、服务、用户 H5 制品版本一致。
- 小程序体验版通过。
-
REG-001~012和最小农业只读冒烟通过。
- 按 G1-G6 逐阶段开放,不跳级。
- 支付、重复回调、退款、库存和 posting 无硬差异。
- 云仓单一去向、二次销售和结算模式符合快照。
- 租地/认养只邮寄,权益与履约闭合。
- 五段对账为 0 硬差异。
- 无 SEV-1/2,队列积压在目标线内。
- 至少完成一个 02:00-03:30 日任务周期。
- 商户结单、posting、五段对账、材料/附件任务正常。
- 首日监控、日志、告警和业务反馈已复核。
- 最终开关快照、证据和 manifest 已归档。
- 上一稳定制品和恢复点保留到观察期结束。
- 未决问题已分配 Owner、优先级和截止时间。
- 四队列状态、最老消息、最终失败和租约超时。
- Timer 最近一次运行、扫描数、成功/失败和下一次计划。
- 支付/退款/运费待修复数量和金额。
- Outbox 和事件消费差异。
- 库存/权益恒等式告警。
- posting、冻结、待追偿和回购。
- 备份、binlog、对象存储和磁盘。
- API、数据库、Redis、第三方成功率。
-
02:00商户结单。 -
02:05商户 posting 及后续补偿。 -
02:10五段对账。 -
03:10溯源材料到期。 -
03:30未绑定临时附件清理。 - 核对任务是否按
Asia/Shanghai归属正确业务日。 - 对所有非零差异建立异常或修复 operation。
- 使用独立变更单和
request_id。 - 记录 before/after、原因、Owner 和影响对象。
- 高风险阈值、回购、自动入账和权限范围双人复核。
- 验证 Swoole/worker 是否需要重载。
- 变更后执行最小冒烟和相关对账。
- Secret 值不进入审计正文,只记录 Secret 版本。
- 先读取事实、版本和原结果键。
- 生成预演,显示预计影响数量、金额、事件和对象。
- 审核后使用原 event/job/posting/result key。
- 重放操作写
eb_farm_audit_log。 - 重放后检查主事实、流水、Outbox、消费日志和最终投影。
- 不提供“忽略幂等重新生成”按钮。
以下事项全部完成前,本文不能从“设计基线”提升为“可执行生产 Runbook”:
- 后端生产 Composer 命令和构建 Runner。
- Docker 基础镜像 digest、代码注入和
/entrypoint.sh行为。 -
config/farm.php、农业环境变量和动态开关刷新方式。 - M01-M12 实际 SQL、down、before/after 和脚本 hash。
- 四队列 Supervisor 完整命令、进程数、超时、尝试次数和日志。
- Swoole 内置队列与独立 worker 不重复消费的证明。
- 农业 Timer 全注册、分布式租约和故障恢复。
- 用户 uni-app H5/微信小程序可重复构建、上传和回退。
- 前端原子发布/CDN 缓存策略。
- 生产 DB/Redis/Swoole/Node/npm/Composer/Supervisor/HBuilderX 精确版本。
- Secret Manager、密钥轮换和常驻进程重载。
- 日志集中采集、结构化字段、指标、告警和值班平台。
- 数据库/对象存储备份工具、加密、保留和跨域策略。
- RPO/RTO 的 PRE 实测结果。
- 支付/退款渠道真实小额闭环。
- 灰度 allowlist 的后端强制和审计。
-
DR-001~008全部证据。 - C0-C6 的真实签字人和事故联系人。
- 20-v1-events-jobs-permissions-notifications.md
- 21-v1-code-change-blueprint.md
- 22-v1-test-acceptance-release-manual-plan.md
- 24-g3-g4-decision-register.md
- 26-pre-development-master-checklist.md
- 29-g3-technical-spike-report.md
- 31-v1-write-operation-contract-registry.md
- 32-v1-event-job-operation-registry.md
- 33-v1-state-exception-transaction-matrix.md
- 34-v1-database-field-dictionary.md
- 35-v1-page-api-file-trace.md
- 36-v1-er-diagrams.md
- 37-v1-api-field-contract-registry.md
- 43-v1-test-catalog-and-fixtures.md
- 首页
- 项目总览
- 项目立项
- 端与角色
- 供应链经营闭环
- 模块地图
- V1 范围 PRD
- 任务拆解
- 结算与账本
- V1 结算口径
- 云仓秒杀
- CRMEB 底座能力映射
- 当前菜单页面审计
- V1 决策与术语
- 云仓流程与状态机
- 租地认养与溯源 PRD
- V1 数据模型草案
- 开发前设计计划
- V1 信息架构
- 页面与原型规格
- V1 API 契约草案
- 事件任务权限通知
- 五项目代码改造蓝图
- 测试验收发布与手册计划
- CRMEB 视觉基线审计
- G3/G4 决策登记表
- 用户端 uni-app 复用审计
- 开发前主清单
- 自主设计工作指引
- V1 需求追踪矩阵
- G3 技术专项验证报告
- V1 P0 页面矩阵
- 写操作契约注册表
- 事件任务操作注册表
- 状态异常事务矩阵
- 数据库字段字典
- 页面 API 文件追踪
- V1 ER 图
- API 字段契约注册表
- 平台管理员手册
- 商户手册
- 用户帮助
- 服务与现场手册
- 开发任务包
- 测试目录与 Fixtures
- 发布与运维手册
- 设计交付与研发交接