Skip to content

44 v1 release operations runbook

技术老胡 edited this page Jul 30, 2026 · 1 revision

SmartFarm V1 发布与运维手册

状态:开发前发布设计基线,尚未创建迁移脚本、农业队列配置或执行任何发布

更新时间:2026-07-30

本文档定义 SmartFarm V1 从制品构建、数据库升级、进程发布、灰度开放到故障恢复的标准操作。它是发布负责人、后端、四端前端、DBA、运维、测试和业务值班共同使用的 Runbook,不表示当前环境已经具备文中所有能力。

本文使用以下事实标记:

标记 含义
现状已核对 已从当前源码或配置只读确认,可作为当前事实
V1 冻结要求 开发和发布必须实现的目标设计
实施前核验 当前无法从源码确认,必须在开发完成后、进入对应发布闸门前取得证据;未核验不得猜测执行

法律、税务、会计科目和运营资质不在本文范围内。本文只处理技术发布、交易事实、库存、业务账本、系统资金映射和运行可靠性。


一、发布原则

  1. 所有发布以唯一 release_id 和五个项目的 Git SHA 为身份,不以“最新代码”作为版本描述。
  2. 数据库变更只能前向兼容。新应用发布前先扩展结构,旧应用必须能够忽略新增表和可空扩展列。
  3. 任何订单、支付、退款、库存、持仓、账本、入账、生产、履约或溯源事实产生后,禁止通过删表、删流水或缩列回退。
  4. 资金和库存异常只能执行“查看事实 → 生成预演 → 审核 → 按原结果键修复”,禁止直接修改余额、库存汇总或历史账本。
  5. 关闭用户入口不等于关闭补偿链。支付/退款回调、未支付释放、Outbox、差异修复和对账必须继续运行。
  6. 发布过程中所有密钥只记录密钥标识、版本和校验结果,不记录明文。
  7. 数据库升级、应用部署、前端切换、特性开关和恢复操作均需双人复核,并保留时间、操作者和结果证据。
  8. 任何标为“实施前核验”的项目未完成时,所在闸门自动失败,不能用口头确认替代。

二、当前工程发布基线

1. 后端 smartfarm

项目 当前事实 发布影响
PHP composer.json 要求 PHP >=8.0,并要求 JSON、OpenSSL、GD、Redis、ZIP、PDO、cURL、BCMath、Mbstring、Ctype、Swoole 等扩展 生产镜像必须逐项校验扩展;当前本机 PHP 8.2.9 不是生产版本证明
依赖 存在 composer.locktopthink/think-queue 锁定为 v3.0.12 制品必须从 lock 文件重建,禁止生产机临时更新依赖
Composer 脚本 仅有 post-autoload-dump,执行 think service:discoverthink 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.phpfailed.type=none V1 关键失败必须由 eb_farm_job_run、消费日志和告警任务保存;发布前验证不得静默丢失
Swoole 内置队列 config/swoole.php 可消费默认队列和 swoole_task;是否启用取决于 APP_DEBUG PROD 默认应由独立 Supervisor worker 消费农业队列;不得同时重复消费同一队列
Timer swoole.workerStart 触发 CreateTimerListen,再触发 create_timerTimerService 仅在当前 Swoole 实例的 worker 0 注册 tick 多应用实例仍可能各自调度,V1 必须依靠 job_name + run_key 租约防重
日志 config/log.php 当前为文件日志、非 JSON、按级别拆分、单文件 10MB、最多 30 个文件 中央采集和结构化字段尚未确认,C1 前必须完成采集验证
农业发布文件 当前不存在 config/farm.phpinstall/upgrade/farm_v1/ 和农业 Timer/Job 配置 未创建并通过审计前不得进入 C2

当前 Dockerfile 的 Supervisor 日志每个标准输出/错误文件仅配置 2MB。V1 的日志轮转、集中采集和保留策略必须由部署环境覆盖,不能把 Dockerfile 当前值当作生产容量。

2. 四端前端

项目 锁定工具事实 当前真实构建命令 当前输出契约 结论
smartfarm_admin package-lock.json v3;Node >=18、npm >=8;Vue CLI 3.5.3 npm run build dist/system.htmldist/system/,关闭生产 source map 可由 CI 构建
smartfarm_mer package-lock.json v3;Node >=18、npm >=8;Vue CLI 3.5.3 npm run build dist/mer.htmldist/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.htmldist/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.htmlpublic/mer.htmlpublic/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。

