192 lines
8.1 KiB
Markdown
192 lines
8.1 KiB
Markdown
# FT546WMS 影子 v3 现场操作手册
|
||
|
||
## 1. 这次部署做什么
|
||
|
||
目标分支:`test/ft546wms-shadow-v3-20260903`。
|
||
|
||
影子 v3 只观察算法建议,不改变 Legacy 分配结果。入库、自动出库、手动出库仍由原存储过程执行一次,原返回码、返回消息、库位和异常保持不变。正常业务请求只做固定大小的内存登记,不等待影子线程,也不在调用线程执行影子数据库、文件或同步日志操作。
|
||
|
||
影子后台会读取业务表,并且只写 `alg.*` 对象。它可能增加数据库 CPU 和 I/O,因此仍需低峰部署、监控和随时回滚。
|
||
|
||
## 2. 固定安全边界
|
||
|
||
- 现场只允许一个 FT546WMS JVM,稳定版和影子版不能同时运行。
|
||
- 仓库固定为 `01`;原始数据中的 `1` 与 `01` 等价,`W02` 只用于诊断,不能覆盖配置。
|
||
- SQL Server 必须使用 Windows 集成认证;脚本不接收用户名和密码。
|
||
- 当前现场已有 v2 包,安装必须使用 `upgrade`,不能使用 `clean`。
|
||
- v2 到 v3 升级保留 `alg.decision_log`;发现未知 `alg` 对象、清单不完整或 manifest 不匹配时脚本会停止。
|
||
- 影子失败、过期、并发、超时、配置错误或输入缺失均 fail-open:Legacy 继续,影子样本作废。
|
||
- 不执行正式 ACTIVE 切换,不增加 WCS/PDA/理库/预留/回放功能。
|
||
|
||
## 3. 部署前准备
|
||
|
||
现场负责人先记录:
|
||
|
||
- SQL Server 名称和数据库名;
|
||
- 当前 v2 测试开始时间和时区;
|
||
- IDEA 当前 Run Configuration;
|
||
- 当前稳定实例 PID 和端口;
|
||
- 本次交付给出的精确 v3 提交号 `<V3_COMMIT>`;
|
||
- 应用日志目录。
|
||
|
||
部署前先导出现有 v2 证据。不要卸载 v2:
|
||
|
||
```cmd
|
||
cd /d C:\project\FT546WMS-SHANDOW
|
||
call scripts\shadow-v3-export.cmd C:\project\FT546WMS-SHANDOW "<SQL_SERVER>" "<DATABASE>" "<V2_START_UTC>" "C:\project\FT546WMS-v2-before-v3" "<LOG_DIR>"
|
||
```
|
||
|
||
如果当前代码还没有 v3 导出脚本,先用既有导出方式保存 `alg.decision_log`、诊断结果、日志、分支和提交号,再继续。
|
||
|
||
## 4. 按顺序部署 v3
|
||
|
||
### 第一步:停止 IDEA 中的 v2 稳定实例
|
||
|
||
记录停止时间,在 IDEA 点 Stop。用下面命令确认最多只有一个相关 JVM,最好为 0:
|
||
|
||
```cmd
|
||
jps -lv | findstr /I "RuoYiApplication FT546WMS"
|
||
```
|
||
|
||
停止和重新启动之间会有一次短暂停机,这是计划内中断。不要同时启动两个实例来消除停机,否则可能重复执行定时任务、消费或外部回调。
|
||
|
||
### 第二步:同步精确分支和提交
|
||
|
||
```cmd
|
||
cd /d C:\project\FT546WMS-SHANDOW
|
||
git fetch origin
|
||
git switch test/ft546wms-shadow-v3-20260903
|
||
git pull --ff-only
|
||
git rev-parse HEAD
|
||
git status --porcelain
|
||
```
|
||
|
||
`git rev-parse HEAD` 必须等于交付的 `<V3_COMMIT>`,`git status --porcelain` 必须没有输出。若不一致,停止部署。
|
||
|
||
### 第三步:执行只读预检
|
||
|
||
```cmd
|
||
call scripts\shadow-v3-preflight.cmd C:\project\FT546WMS-SHANDOW <V3_COMMIT> "<SQL_SERVER>" "<DATABASE>"
|
||
```
|
||
|
||
只有看到 `PREFLIGHT_OK` 才能继续。预检检查分支、精确提交、干净工作树、main 祖先、JVM 数量、SQL 连接、v2/v3 manifest 和当前快照;它不修改数据库。
|
||
|
||
### 第四步:升级数据库包
|
||
|
||
当前现场是 v2,只执行:
|
||
|
||
```cmd
|
||
call scripts\shadow-v3-install.cmd "<SQL_SERVER>" "<DATABASE>" upgrade
|
||
```
|
||
|
||
只有全新测试数据库、确认没有 `alg` schema 时才允许使用 `clean`。现场生产库不要使用 `clean`。
|
||
|
||
### 第五步:设置 IDEA 环境变量
|
||
|
||
在影子 Run Configuration 中使用:
|
||
|
||
```text
|
||
FORTUCKY_SHADOW_ENABLED=true
|
||
FORTUCKY_ALGORITHM_MODE=SHADOW
|
||
FORTUCKY_ALGORITHM_DATABASE_WRITES_ENABLED=true
|
||
FORTUCKY_ALGORITHM_WAREHOUSE_ID=01
|
||
FORTUCKY_SHADOW_TIMEOUT_SECONDS=3
|
||
FORTUCKY_SHADOW_SNAPSHOT_MAX_AGE_SECONDS=60
|
||
FORTUCKY_SHADOW_QUIET_INTERVAL_MILLIS=1000
|
||
```
|
||
|
||
不要设置 `ACTIVE`,不要添加数据库密码,不要设置 replay、tidy、reservation 或 WCS callback 开关。
|
||
|
||
### 第六步:只启动一次影子实例
|
||
|
||
在 IDEA 启动 v3。不要重复点击 Run。启动时后台会认领唯一实例并建立第一代快照;认领或刷新失败只会关闭影子可用性,不应阻止 Legacy 启动。
|
||
|
||
启动后检查:
|
||
|
||
```cmd
|
||
jps -lv | findstr /I "RuoYiApplication FT546WMS"
|
||
```
|
||
|
||
只能看到一个 FT546WMS JVM。
|
||
|
||
### 第七步:做只读和受控业务检查
|
||
|
||
先完成登录、页面查询等只读检查,再由现场人员执行一笔受控入库、一笔自动出库和一笔手动出库。确认:
|
||
|
||
- Legacy 返回码、消息、库位和设备动作与稳定流程一致;
|
||
- 没有相同存储过程重复执行;
|
||
- `alg.shadow_snapshot_state` 为仓库 `01` 的 `PUBLISHED`;
|
||
- `alg.shadow_instance_heartbeat` 只有当前实例;
|
||
- `alg.decision_log` 出现新的计划/比较记录;
|
||
- 应用日志中的影子 warning 不包含业务载荷或异常消息。
|
||
|
||
## 5. 立即停止条件
|
||
|
||
出现任一情况立即执行第 7 节回滚:
|
||
|
||
- Legacy 结果、响应码、消息、库位或设备动作改变;
|
||
- 同一个 Legacy 存储过程疑似执行两次;
|
||
- 出现第二个 FT546WMS JVM;
|
||
- `alg` 之外出现本次部署造成的数据写入或新对象;
|
||
- WMS、WCS、PDA 或现场作业异常;
|
||
- 正常接口延迟或数据库 CPU、I/O、锁等待超过现场阈值;
|
||
- 快照长时间不是 `PUBLISHED`,或 `ERROR_*` 指标持续增长。
|
||
|
||
单条 `shadow_failure` 表示该影子样本失败开放,不等于 Legacy 失败;但必须记录时间并纳入分析。
|
||
|
||
## 6. 连续观察和七天导出
|
||
|
||
至少连续观察 7 天,覆盖正常业务高峰、入库、自动出库和手动出库。期间不要重放业务来补影子样本。
|
||
|
||
观察结束后运行:
|
||
|
||
```cmd
|
||
cd /d C:\project\FT546WMS-SHANDOW
|
||
call scripts\shadow-v3-export.cmd C:\project\FT546WMS-SHANDOW "<SQL_SERVER>" "<DATABASE>" "<V3_START_UTC>" "C:\project\FT546WMS-shadow-v3-export" "<LOG_DIR>"
|
||
```
|
||
|
||
成功时显示 `EXPORT_OK`。输出目录包含:
|
||
|
||
- `deployment.txt`:分支、提交、工作树;
|
||
- `runtime-processes.txt`:JVM 进程;
|
||
- `environment-variable-names.txt`:仅环境变量名,不含值;
|
||
- `sql-diagnostics.txt`:manifest、快照、心跳、输入覆盖、阻塞;
|
||
- `comparison-detail.txt`:比较汇总和完整决策行;
|
||
- `runtime-metrics.txt`:准入、跳过、错误和时延桶;
|
||
- `inventory-parity.txt`:Legacy 与已发布快照库存差异计数;
|
||
- `shadow-warnings.txt`:日志目录中的结构化影子 warning。
|
||
|
||
把整个输出目录压缩后交给分析,不要包含密码、令牌或与测试无关的个人信息。只有七天数据通过分析后,才讨论正式切换;本分支本身不执行 ACTIVE 切换。
|
||
|
||
## 7. 回滚
|
||
|
||
首选回滚只关闭影子,不卸载数据库对象:
|
||
|
||
1. 在 IDEA 停止 v3,记录停止时间;
|
||
2. 设置 `FORTUCKY_SHADOW_ENABLED=false`;
|
||
3. 完整重启一次;
|
||
4. 检查只有一个 JVM;
|
||
5. 做登录、查询、受控入库和出库冒烟检查。
|
||
|
||
更彻底的应用回滚是停止 v3,切回现场原稳定源码/提交并用原 Run Configuration 启动。无论哪种方式,都先恢复业务服务,再处理数据库对象。
|
||
|
||
`alg.*` 可以保留供取证,稳定 Legacy 不依赖它。不要把卸载当作紧急回滚步骤。
|
||
|
||
## 8. 可选卸载
|
||
|
||
只有满足全部条件才卸载:影子实例已停止、稳定服务已恢复、七天证据已导出并备份、DBA 已确认维护窗口。
|
||
|
||
```cmd
|
||
call scripts\shadow-v3-uninstall.cmd "<SQL_SERVER>" "<DATABASE>" CONFIRM_UNINSTALL
|
||
```
|
||
|
||
卸载器只接受精确口令 `CONFIRM_UNINSTALL`,并由 SQL 包再次校验 v3 manifest 和完整对象白名单。发现未知/缺失对象时会在删除前停止。不要修改 manifest 或脚本绕过保护。
|
||
|
||
## 9. 自动化验证与残余风险
|
||
|
||
- 本地单元/静态测试不能替代 SQL Server 2016 备份副本演练。
|
||
- `READ UNCOMMITTED` 只用于观察,可能看到业务事务中间状态。
|
||
- 单线程容量一队列限制影子后台并发,但不能消除数据库资源竞争。
|
||
- 3 秒 worker 等待超时不等于 JDBC/SQL Server 一定在 3 秒内完成取消或回滚。
|
||
- 影子调用线程不等待后台,但主机和数据库资源竞争仍可能间接影响 Legacy,需要现场监控。
|