4.5 KiB
4.5 KiB
任务完成与取消双通道回调设计
目标
任务模块根据 YAML 配置选择 MQ 异步或 Feign 同步方式通知 LMS/WMS 执行完成、取消业务;业务处理成功后,两条链路都由 Task 服务统一把任务从回调待处理状态推进到最终完成或取消状态。
当前问题
TransportTaskOperationManager#handleFinished、handleCancelled固定发布 RocketMQ 消息,无法切换为同步 Feign。- LMS/WMS 的 MQ Consumer 调用
AbstractTask#doHandleFinish、doHandleCancel后没有回调 Task,任务停留在FINISHED_CALLBACK_PENDING或CANCEL_CALLBACK_PENDING。 TransportTaskCallbackServiceImpl使用%03d格式化字符串状态码,回调处理存在运行时类型异常。TaskCommonApi只暴露取货、进出等动作,没有完成和取消接口。
配置
在 Task 服务 YAML 中增加必填配置:
nl:
task:
callback-type: mq
允许值为 mq、feign。使用枚举解析配置;配置缺失或值非法时启动失败,不做静默兜底。默认项目配置使用 mq,保持现有部署行为。
执行链路
MQ 异步模式
- Task 将任务置为对应的回调待处理状态,并把
callbackStatus置为PENDING。 - 当前事务提交后发布完成或取消消息。
- LMS/WMS Consumer 校验任务仍处于当前事件对应的待处理状态,然后路由到
AbstractTask子类执行业务。 - 业务成功后,Consumer 写入带有效期的 Redis 成功标识,再通过
TransportTaskApi.receiveCallbackResult回调SUCCESS;若成功回调失败,MQ 重试时只重试回调,不重复执行业务。 - Task 的统一回调服务把任务更新为
FINISHED或CANCELLED,并把callbackStatus置为SUCCESS。 - 业务异常时,Consumer 尝试回调
FAILED记录错误与重试次数,再重新抛出异常,让 MQ 执行重试。
Feign 同步模式
- Task 将任务置为对应的回调待处理状态,并把
callbackStatus置为PENDING。 - Task 根据
ownerService从TaskCommonApiFactory获取 LMS/WMS Feign Client。 - 调用新增的
doHandleFinished或doHandleCancelled,业务服务通过TaskFactory路由到相同的AbstractTask子类。 - Feign 返回成功后,Task 直接调用统一回调服务,以相同规则更新最终状态。
- Feign 返回失败或抛出异常时不进入最终状态,异常沿现有任务操作链路上抛。
接口与数据
- 在
TaskCommonApi增加doHandleFinished、doHandleCancelled。 - 两个接口继续复用
TaskStatusCallApiReqDTO,携带任务标识、业务归属、业务标识、处理器编码和 payload。 - 同步与异步链路都复用
TaskCallbackResultReqDTO和TransportTaskCallbackService完成最终状态收口。 eventId使用任务 ID 与事件类型组成的稳定值;Task 按当前 pending 状态校验 eventId,拒绝延迟或错序事件推进错误终态。
幂等与错误处理
- Task 已处于
FINISHED或CANCELLED时忽略重复成功回调。 - 只有
FINISHED_CALLBACK_PENDING能推进到FINISHED,只有CANCEL_CALLBACK_PENDING能推进到CANCELLED。 - MQ 重复消息在消费前查询 Task 状态;状态已不匹配时直接跳过。
- MQ 业务成功后使用七天 Redis 标识隔离业务执行与 Task 成功回调重试;成功回调完成后删除标识。
- Feign
CommonResult必须调用getCheckedData或检查isSuccess,业务失败不允许误更新最终状态。 - MQ 回调失败不吞掉业务异常,保留 RocketMQ 重试能力。
- 任务状态分布式锁延迟到本地事务完成后释放,避免提交前窗口发生并发重复处理。
验证
- Spring 集成测试验证 execute starter 的完成、取消 Feign 入口能正确路由到任务处理器。
- 编译 execute starter、task-api、task-server、lms-server、wms-server,验证跨模块接口一致。
- 检查 MQ 成功回调和 Feign 成功返回最终都进入统一状态处理服务。
一致性边界
- MQ 和 Feign 均向
AbstractTask透传稳定的eventId与eventType,业务处理器应以该事件标识在业务数据库中实现幂等。 - Redis 成功标识可以避免“业务已成功、Task 成功回调失败”时重复执行业务,但不能覆盖业务事务提交后、Redis 标识写入前进程崩溃的极小窗口,因此业务数据库幂等仍是最终保障。
- Feign 调用与 Task 本地事务不构成分布式事务;远端成功后若本地事务回滚,重试仍依赖上述事件幂等。