环境隔离最低要求:

  1. 数据库实例或 schema 独立。
  2. Redis DB、Key 前缀和四队列名独立。
  3. 对象存储 bucket/目录独立。
  4. 支付商户号、回调域名和退款证书独立。
  5. 短信、模板消息、地图和物流额度独立或具备环境标识。
  6. H5 域名、小程序版本和 WebSocket 地址独立。
  7. 日志、告警、测试证据和发布制品不得跨环境混写。

五、配置与密钥清单

1. 管理规则

  • Secret 只能来自批准的 Secret Manager、CI Secret 或部署平台密钥注入。
  • 数据库中的敏感系统配置由现有加密/掩码能力管理;后台响应不得返回完整值。
  • Git、Markdown、截图、Figma、构建日志、错误堆栈和测试报告不得出现明文 Secret。
  • release manifest 只记录 secret_id、版本、更新时间、Owner 和联通校验结果。
  • 轮换生产 Secret 时不得自动回退到旧 Secret;回滚应用前先确认旧应用兼容当前 Secret。
  • Swoole 常驻进程使用静态配置时,配置轮换后必须按受控方式重载并验证;具体缓存刷新/重载语义为“实施前核验”。

2. 当前与 V1 配置

类别 配置/Secret 存储位置 Owner 发布验证
应用 APP_KEY 后端环境变量 密钥管理员/后端 各实例一致,不输出到日志
应用 APP_DEBUGINSTALLEDDEFAULT_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.phpconfig/farm.php、环境变量 后端/运维 32、Supervisor 完全一致
自动入账 用户单笔 10000.00、日累计 50000.00、商户结单 100000.00 004_config_seed.sql 初始化,后台受控配置 财务/超级管理员 金额、币种、审计和缓存版本一致
商户结单 02:00 Asia/Shanghai 系统配置 财务/后端 只归集上一自然日
入账租约 默认 300 系统配置 后端/运维 不短于实际事务和故障抢占需要
业务默认值 选择期、自提期、观察期、在途宽限、回购比例、提醒节点、批量上限 config/farm.php 与系统配置 产品/业务 Owner、后端 122232 一致;历史订单读快照
前端 API ENVVUE_APP_BASE_APIVUE_APP_WS_URL 三个 Vue 项目的环境文件/CI 各前端/运维 域名、HTTPS/WSS、跨域和版本环境正确
用户端 API 基址、H5 域名、微信小程序 AppID、版本和合法域名 uni-app 配置/发布平台 用户端/密钥管理员 H5、体验版、正式版分别验证
腾讯地图客户端 现有 tx_map_key 系统配置 地图/平台运营 仅客户端展示,域名/小程序白名单有效
腾讯地图服务端 farm_tencent_map_server_keyfarm_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 失败。


六、发布制品与 Manifest

1. Release manifest 必填字段

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 明文、真实支付报文、用户隐私或数据库备份文件本身。

2. 制品清单

制品 内容 完整性检查
后端制品 应用代码、vendor、配置模板、迁移脚本、版本文件 Git SHA、Composer lock、镜像 digest、PHP 扩展列表
平台端 system.htmlsystem/ 同一构建 ID、文件 hash、资源 200、无 source map/Secret
商户端 mer.htmlmer/ 同上
服务端 ser.htmlser/ 同上;原客服路由回归
用户 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 不允许重新执行一次未留证据的“相同构建”。


七、M01-M12 数据库升级与回退

1. 迁移目录

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 必须以清晰的 M02M11 段落和独立校验查询组织。若最终拆成更多文件,README.md 和 manifest 必须保持 M01-M12 的唯一顺序,不能改变迁移语义。

2. 通用执行规则

  1. 在升级副本和全新空库分别执行完整升级。
  2. 每组执行前记录数据库版本、表前缀、当前结构摘要、脚本 hash 和开始时间。
  3. 每组执行后运行该组校验,保存行数、索引、列类型、唯一键、孤儿引用和 EXPLAIN 证据。
  4. 脚本必须满足“重复执行安全”或“明确检测已完成并停止”之一,禁止重复创建半套结构。
  5. 任一组失败立即停止后续组,不跨过失败继续。
  6. 无法证明某组是否完成时,不猜测重跑;恢复到发布前副本或由 DBA 根据校验事实决定。
  7. 业务事实产生前才允许执行 down;事实产生后只允许前滚修复。
  8. 金额扩容列不自动缩回;账号唯一约束不自动移除;历史快照和审计不回写。
  9. 90 张农业表不建立物理外键,发布校验必须显式执行逻辑引用和孤儿扫描。

