20 KiB
FT546 调度中心影子先行安全接入设计
状态:已确认 确认日期:2026-08-12 实施分支:
optimize/wcs现场原则:稳定版本始终是唯一生产调度者和唯一 PLC 写入者,直到受控切换完成
1. 背景与决策
javaTest 中心调度已经覆盖父任务阶段、选车、路径规划、交通资源、换层、二段式任务、避让、故障注入和历史回放。ruoyi-wcs 与 FT546 Admin 已完成一部分标准内核、PLC 编码、Outbox、运行模式和内存端到端测试,但生产适配器、现场事实对账和运行模式隔离仍不完整。
本设计采用“影子先行”路线:
- 现场稳定版本不改动、不停机,继续独占现场任务、业务表、WMS 回调和 PLC 写入。
- 先运行独立
javaTest离线影子,建立确定性算法基线。 - 再实现与生产控制进程隔离的实时只读采集与同核影子计算。
- 先根据现场差异证据决定算法和适配器修改,不预设新算法一定优于旧算法。
- 通过 SQL Server 集成、现场影子和 HIL 门禁后,才允许在维护窗口内由
LEGACY受控切换到STANDARD。
截至确认日,不能直接把 ruoyi-admin --ft546.wcs.runtime-mode=SHADOW 部署为现场影子。当前实现没有为 SHADOW 装配标准核心,却仍会在 ScheduleThread.@PostConstruct 中查询设备、构造 PLC reader、注册设备运行时并构造旧业务线程;无权限保护的线程操作接口还可以手动启动 PLC reader 和旧调度线程。模式名称本身不构成安全隔离。
2. 目标与非目标
2.1 目标
- 将
javaTest已验证的调度语义逐步接入ruoyi-wcs,不破坏 FT546 现有业务。 - 保持
LEGACY为默认模式和可验证回退路径。 - 使
SHADOW与未来STANDARD复用同一调度核心,只在出站能力和状态所有权上不同。 - 在影子阶段强制实现零 PLC 写入、零 WMS 回调、零生产业务表写入和零旧业务调度线程。
- 对旧队列字段和 PLC 地址、数据类型、值、顺序形成可审计差异报告。
- 完整表达父任务阶段、同车绑定、换层、二段下发、避让、业务完成、车辆释放、Outbox 和重启恢复。
- 在缺少真实 PLC 或隔离 SQL Server 时明确证据边界,不把内存测试或历史回放声明为可投产证明。
2.2 非目标
- 不在影子采集前主动修改调度规则来追求结果一致。
- 不在现场稳定分支上开发、试验或合并未验收代码。
- 不修改 FT546 PLC 控制流程、安全联锁和既有寄存器语义。
- 不做
LEGACY与STANDARD并行 PLC 双写。 - 不做运行中热切换或遇错自动切回。
- 不用历史
agv_id、path_info、完成状态或finish_date强制新调度作出相同选择。
3. 方案比较
3.1 采用:同核只读影子后受控接管
未来 SHADOW 与 STANDARD 使用同一个任务、调度、交通和恢复核心。SHADOW 只消费不可变现场事实并生成虚拟命令;STANDARD 在就绪、恢复和单写者门禁全部通过后才装配真实出站适配器。
优点是算法差异可以在无现场控制权的条件下观察,切换前能证明协议和值的一致性,切换后也没有第二套调度语义。代价是必须先完成持久化、只读采集、差异报告和运行模式硬隔离。
3.2 不采用:直接启用当前 STANDARD
当前 STANDARD 绑定的多个 Repository、Gateway、Snapshot 和 Recovery 端口尚无生产实现,不能证明应用可启动、SQL Server 事务可恢复或真实 PLC 语义可靠。直接启用可能造成启动失败、首单失败或发送后结果不明。
3.3 不采用:把旧队列线程包装成新调度中心
这种做法会保留旧线程和新内核对任务、车辆、资源和完成事实的双重所有权,无法证明唯一调度者,也无法解决阶段语义、Outbox、UNKNOWN 和重启恢复问题。
4. 运行模式与单写者边界
| 模式 | 调度所有者 | 现场事实来源 | 核心状态写入 | PLC/WMS 写入 | 用途 |
|---|---|---|---|---|---|
LEGACY |
旧线程 | 现有 PLC reader 与业务表 | 旧表 | 允许,唯一写者 | 当前生产和回退 |
SHADOW |
标准核心,仅计算 | 离线快照或只读采集 | 独立影子库/Schema | 禁止 | 差异采集与准入 |
STANDARD |
标准核心 | 标准快照采集器 | WCS 核心表 | 通过 Outbox 允许 | 最终受控接管 |
强制规则:
- 默认值保持
LEGACY。 SHADOW不创建真实DeviceCommandGateway、WmsNotificationGateway、旧业务调度线程或 PLC reader。SHADOW的禁止写入必须同时由 Bean 装配、数据库权限、网络 ACL 和自动化测试保证。STANDARD缺少任何必需端口、端点、能力证据或恢复条件时必须启动失败或保持未激活,不能降级为“首单运行时失败”。LEGACY与STANDARD不能同时拥有有效调度租约或有效 PLC 写通道。- 切换采用配置变更加进程重启,不支持运行中热切换。
5. 现场稳定版本保护
5.1 代码与制品
- 开发只在
optimize/wcsworktree 进行,不修改、合并或推送到现场稳定分支。 - 设计确认时,本地远端跟踪引用
origin/main为提交652607c。现场回退必须锁定实际已部署制品、提交号、配置和校验和;不能只依赖可能移动或过期的分支名称。 - 本地
main与origin/main已分叉,不能把本地main当作现场回退来源。 - 数据库迁移只允许新增表、列、索引和约束,不删除、不重命名现场旧对象。
5.2 进程、网络与数据库
- 实时影子使用独立进程、服务端口、日志目录和部署目录,优先部署在独立主机。
- 影子数据库账号只允许读取批准的现场事实视图;禁止写现场订单、队列、设备、资源、Outbox 和回调表。
- 影子结果写入独立数据库或独立 Schema,不能与生产核心表共用写权限。
- 网络 ACL 禁止影子主机访问 PLC 写端口和生产 WMS 回调地址。
- 影子查询使用独立连接池、短超时、限速和熔断;积压或超时时停止影子计算,不持续压迫生产数据库。
- 影子进程的崩溃、阻塞、快照过期或输出磁盘故障不能反向暂停或修改现场稳定程序。
5.3 当前可运行边界
独立 javaTest 可以立即运行。它只读取打包的历史与地图资源,使用内存车辆、队列、PLC、WMS 和资源账本,不启动 Spring、不连接 SQL Server/PLC/WMS,只写命令参数指定的本地输出目录。
当前 ruoyi-admin 的 SHADOW 不允许直接运行现场影子,必须先完成以下整改:
ScheduleThread按模式装配,SHADOW不执行plcReadInit()和scheduleInit()。ThreadOperationController在SHADOW禁止启动 PLC reader 和旧调度;接口恢复权限校验并按模式返回明确状态。- 建立专用
Ft546ShadowConfiguration,只装配只读快照源、同核调度、记录型命令网关和差异仓储。 - 影子启动自检必须证明无 PLC/WMS 真实 Bean、无生产写权限和无旧调度线程。
6. 父任务与阶段模型
一个业务请求只创建一个父任务,阶段不会重新进入全局业务队列,也不会重新创建 WMS 任务:
WAITING_ASSIGNMENT
-> 可选 FLOOR_TRANSFER_TO_PICKUP
-> EMPTY_TO_PICKUP
-> PICKUP_CONFIRMED
-> 可选 LOADED_RETURN_TO_SOURCE_FRONT
-> LOADED_TO_PLACE
-> CARGO_DEPOSITED / BUSINESS_COMPLETED
-> 可选 EMPTY_RETURN_TO_TARGET_FRONT
-> VEHICLE_RELEASED
规则:
task_type表示执行阶段,业务类型取default02;入库、出库、移库分别为1/2/7。- 取货确认后载货状态由
EMPTY变为LOADED,车辆与父任务锁定;普通等待、断线和重启不能自动换车。 - 到放货点并取得可靠完成事实后记录
CARGO_DEPOSITED,只归档一次并只产生一次 WMS 业务效果。 - 车辆可能在业务完成后继续空车返回目标通道前端,车辆释放时间与业务完成时间分别记录。
- 每个阶段从设备确认的实际位置重新规划,不复用历史路径或上一阶段估算位置。
- 命令身份至少包含
parentTaskId + phase + routeVersion + commandSegment;旧 ACK 不能推进新阶段。 - 不需要的阶段必须记录明确跳过原因,不能无痕跳过。
7. 选车、路径与避让
- 车辆硬过滤包含在线、自动、健康、已同步、空闲、电量、载货、能力和可达性。
- 同层和跨层可行车辆进入同一稳定选车策略;历史车辆只用于对比。
- 候选路径限制在最短物理距离的
110%内,最多 32 条,按对向风险、占用节点、不兼容预约、活动路线重叠、转弯、距离和站点序列作确定性字典序比较。 - 临时交通冲突只进入
HOLD,不能误判为NO_ROUTE。 - 同一任务、车辆、阻塞资源和原因连续三次交通
HOLD后,才允许从实际位置重规划尚未承诺的剩余路线。 - 已发送、已接受或结果为
UNKNOWN的动作不能被新路线覆盖。 - 路线预约必须原子替换;失败时完整保留旧路线和旧预约。
- 只有拓扑中存在经过验证的安全让行点,才创建
CLEARANCE运行步骤;不能临时选择任意空点。 - 避让不创建新 WMS 业务任务,不重复归档或回调。
8. 换层编排
提升机不是普通地图边。跨层任务使用幂等换层子作业,并联合保护源入口、提升机本体和目标出口:
预约源入口 + 提升机 + 目标出口
-> 创建幂等换层子作业并锁车
-> 等待旧提升机协议执行事实
-> 核对车辆、楼层、门、端口和实际出口
-> 从实际出口重新规划当前业务阶段
- 任一资源预约失败时保持
BLOCKED,不发送进入提升机动作。 - 作业提交后断线、故障或重启不释放车辆锁,不创建第二个换层作业。
- 完成事实必须包含匹配车辆、目标层和实际出口;重复完成只推进一次。
- 目标出口占用时保持换层完成待提交状态,不能让车辆出现在已占节点。
- 事实不确定时进入恢复工单,隔离车辆、提升机和相关端口,不盲目释放。
9. FT546 旧 PLC 与二段任务
标准核心生成强类型命令意图,FT546 Adapter 负责映射旧寄存器。核心不伪装旧 PLC 不具备的候选缓冲、Prepare/Commit、命令幂等或有序快照能力。
必须保持并逐项回归的写入序列:
普通主任务:4004 -> 4000 -> 4002 -> 4021
跨层任务: 普通主任务序列 + 4020=1 -> 4022=8
二段第一段:4404 -> 4422=1 -> 4402=1 -> 4400
二段第二段:4404 -> 4422=2 -> 4423=99 -> 4402=9 -> 4400
对每次虚拟或真实协议发送,证据至少包含:
deviceId
parentTaskId
phase
commandKey
routeVersion
taskNo
taskType
pathPoints
registerAddress
dataType
values
writeSequence
triggerValue
相同车辆、路径、阶段和任务输入下,队列字段、寄存器地址、数据类型、值和顺序必须与旧实现逐项一致。新算法可以选择不同车辆或安全路径,但差异必须归类为算法决策差异,不能混入协议不一致。
旧 PLC 不识别 commandKey。发送前能证明未发送的失败可以重试;任何写入开始后无法证明结果的命令进入 UNKNOWN,保护完整点到点或二段任务路径,不补写单个寄存器、不自动重发。
10. 设备事实、Outbox 与恢复
每个标准调度 tick 的因果顺序为:
采集不可变设备事实
-> 校验新鲜度和恢复门禁
-> 加载候选任务、资源和活动命令
-> 生成调度授权或 HOLD
-> 同事务持久化绑定、预约、DeviceCommand 和 CommandOutbox
-> 出站分发
-> 使用新设备事实推进步骤、订单和资源
-> 独立分发 WMS NotificationOutbox
send成功只表示通信层受理,不表示物理完成。- 订单、步骤、设备命令、设备事实和资源预约保持独立状态。
- 设备事实必须校验设备、任务号、阶段、预期端点、载货变化、模式和时间新鲜度。
- 重复、乱序、倒退、旧阶段或不能关联当前命令的事实只记录审计,不推进状态。
UNKNOWN保留车辆和未确认资源,只允许继续只读采集、诊断和受控恢复。- WMS 回调失败不回滚物理任务,只重试通知 Outbox。
- 核心 tick 失败时不创建新设备动作;已存在的 WMS 通知 Outbox 可以独立投递。
- 重启时先取得租约并保持全局调度暂停,加载活动状态、采集设备快照、完成对账,再局部启用安全设备。
11. 影子数据与差异报告
11.1 数据来源顺序
- 已打包的历史队列、地图和通道前端快照,用于可重复离线基线。
- 现场稳定程序已经落库的只读事实,用于实时影子比较。
- 经过审批的原始报文副本,用于协议和故障审计。
影子不直接增加 PLC 连接。实时事实缺失、过期或互相矛盾时,本轮结果标记为 INSUFFICIENT_FACTS,不产生误导性可比结论。
11.2 比较维度
协议一致性:
- 队列业务字段、默认字段和阶段字段;
- PLC 地址、数据类型、值、顺序和触发值;
- 换层、二段任务和旧任务号编码;
- 完成、归档和回调的幂等键。
调度合理性:
- 任务到达与父任务归并;
- 车辆资格、选车和同车绑定;
- 每阶段路径、候选质量和资源保护;
- 换层入口/出口、二段、HOLD、避让和重规划;
- 业务完成与车辆释放。
每个差异必须保存相同输入快照、旧结果、新结果、差异类别和可解释原因。协议差异与算法差异分别统计。
11.3 已建立的离线基线
2026-08-12 在提交 f66585f 上执行:
javaTest tests: 549
failures/errors/skipped: 0/0/0
raw snapshots / unique GUID / duplicates: 240 / 98 / 142
business tasks / operational queues: 76 / 17
completed / waiting / failed: 76 / 0 / 0
incomplete vehicle releases: 0
total safety violations / deadlocks: 0 / 0
archive count / WMS effects / duplicate effects: 76 / 76 / 0
本地证据目录:javaTest/outputs/wcs-history-business-shadow-20260812-f66585f/。六个报告文件的 manifest.sha256 校验结果为零不匹配。该目录是开发机生成证据,不随本设计文档提交。
报告明确标注:这是“真实历史负载驱动纯内存仿真”,不是现场 SHADOW、HIL 或 ACTIVE 验收。
12. 故障隔离
| 故障 | 处理 | 禁止行为 |
|---|---|---|
| 影子快照缺失/过期 | 标记 INSUFFICIENT_FACTS,暂停该对象计算 |
猜测设备状态 |
| 影子数据库超时 | 熔断、退避并记录采集缺口 | 加速重试压迫生产库 |
| 命令发送结果不明 | UNKNOWN、隔离设备和资源 |
自动重发或释放 |
| 换层事实不一致 | 隔离车辆、提升机和端口,创建 RecoveryCase | 重建换层任务 |
| 二段任务部分写入不明 | 保护整个二段任务范围 | 补写单寄存器 |
| WMS 回调失败 | 重试通知 Outbox | 回滚物理完成 |
| 影子进程崩溃 | 只影响影子报告 | 影响现场调度或告警处置 |
| 输出磁盘满 | 停止新影子计算并告警 | 丢弃差异后继续宣称健康 |
13. STANDARD 切换与回退
现场不做热切换。维护窗口内按以下顺序交接:
LEGACY 正常运行
-> STANDARD 以控制关闭方式启动并完成恢复对账
-> 暂停新任务进入
-> 等待或人工核对活动命令
-> 停止 LEGACY 调度写入
-> 获取数据库租约和 fencing token
-> 再次验证旧写者失效
-> 开放 STANDARD 真实出站网关
-> 恢复新任务进入
回退规则:
STANDARD取得写入权之前失败时,LEGACY不停止。STANDARD取得写入权之后失败时,先禁止新命令并对账所有活动命令。- 存在
UNKNOWN时禁止自动切回LEGACY,必须先完成现场对账,避免重复动作。 - 确认无未决物理动作后,释放
STANDARD租约,恢复锁定的稳定制品和LEGACY配置。 - 回退不回滚新增数据库结构,只停止使用;避免数据库降级造成更大不可用。
- 切换和回退演练必须记录制品校验和、配置快照、操作者、时间、活动任务清单和对账证据。
14. 测试与准入门禁
14.1 自动化分层
- 领域测试:父任务阶段、同车绑定、业务完成与车辆释放、换层、避让、HOLD、资源容量和死锁。
- 协议测试:队列字段、寄存器地址、数据类型、值和顺序逐项对比。
- 故障测试:重复/旧/乱序 ACK、断线、超时、部分写入、重启、乱序快照、Outbox 和
UNKNOWN。 - 模式隔离测试:
SHADOW上下文无 PLC/WMS 真实 Bean、无生产写入、无旧调度线程,线程操作接口 fail-closed。 - SQL Server 集成测试:事务、唯一键、乐观锁、资源并发、Outbox、租约、fencing token 和重启持久性。
- 模拟端到端:入库、出库、移库、同层、跨层、二段、通道前端返回和共享资源避让。
- 历史回放:240 条原始记录归并、76 个父任务全阶段和所有不变量。
- 实时影子:旧队列与新虚拟队列的连续差异采集,且副作用为零。
- HIL:隔离 PLC 或测试设备上的寄存器时序、断线、重启和部分写入。
- 切换演练:单写者交接、启动失败不影响 LEGACY、对账后回退。
14.2 STANDARD 硬门槛
- 安全不变量违规数为 0。
- 现场表写入、PLC 写入和 WMS 回调等影子副作用为 0。
- 可比较场景的队列业务字段、PLC 地址、数据类型、值和顺序不一致数为 0。
- 所有算法差异都有输入、旧结果、新结果和决策原因;未经审核的差异数为 0。
- 所有生产 Adapter、Repository、端点、拓扑、能力证据和恢复门禁均就绪。
- SQL Server 集成、现场影子和 HIL 任一缺失时,只能声明本地实现或相应层级验收完成,不能声明可投产。
15. 实施顺序
阶段 A:离线影子基线
- 保持现场稳定程序不变。
- 固化
javaTest输入清单、测试结果、报告和校验和。 - 建立队列/PLC 协议字段差异格式。
阶段 B:实时只读影子硬隔离
- 修复
SHADOW条件装配和线程启动边界。 - 增加只读现场事实 Adapter、记录型命令网关和独立差异仓储。
- 增加启动自检、数据库权限验证和网络不可达证明。
- 现场旁路运行并采集差异,不修改调度算法。
阶段 C:按证据补齐同核语义和 FT546 Adapter
- 根据差异逐项补齐父任务阶段、换层、二段、避让、设备事实、Outbox 和恢复。
- 每次修改都用同一采样重新计算,区分协议回归与允许的算法差异。
- 完成生产 MyBatis Repository 和 SQL Server 集成验证。
阶段 D:HIL 和受控切换
- 在隔离 PLC/测试设备验证真实协议。
- 完成维护窗口切换和回退演练。
- 只有全部硬门槛通过后才允许切换现场写入权。
16. 完成定义
本接入只有在以下事实同时成立时才算完成:
SHADOW与STANDARD使用同一核心,SHADOW没有权威写通道。- 现场稳定版本在影子阶段保持唯一生产调度者和 PLC 写入者。
- 父任务、换层、二段、避让、Outbox、事实对账和恢复均有生产实现及自动化证据。
- 队列业务字段和 PLC 地址、类型、值、顺序与旧逻辑的协议差异为零。
- 所有允许的车辆或路径差异均可解释、已审核且不违反安全不变量。
- SQL Server、实时影子、HIL、单写者切换和回退演练证据齐全。
LEGACY稳定制品、配置和对账式回退流程仍可执行。