14 KiB
Task 服务新架构详细开发设计方案
1. 业务背景与定位
新架构中,系统拆分为通用 Task 服务、LMS 服务、WMS 服务。
其中:
LMS:生产内部搬运业务,例如 AGV 搬运某个架子、托盘、料车到某个生产站点、缓存位、对接位;WMS:仓储出入库业务,例如入库、出库、移库、堆垛机搬运、AGV 和立库设备联动;Task:统一任务服务,负责任务创建记录、任务状态流转、调度下发外部系统、接收外部反馈、任务日志、重试和补偿。
旧架构中 AbstractAcsTask 同时承担了任务创建、点位计算、外部下发、完成业务、取消业务等职责。新架构建议将其拆分,避免 Task 服务反向依赖 LMS/WMS 的业务实现。
2. 总体设计目标
- Task 服务成为通用任务中台,只处理任务生命周期和外部系统交互;
- LMS/WMS 保留各自业务语义和业务数据处理能力;
- 不再跨服务使用 Java 类名
handle_class; - 使用稳定的
handler_code标识业务处理器; - 任务完成、取消时,由 Task 服务通知业务归属服务执行业务回调;
- 支持 AGV、堆垛机、ACS、WCS 等多种外部系统;
- 支持同步 RPC 回调,也能平滑演进到 MQ 事件回调;
- 支持幂等、重试、补偿和人工干预。
3. 核心拆分思想
旧版一个 AbstractAcsTask 拆成三层能力:
业务任务创建层:LMS/WMS
负责业务校验、点位计算、业务参数准备、调用 Task 创建任务
通用任务执行层:Task
负责任务状态、任务下发、外部反馈、任务日志、重试补偿
业务结果处理层:LMS/WMS
负责完成/取消后的业务确认、库存、单据、点位、分配明细处理
对应代码抽象:
LMS/WMS:BusinessTaskCreator,可选
Task:ExternalTaskDispatcher
LMS/WMS:TaskBizCallbackHandler
4. 服务职责边界
4.1 LMS 服务职责
LMS 负责生产内部搬运任务的业务语义,例如:
- 判断某个架子是否允许搬运;
- 判断目标站点、缓存位、对接位是否可用;
- 生成生产搬运业务记录;
- 调用 Task 服务创建搬运任务;
- 任务完成后更新生产业务状态;
- 任务取消后回滚生产占用、点位锁定、业务单据状态。
4.2 WMS 服务职责
WMS 负责仓储出入库任务的业务语义,例如:
- 入库、出库、移库业务校验;
- 库位分配、库存预占、出入库单据状态维护;
- 调用 Task 服务创建 AGV/堆垛机/输送线任务;
- 任务完成后确认出入库或移库;
- 任务取消后释放库位、回滚库存预占、恢复单据状态。
4.3 Task 服务职责
Task 服务只处理通用任务能力:
- 保存任务主表;
- 保存任务明细或任务步骤;
- 管理任务状态机;
- 根据
external_system选择外部系统下发器; - 下发 AGV/ACS/WCS/堆垛机任务;
- 接收外部系统反馈;
- 根据
owner_service通知 LMS/WMS 做业务回调; - 记录任务日志;
- 处理重试、超时和补偿。
Task 服务不直接处理 LMS/WMS 的业务表,不直接注入 LMS/WMS 的业务 Service。
5. 模块依赖设计
推荐依赖方向:
lms-server -> task-api
wms-server -> task-api
task-server -> task-api
task-server -> lms-api,可选,仅 RPC 回调需要
task-server -> wms-api,可选,仅 RPC 回调需要
禁止依赖:
task-server -> lms-server
task-server -> wms-server
如果采用 MQ 事件方式,Task 服务甚至可以不依赖 lms-api、wms-api,只发布标准任务事件。
6. 新版任务标识设计
旧版:
handle_class = org.nl.b_lms.sch.tasks.TwoInTask
新版:
owner_service = LMS
biz_type = PRODUCTION_TRANSFER
handler_code = LMS_RACK_TO_STATION
biz_id = LMS 业务记录 ID
或 WMS:
owner_service = WMS
biz_type = INBOUND
handler_code = WMS_INBOUND_STACKER
biz_id = WMS 入库单/分配明细 ID
字段含义:
| 字段 | 含义 |
|---|---|
owner_service |
任务归属业务服务,决定完成/取消回调给谁 |
biz_type |
业务任务类型,用于查询、统计和权限控制 |
handler_code |
业务回调处理器编码,业务服务内部使用 |
biz_id |
业务侧记录 ID,用于回查业务数据 |
external_system |
外部执行系统,例如 AGV、ACS、WCS、STACKER |
external_task_type |
外部系统任务类型 |
7. 数据模型建议
7.1 task_task 主表
| 字段 | 说明 |
|---|---|
id |
Task 服务任务 ID |
task_no |
任务编号 |
owner_service |
LMS/WMS |
biz_type |
业务类型 |
biz_id |
业务侧 ID |
handler_code |
业务回调处理器编码 |
external_system |
外部系统 |
external_task_type |
外部任务类型 |
status |
任务状态 |
priority |
优先级 |
start_point_code |
起点 |
end_point_code |
终点 |
vehicle_code |
载具、架子、托盘、料车等 |
callback_status |
回调状态 |
request_payload |
创建任务扩展参数 |
dispatch_payload |
下发外部系统参数 |
result_payload |
外部反馈参数 |
error_msg |
异常信息 |
7.2 task_task_log 日志表
记录每次状态变化、下发、反馈、回调、取消、重试。
关键字段:
| 字段 | 说明 |
|---|---|
task_id |
任务 ID |
event_type |
CREATE/DISPATCH/FEEDBACK/CALLBACK/CANCEL/RETRY |
from_status |
原状态 |
to_status |
新状态 |
request_json |
请求参数 |
response_json |
响应参数 |
success |
是否成功 |
error_msg |
错误信息 |
7.3 task_callback_log 回调日志表
用于保证业务回调幂等和补偿。
| 字段 | 说明 |
|---|---|
task_id |
任务 ID |
owner_service |
LMS/WMS |
handler_code |
业务处理器编码 |
event_type |
FINISH/CANCEL/EXECUTING |
status |
PROCESSING/SUCCESS/FAILED |
retry_count |
重试次数 |
error_msg |
失败原因 |
8. 状态机设计
推荐 Task 服务状态:
| 状态 | 含义 |
|---|---|
CREATED |
已创建 |
READY |
可下发 |
ISSUING |
下发中 |
ISSUED |
已下发 |
EXECUTING |
外部执行中 |
FINISHED_PENDING_CALLBACK |
外部完成,等待业务完成回调 |
FINISHED |
业务完成后最终完成 |
CANCEL_PENDING_EXTERNAL |
等待外部系统取消 |
CANCEL_PENDING_CALLBACK |
外部取消成功,等待业务取消回调 |
CANCELLED |
业务取消后最终取消 |
FAILED |
失败 |
核心原则:
外部系统完成 != 业务完成
外部系统取消 != 业务取消完成
因此必须有 PENDING_CALLBACK 中间状态。
9. 接口设计
9.1 Task 创建接口
POST /rpc-api/task/create
请求核心字段:
{
"ownerService": "LMS",
"bizType": "PRODUCTION_TRANSFER",
"bizId": "LMS-BIZ-10001",
"handlerCode": "LMS_RACK_TO_STATION",
"externalSystem": "AGV",
"externalTaskType": "MOVE",
"startPointCode": "CACHE_A01",
"endPointCode": "STATION_01",
"vehicleCode": "RACK_001",
"priority": 1,
"requestPayload": {}
}
WMS 入库示例:
{
"ownerService": "WMS",
"bizType": "INBOUND",
"bizId": "IN-DIS-10001",
"handlerCode": "WMS_INBOUND_STACKER",
"externalSystem": "STACKER",
"externalTaskType": "INBOUND",
"startPointCode": "IN_PORT_01",
"endPointCode": "A010101",
"vehicleCode": "PALLET_001",
"priority": 5,
"requestPayload": {}
}
9.2 外部系统反馈接口
POST /api/task/feedback
{
"taskId": 10001,
"externalTaskNo": "ACS-TASK-001",
"externalEventId": "EVT-001",
"status": "FINISHED",
"payload": {}
}
9.3 取消任务接口
POST /rpc-api/task/cancel
{
"taskId": 10001,
"reason": "人工取消"
}
9.4 业务回调接口
第一阶段建议 RPC,同步调用业务服务:
POST /rpc-api/lms/task-callback/handle
POST /rpc-api/wms/task-callback/handle
{
"taskId": 10001,
"taskNo": "T202607130001",
"eventType": "FINISH",
"bizType": "PRODUCTION_TRANSFER",
"bizId": "LMS-BIZ-10001",
"handlerCode": "LMS_RACK_TO_STATION",
"payload": {}
}
10. Task 服务核心代码抽象
10.1 外部系统下发器
public interface ExternalTaskDispatcher {
String getExternalSystem();
DispatchResult dispatch(TaskDO task);
CancelExternalResult cancelExternal(TaskDO task);
}
实现示例:
AgvTaskDispatcher
AcsTaskDispatcher
WcsTaskDispatcher
StackerTaskDispatcher
Task 服务根据 external_system 选择对应 dispatcher。
10.2 业务回调通知器
public interface TaskBizCallbackNotifier {
CallbackResult notifyFinish(TaskDO task);
CallbackResult notifyCancel(TaskDO task);
CallbackResult notifyExecuting(TaskDO task);
}
第一阶段可实现为 RPC:
RpcTaskBizCallbackNotifier
第二阶段可实现为 MQ:
MqTaskBizCallbackNotifier
11. LMS/WMS 业务回调 handler 设计
业务服务内部定义:
public interface TaskBizCallbackHandler {
String getHandlerCode();
void onTaskFinished(TaskCallbackRequest request);
void onTaskCancelled(TaskCallbackRequest request);
default void onTaskExecuting(TaskCallbackRequest request) {}
}
LMS 示例:
@Component
public class LmsRackToStationCallbackHandler implements TaskBizCallbackHandler {
@Override
public String getHandlerCode() {
return "LMS_RACK_TO_STATION";
}
@Override
public void onTaskFinished(TaskCallbackRequest request) {
// 更新生产搬运记录完成
// 更新架子当前位置
// 释放起点占用
// 占用目标站点或更新目标站点状态
}
@Override
public void onTaskCancelled(TaskCallbackRequest request) {
// 回滚生产搬运记录
// 释放目标站点锁定
// 恢复架子原状态
}
}
WMS 示例:
@Component
public class WmsInboundStackerCallbackHandler implements TaskBizCallbackHandler {
@Override
public String getHandlerCode() {
return "WMS_INBOUND_STACKER";
}
@Override
public void onTaskFinished(TaskCallbackRequest request) {
// 入库确认
// 更新库存
// 更新库位状态
// 更新入库单和分配明细
}
@Override
public void onTaskCancelled(TaskCallbackRequest request) {
// 回滚入库分配
// 释放库位预占
// 恢复入库单状态
}
}
业务服务内建立分发器:
@Service
public class TaskBizCallbackDispatcher {
private final Map<String, TaskBizCallbackHandler> handlerMap;
public void dispatch(TaskCallbackRequest request) {
TaskBizCallbackHandler handler = handlerMap.get(request.getHandlerCode());
if (handler == null) {
throw new IllegalArgumentException("未找到处理器:" + request.getHandlerCode());
}
if ("FINISH".equals(request.getEventType())) {
handler.onTaskFinished(request);
} else if ("CANCEL".equals(request.getEventType())) {
handler.onTaskCancelled(request);
} else if ("EXECUTING".equals(request.getEventType())) {
handler.onTaskExecuting(request);
}
}
}
12. 典型流程
12.1 LMS 生产搬运任务
LMS 判断架子 RACK_001 要去 STATION_01
-> LMS 锁定目标站点
-> LMS 创建生产搬运业务记录
-> LMS 调用 Task.createTask,handler_code = LMS_RACK_TO_STATION
-> Task 下发 AGV
-> AGV 反馈执行中,Task 更新 EXECUTING,可选通知 LMS
-> AGV 反馈完成,Task 更新 FINISHED_PENDING_CALLBACK
-> Task 回调 LMS
-> LMS 更新架子位置、站点状态、业务记录完成
-> Task 更新 FINISHED
12.2 WMS 入库任务
WMS 入库单分配库位 A010101
-> WMS 锁定库位,生成入库分配
-> WMS 调用 Task.createTask,handler_code = WMS_INBOUND_STACKER
-> Task 下发堆垛机/AGV
-> 外部系统反馈完成
-> Task 更新 FINISHED_PENDING_CALLBACK
-> Task 回调 WMS
-> WMS 确认入库、更新库存、更新库位、更新单据
-> Task 更新 FINISHED
12.3 取消任务
用户取消任务
-> Task 判断状态
-> 如果已下发,调用外部系统取消
-> 外部取消成功后 Task 更新 CANCEL_PENDING_CALLBACK
-> Task 回调 LMS/WMS
-> LMS/WMS 执行业务回滚
-> Task 更新 CANCELLED
13. 幂等与事务
13.1 Task 幂等
外部反馈按以下维度幂等:
task_id + external_event_id + status
同一个完成反馈不能重复触发业务完成。
13.2 业务幂等
LMS/WMS 按以下维度幂等:
task_id + event_type
如果业务回调已经成功,再次收到直接返回成功。
13.3 跨服务一致性
不做分布式事务,采用最终一致性:
- Task 更新为
PENDING_CALLBACK; - Task 调用 LMS/WMS;
- LMS/WMS 在本地事务内完成业务更新和回调日志;
- Task 更新最终状态;
- 失败则进入重试或人工补偿。
14. 开发落地步骤
第一阶段:基础 RPC 版本
- 在
task-api定义任务创建、取消、回调 DTO; - 在
task-server建任务主表、任务日志表、回调日志表; - 实现 Task 创建接口;
- 实现
ExternalTaskDispatcher和 AGV/ACS/堆垛机下发器; - 实现外部反馈接口;
- 实现 RPC 业务回调通知器;
- 在 LMS/WMS 实现
TaskBizCallbackHandler和分发器; - 打通 LMS 生产搬运和 WMS 入库两个典型任务。
第二阶段:增强可靠性
- 增加回调失败重试定时任务;
- 增加外部下发失败重试;
- 增加人工补偿页面;
- 增加状态流转校验;
- 增加任务日志和链路追踪。
第三阶段:MQ 演进
- Task 服务发布任务完成/取消事件;
- LMS/WMS 消费事件执行业务;
- 业务服务回调 Task 确认处理结果;
- RPC 和 MQ 可按任务类型配置切换。
15. 最终建议
不要把 LMS/WMS 的业务 xxxTask 子类放到 Task 服务,也不要让 Task 服务依赖 LMS/WMS server。
推荐把旧 AbstractAcsTask 拆成:
Task 服务:ExternalTaskDispatcher,负责外部系统下发和取消
LMS/WMS:TaskBizCallbackHandler,负责业务完成和业务取消
旧 handle_class 改为:
owner_service + handler_code
这样既保留了旧版“不同任务走不同处理器”的扩展性,又满足新架构下服务边界清晰、依赖方向正确、任务服务通用化的目标。