3. 分组操作

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,不能影响原菜单 只停用入口;不得通过删菜单清业务事实

4. 中途失败与续跑

DR-006 要求每个 M 组具备以下证据:

  • not_started:前置对象不存在。
  • completed:全部对象和校验均符合当前脚本 hash。
  • partial:只完成部分语句或校验失败,必须停止。
  • conflict:存在非本版本对象、列或索引,必须人工评审。

续跑只允许:

  1. completed 直接跳过;
  2. not_started 从组首执行;
  3. partial/conflict 先恢复或发布修正脚本,再以新 release manifest 执行。

禁止手工补一列后把原组标记成功。任何人工 DDL 都要成为版本化修正脚本。

5. 数据库回退顺序

仅在确认没有业务事实时,按 M12 → M11 → ... → M02 逆序执行 down 和校验;M01 只按备份与审批处理。只要 M05-M11 任一事实表已有真实业务记录,默认回退模式立即切换为:

关闭新入口
→ 保留扩展结构
→ 回退到兼容该结构的应用版本,或前滚修复
→ 保持回调、Outbox、修复和对账
→ 完成五段对账

八、后端与四端构建与发布

1. 后端构建

  1. 校验 Git SHA、工作树、composer.lock hash 和 PHP 扩展。
  2. 使用组织批准的 Composer 生产安装命令从 lock 文件构建。当前仓库没有冻结该命令,具体 --no-dev、autoload 优化和脚本执行参数必须在 PRE 证明后写入流水线,属于“实施前核验”。
  3. 运行静态检查、单元/集成测试、路由/操作码/事件/表集合审计。
  4. install/upgrade/farm_v1、配置模板和 Supervisor 示例纳入同一后端制品。
  5. 构建镜像时固定基础镜像 digest,并证明代码是 COPY 入镜像还是由部署卷提供;当前 Dockerfile 的注释不能作为发布机制。
  6. 记录镜像 digest、PHP/Swoole/Composer 版本和扩展清单。
  7. 在无生产 Secret 的条件下执行镜像启动、自检和只读健康检查。

2. 三个 Vue 端构建

锁文件未变化时使用 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 或经验证的等价执行方式。

3. 用户 uni-app 构建

当前没有可执行的 npm 构建脚本,因此 C1 前必须补齐并签字以下内容:

  1. HBuilderX 精确版本和插件版本。
  2. H5 构建入口、命令或受控 GUI 步骤。
  3. 微信小程序构建入口、命令或受控 GUI 步骤。
  4. H5 和小程序输出目录。
  5. H5 index.html/static 到后端 public/ 的原子发布方式。
  6. 小程序体验版上传、审核、正式发布、版本回退和操作权限。
  7. manifest.json 中 AppID、权限、地图和支付配置的环境替换方式。
  8. 构建日志、制品 hash 和可重复构建证据。

未完成上述核验时,只允许发布后端和三个管理端的兼容版本,不允许开放 V1 用户入口。

4. 前端原子切换

当前后端直接读取固定文件名,发布平台必须提供以下任一种经过 PRE 验证的原子方式:

  • 版本目录 + 原子软链接切换;
  • 同文件系统 staging 目录 + 原子重命名;
  • 具备版本化回源的对象存储/CDN 切换。

不允许先覆盖 HTML、后复制 chunk,或反向操作。切换后保留至少一个上一稳定制品,直到 C6 完成。

5. 推荐部署顺序

  1. 建立 C0 manifest,冻结全部制品。
  2. 完成备份和 verify_before
  3. 执行 M01-M12,并保持所有 V1 入口关闭。
  4. 发布兼容新结构的后端。
  5. 启动/重启 Swoole、四农业队列和 Timer,先验证空扫描及补偿能力。
  6. 发布平台端、商户端、服务端。
  7. 发布用户 H5;小程序先体验版,正式版按灰度门推进。
  8. 运行 verify_after、健康检查、普通商城冒烟和五段对账。
  9. 按灰度阶段逐项开放。

九、四逻辑队列、Supervisor 与 Timer

1. 四队列冻结设计

逻辑队列 任务范围 并发原则 不得被谁阻塞
farm-critical 支付/退款事实修复、用户/商户正式入账、回购、异常执行 低并发、严格锁、最高优先级 通知、报表、大列表
farm-business 活动、供货、批次、分配、履约和一般领域任务 有界并发、按业务键租约 通知渠道
farm-notification 站内信、微信、短信和提醒 可独立扩容、允许渠道退避 核心业务事务
farm-maintenance 对账、缓存/二维码修复、临时附件清理、失败告警 限速、分片;关键告警不得整体暂停 报表和低优先任务

43 中早期的下划线队列名不是当前冻结值;实施以 32 和本表的连字符名称为准。

2. Queue 命令事实

当前锁定的 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

约束:

  1. worker timeout 必须大于该队列最长 Job 的业务超时;farm-maintenance 包含最长 900 秒对账任务。
  2. stopwaitsecs 必须大于 worker timeout,并允许当前事务安全结束。
  3. 框架尝试次数与 eb_farm_job_run 的 5 段业务退避不得叠加成无界重试;最终策略须通过故障注入。
  4. farm-critical 初始低并发,资金/库存业务键必须串行;扩容靠分片,不绕过锁。
  5. 当前默认 mer_q 可以继续承载原 CRMEB 队列,但不得同时消费四农业队列。

3. Supervisor 示例必须具备

每个农业队列一个独立 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 必须进入发布证据。

4. Timer 运行链

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

发布验证:

  1. INSTALLED=true
  2. app/event.php 中每个 32 的农业 Timer Listen 恰好注册一次。
  3. 每个 Listen 只投递,不执行批量业务。
  4. 同一 Swoole 实例只有 worker 0 注册 tick。
  5. 多实例同时触发时只有一个实例取得 job_name + run_key 租约。
  6. 重启后出现新的 eb_farm_job_run 心跳/空扫描证据。
  7. Timer 停机两个周期触发告警。
  8. Timer 恢复后从游标继续,不重置业务结果键。

5. 不可关闭的补偿任务

这里的“不可关闭”是指:即使对应业务入口、特性开关或灰度流量已经关闭,处理既有业务事实的任务仍不得停止。

任务族 为什么必须继续 可暂停边界
支付成功/退款回调适配 外部渠道仍可能重试或迟到 不可因业务入口关闭而停
FarmOutboxDispatch 已提交事实需要至少一次投递 不可停;仅短时受控切换
CloudUnpaidReleaseCloudPaidRepair 释放未支付库存、补齐已付事实 不可停
云仓/农业运费支付修复和退款 迟到款必须原路退款,不能抢回去向 不可停
二次分配释放、退款同步 已有普通订单仍会取消或退款 不可停
FarmFinancialPostingRepair 已进入 processing/retry 的入账必须闭合 不可停;可关闭“新自动入账资格”
CloudReconciliation、供货库存对账 关闭入口后仍需确认无悬挂 不可停
地块/资产预留过期与已付未分配修复 旧预留会占容量,已付订单需履行 不可停
异常已审核步骤、确认超时 已对用户形成承诺 不可整组停;新方案可暂停审核
到期、所有权切割和已审核回购 已存在批次到期事实 不可遗忘;可暂停新的审核执行并转人工
失败任务告警 其他补偿失败需要被发现 不可停

外部营销通知可降级或暂停发送,但通知事实、内部告警和用户可查询状态必须保留。


十、特性开关与灰度

1. 开关分类

下表中的 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 微信/短信等外部通知 站内状态和通知日志保留

开关必须区分“阻止新事实”和“完成旧事实”。不得用一个总开关直接让旧订单、退款、履约和回购失去处理入口。

2. 灰度顺序

阶段 开放内容 允许对象 晋级条件 回退动作
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 证明“后端强制、可审计、不会仅靠前端隐藏”后才能使用。


十一、预发布演练

1. 进入条件

  • 所有制品 hash 已冻结。
  • PRE 拓扑和配置结构与 PROD 等价。
  • M01-M12 在全新库和升级副本通过。
  • 四队列、Timer、Outbox、失败告警和日志采集可观测。
  • 固定 Fixture、测试时钟和角色账号可用。
  • 支付、退款、地图、消息、物流和文件 Stub/沙箱已配置。
  • 恢复点已建立且验证可读。

2. 必演场景

编号 场景 必须观察
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、数据库断言、截图和结论。没有证据的“演练成功”不算通过。


十二、支付、退款、库存与账本五段对账

1. 五段定义

平台页面按已冻结的五组展示:首次订单、库存、二次零售、业务账本、资金入账。支付和退款事实贯穿首次订单及二次零售,不单独制造第六套事实。

核对来源 核心等式/唯一性 差异示例
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、重复入账

2. 运行时点

  • 每日 02:10 Asia/ShanghaiCloudReconciliationJob 分片运行。
  • 每次发布在灰度前运行一次。
  • C6 前至少覆盖一个完整自然日结单/入账周期。
  • 支付、退款、库存或 posting 故障恢复后立即运行受影响范围对账。
  • 数据库恢复和应用回退后必须运行全量五段对账。

3. 差异处理

  1. 区分正常时间差、可重试技术差异和业务恒等式错误。
  2. 正常时间差必须有预计闭合时间和对应 Job,不允许无限挂起。
  3. 金额、库存或所有权硬差异立即冻结受影响对象的新动作。
  4. 使用 CW_RECONCILIATION_PREVIEW 生成不可变差异方案,不改业务事实。
  5. 财务/技术双人审核,确认来源版本未变化。
  6. 使用 CW_RECONCILIATION_EXECUTE 按批准动作和原结果键执行。
  7. 可恢复失败使用同一 operation/result key 重试。
  8. 修复后重跑五段对账和普通商城受影响回归。
  9. 历史账本、库存流水和 posting 不覆盖;通过补记、冲正或补事件恢复。

发布通过线:

  • 支付金额冲突、重复退款、库存恒等式、重复账本、重复 posting 差异为 0。
  • 允许存在的时间差全部有 owner、截止时间和可观测任务。
  • 任何未解释差异均阻断 C5/C6。

十三、监控指标、日志与告警

1. 当前差距

  • 当前应用日志是非 JSON 文件日志。
  • 当前 Supervisor 日志容量很小。
  • 当前没有可确认的 Prometheus/OpenTelemetry/APM 接入。
  • 当前默认队列不保存框架 failed job。
  • 当前没有农业健康检查和业务仪表盘。

以上能力的具体产品、采集 Agent、指标协议和告警平台属于“实施前核验”;Runbook 只冻结必须观测的信号和告警语义。

2. 基础设施指标

指标
HTTP/Swoole 请求量、2xx/4xx/5xx、P50/P95/P99、活跃连接、worker 数、重启数、内存、协程/连接池等待
MySQL 连接、事务、死锁、锁等待、慢 SQL、复制延迟、磁盘、binlog、备份状态
Redis 可用性、延迟、内存、连接、阻塞、淘汰、每队列深度和最老消息年龄
Supervisor 每个 program 的状态、PID、重启次数、异常退出和日志写入
文件/对象存储 上传失败、读取失败、签名失败、容量、备份和孤儿临时附件
第三方 支付/退款、地图、短信/微信、物流成功率、超时、限流和配额
前端 制品版本、JS 错误、资源 404、API 失败、白屏、H5/小程序版本分布

3. 业务可靠性指标

  • 核心已支付但农业仍待付款数量和最老年龄。
  • 已过选择截止仍待选择数量。
  • 运费 paying/late/refund_pending 数量和金额。
  • 供货、活动和批次库存恒等式失败数。
  • 材料已过期仍具新供货资格商品数。
  • 二次订单未分配、观察期已过未生效、退款未冲正数量。
  • 达节点未生成账本数量。
  • 用户/商户待入账超时、失败、冻结数量和金额。
  • posting 租约超时、重复幂等命中、事务回滚和待追偿金额。
  • 到期未完成所有权切割/回购数量和金额。
  • 已付未分配地块/资产、过期预留、已验收未分配产出数量。
  • Outbox pending/retry/final failed、消费失败、Job 积压和通知失败。
  • 每日五段对账各段差异数量和金额。

4. 初始告警线

以下为 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

5. 日志字段

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 日志若不改格式,必须提供可靠解析规则并验证字段完整;否则在开发阶段增加独立结构化农业日志通道。


十四、备份与恢复

1. 保护对象

对象 保护方式 恢复依据
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

2. V1 恢复目标

下列是设计目标,不是当前环境承诺;必须经 PRE 实测后签字:

对象 RPO 目标 RTO 目标 状态
MySQL 交易事实 ≤5 分钟 ≤60 分钟 实施前核验
Redis 农业队列/缓存 不以 Redis 作为唯一事实 ≤30 分钟 重建/恢复消费 实施前核验
后端和三个 Web 制品 0,不可变制品 ≤30 分钟 实施前核验
用户 H5/小程序 H5 0;小程序受平台发布机制限制 H5 ≤30 分钟,小程序另测 实施前核验
对象存储证据 ≤1 小时 ≤4 小时 实施前核验
配置与 Secret 版本 0 ≤30 分钟 实施前核验

3. 备份操作

  1. 确认备份任务健康、上次恢复演练有效。
  2. 在发布前创建专用恢复点,记录 backup ID 和数据库时间。
  3. 记录支付渠道、队列、Outbox 和进行中高风险 operation 的水位。
  4. 导出脱敏结构/配置/菜单摘要和 Secret 版本引用。
  5. 校验备份大小、校验和、可读性和存储位置。
  6. 不在 02:00~03:40 的结单、posting、对账、溯源材料和附件清理密集窗口安排未经压测的重型全量备份。
  7. 备份工具、具体命令、加密、保留周期和跨区域策略由生产平台确定,C2 前必须完成“实施前核验”。

4. 恢复操作

  1. 事故指挥批准恢复目标时间,冻结新交易入口。
  2. 保留支付/退款回调接收证据;若无法正常处理,必须安全落盘/排队,不能丢弃。
  3. 在隔离环境恢复全量备份和目标时间前的 binlog。
  4. 注入隔离 Secret,禁止隔离环境向真实用户、支付、短信和物流发送副作用。
  5. 运行 verify_after、90 表完整性、逻辑孤儿扫描和五段对账。
  6. 对恢复点之后已被外部渠道确认的支付/退款事实建立差异清单,按原业务号补偿。
  7. 发布与恢复库兼容的应用和四队列,先只读验证。
  8. 经 DBA、后端、支付、财务和发布负责人共同批准后切换。
  9. 切换后继续保持新交易关闭,先清 Outbox/关键队列并复跑对账。
  10. 灰度恢复写入,完成普通商城和农业冒烟。

禁止只恢复数据库而让旧应用、旧缓存和新支付回调继续混用。


十五、DR-001~008 恢复演练

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。
  • 正式运行后至少按组织灾备周期重复;具体周期为“实施前核验”。

十六、故障分级、值班与处置

1. 故障等级

等级 定义 响应目标 发布/业务动作
SEV-1 资金/库存错误、重复扣款/入账、数据泄露、不可恢复数据风险、核心全站不可用 5 分钟确认,立即召集事故组 停新相关写入,保持回调/补偿,准备回退或恢复
SEV-2 P0 主流程不可用、关键队列积压、单端大面积不可用、恢复目标受威胁 15 分钟确认 降级或回到上一灰度阶段
SEV-3 有替代路径的局部故障、通知/地图/报表异常 30 分钟确认 启用降级,核心交易可继续
SEV-4 无即时用户影响的告警、容量趋势或低风险缺陷 下一个工作时段 建单跟踪

响应目标需由实际组织和值班能力在 C1 前确认。不能达到目标时应调整承诺,不得在文档中保留虚假 SLA。

2. 值班交接

每次交接至少说明:

  • 当前 release ID 和灰度阶段。
  • 活动、供货、批次、回购和农业生产中的高风险对象。
  • 四队列深度、最老消息、最终失败任务。
  • 未闭合支付/退款/运费、posting 和五段对账差异。
  • 当前特性开关和临时降级。
  • 最近备份/恢复点和可用性。
  • 未关闭事故、负责人和下一检查时间。

3. 通用处置流程

  1. 发现:确认告警真实,关联 release/trace/business ID。
  2. 定级:事故指挥确定 SEV、影响端、对象、金额和数量范围。
  3. 止损:关闭产生新风险的具体入口,不关闭回调和补偿。
  4. 保全证据:记录开关、队列水位、日志、数据库快照和第三方事实。
  5. 诊断:按五段定位首次不一致位置,不从最终余额倒猜。
  6. 预演修复:生成受影响集合、动作、金额/数量和版本。
  7. 审批执行:按原结果键修复;禁止直接 SQL 改最终值。
  8. 验证:重跑对账、P0 冒烟和受影响回归。
  9. 恢复:按灰度顺序恢复,不一次全开。
  10. 复盘:记录根因、时间线、影响、修复、监控缺口和永久行动项。

4. 常见故障止损矩阵

故障 立即动作 必须保留 恢复依据
支付重复/金额冲突 关闭新相关下单,冻结受影响明细 回调接收、渠道查询、支付修复 渠道事实 + 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 兼容
地图/短信/物流故障 启用地址、站内信、人工单号降级 核心订单/履约事实 降级流程可完成

十七、发布回滚

1. 回滚触发

  • C2-C5 任一闸门校验失败。
  • 出现 S0/S1 测试缺陷或 SEV-1 生产事故。
  • 支付金额、交易号、退款或 posting 唯一性失败。
  • 库存/权益恒等式失败且影响继续扩大。
  • M01-M12 出现 partial/conflict
  • 关键队列无法在约定窗口恢复。
  • 新版本破坏普通商城 REG-001~012
  • 前端与 API 不兼容并产生危险写入风险。

2. 回滚模式

模式 适用 动作
R-A 制品回退 Schema 向后兼容,尚无新事实或旧应用能安全忽略 关闭入口,原子回退前端/后端,保留结构
R-B 入口停用 + 前滚修复 已有订单、库存、账本或生产事实 停新事实、保留补偿链、发布修正版本
R-C 数据库恢复 数据库损坏或不可用,且具备完整恢复方案 隔离恢复、补外部渠道事实、整体切换
R-D 单端前端回退 后端保持兼容,某端制品故障 回退该端完整制品,不单独回退 HTML/chunk

3. 标准顺序

  1. 事故指挥宣布暂停,记录触发原因和时间。
  2. 保存当前 release/开关/队列/对账/数据库水位。
  3. 关闭产生新风险的最小入口。
  4. 保持支付/退款回调、Outbox、释放、修复和对账。
  5. 判断有无 V1 业务事实,选择 R-A/B/C/D
  6. 回退前端时确认旧前端与当前 API/Schema 兼容。
  7. 回退后端时确认旧后端会忽略新表、新事件版本和新配置。
  8. 只有“无任何业务事实”且 down 演练通过时才逆序回退 M12-M02。
  9. 运行 verify_after、五段对账和 REG-001~012
  10. 按灰度阶段恢复;原失败 release 不得重新标记成功。

4. 禁止事项

  • 生产交易后执行删表 down。
  • 缩回已扩容的金额列。
  • 删除库存流水、账本、posting、审计或 Outbox 来“消除差异”。
  • 直接改用户/商户余额。
  • 关闭回调后忽略渠道已成功事实。
  • 以清空 Redis 队列替代业务补偿。
  • 回退一个 HTML 文件但保留另一个版本的 chunk。
  • 在未完成五段对账前重新全量开放。

十八、C0-C6 发布闸门

闸门 目标 必需证据 阻断条件 签字角色
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 的条件和审批。


十九、标准发布清单

C0 前

  • 五项目 SHA 和 lock 文件已冻结。
  • P0、REG、PERF、DR、UAT 报告关联本次 SHA。
  • 数据库变更与 M01-M12 映射完成。
  • API 前后兼容和前端原子切换方案完成。
  • 回滚模式、触发阈值和事故指挥确定。

C1

  • 后端镜像 digest 和基础镜像 digest 已记录。
  • 平台/商户/服务端/H5/小程序制品 hash 已记录。
  • 用户 uni-app 构建与回退流程已核验。
  • 四农业队列 Supervisor 实际配置通过 PRE。
  • 配置/Secret Owner、版本和连通性通过。
  • 日志、指标、告警和值班可达性通过。

C2-C3

  • 发布前恢复点已建立并校验。
  • verify_before.sql 和 M01 通过。
  • M02-M12 按顺序执行,无 partial/conflict。
  • verify_after.sql、90 表、索引、逻辑引用、菜单和配置通过。
  • 所有 V1 入口仍关闭。

C4

  • 后端版本/镜像正确。
  • Swoole 仅运行预期实例。
  • 四逻辑队列各自消费,无重复消费者。
  • Timer 每项恰好注册一次且有租约证据。
  • 平台、商户、服务、用户 H5 制品版本一致。
  • 小程序体验版通过。
  • REG-001~012 和最小农业只读冒烟通过。

C5

  • 按 G1-G6 逐阶段开放,不跳级。
  • 支付、重复回调、退款、库存和 posting 无硬差异。
  • 云仓单一去向、二次销售和结算模式符合快照。
  • 租地/认养只邮寄,权益与履约闭合。
  • 五段对账为 0 硬差异。
  • 无 SEV-1/2,队列积压在目标线内。

C6

  • 至少完成一个 02:00-03:30 日任务周期。
  • 商户结单、posting、五段对账、材料/附件任务正常。
  • 首日监控、日志、告警和业务反馈已复核。
  • 最终开关快照、证据和 manifest 已归档。
  • 上一稳定制品和恢复点保留到观察期结束。
  • 未决问题已分配 Owner、优先级和截止时间。

二十、日常运维

1. 每班检查

  • 四队列状态、最老消息、最终失败和租约超时。
  • Timer 最近一次运行、扫描数、成功/失败和下一次计划。
  • 支付/退款/运费待修复数量和金额。
  • Outbox 和事件消费差异。
  • 库存/权益恒等式告警。
  • posting、冻结、待追偿和回购。
  • 备份、binlog、对象存储和磁盘。
  • API、数据库、Redis、第三方成功率。

2. 每日检查

  1. 02:00 商户结单。
  2. 02:05 商户 posting 及后续补偿。
  3. 02:10 五段对账。
  4. 03:10 溯源材料到期。
  5. 03:30 未绑定临时附件清理。
  6. 核对任务是否按 Asia/Shanghai 归属正确业务日。
  7. 对所有非零差异建立异常或修复 operation。

3. 每次配置变更

  • 使用独立变更单和 request_id
  • 记录 before/after、原因、Owner 和影响对象。
  • 高风险阈值、回购、自动入账和权限范围双人复核。
  • 验证 Swoole/worker 是否需要重载。
  • 变更后执行最小冒烟和相关对账。
  • Secret 值不进入审计正文,只记录 Secret 版本。

4. 人工重放

  • 先读取事实、版本和原结果键。
  • 生成预演,显示预计影响数量、金额、事件和对象。
  • 审核后使用原 event/job/posting/result key。
  • 重放操作写 eb_farm_audit_log
  • 重放后检查主事实、流水、Outbox、消费日志和最终投影。
  • 不提供“忽略幂等重新生成”按钮。

二十一、实施前核验总表

以下事项全部完成前,本文不能从“设计基线”提升为“可执行生产 Runbook”:

  1. 后端生产 Composer 命令和构建 Runner。
  2. Docker 基础镜像 digest、代码注入和 /entrypoint.sh 行为。
  3. config/farm.php、农业环境变量和动态开关刷新方式。
  4. M01-M12 实际 SQL、down、before/after 和脚本 hash。
  5. 四队列 Supervisor 完整命令、进程数、超时、尝试次数和日志。
  6. Swoole 内置队列与独立 worker 不重复消费的证明。
  7. 农业 Timer 全注册、分布式租约和故障恢复。
  8. 用户 uni-app H5/微信小程序可重复构建、上传和回退。
  9. 前端原子发布/CDN 缓存策略。
  10. 生产 DB/Redis/Swoole/Node/npm/Composer/Supervisor/HBuilderX 精确版本。
  11. Secret Manager、密钥轮换和常驻进程重载。
  12. 日志集中采集、结构化字段、指标、告警和值班平台。
  13. 数据库/对象存储备份工具、加密、保留和跨域策略。
  14. RPO/RTO 的 PRE 实测结果。
  15. 支付/退款渠道真实小额闭环。
  16. 灰度 allowlist 的后端强制和审计。
  17. DR-001~008 全部证据。
  18. C0-C6 的真实签字人和事故联系人。

二十二、关联文档

Clone this wiki locally