流程图
表结构
-- 事件路由策略表
CREATE TABLE `tms_event_route` (
`event_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`company_id` bigint(20) NOT NULL COMMENT '租赁公司id',
`event_no` varchar(64) NOT NULL COMMENT '主事件编号',
`event_topic` varchar(100) NOT NULL COMMENT '主事件topic',
`event_name` varchar(64) NOT NULL COMMENT '主事件名称',
`sub_event_no` varchar(64) NOT NULL COMMENT '子事件编号',
`sub_event_name` varchar(64) NOT NULL COMMENT '子事件名称',
`sub_event_topic` varchar(100) NOT NULL COMMENT '子事件topic',
`status` tinyint(3) DEFAULT '1' COMMENT '状态(0=未生效 1=启用)',
`creator` varchar(20) DEFAULT NULL COMMENT '创建人',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间(不可人为调整)',
`modifier` varchar(20) DEFAULT NULL COMMENT '修改人',
`modify_time` datetime DEFAULT NULL COMMENT '修改时间',
`remarks` varchar(64) DEFAULT NULL COMMENT '备注',
`del_tag` varchar(2) DEFAULT '0' COMMENT '归档删除标识(0=正常归档,删除后数据同步下游 1=归档删除,删除后数据不同步下游)',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '记录更新时间',
PRIMARY KEY (`event_id`),
KEY `idx_event_no` (`event_no`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='事件路由策略表'
-- 任务事件表
CREATE TABLE `tms_task_list` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`company_id` bigint(20) NOT NULL COMMENT '租赁公司ID',
`task_topic` varchar(10) COLLATE utf8_bin NOT NULL COMMENT '主题',
`entrepot_no` varchar(20) COLLATE utf8_bin NOT NULL COMMENT '集散中心编码',
`quartzcenter_id` bigint(20) NOT NULL COMMENT '分片ID',
`transport_locno_id` bigint(20) DEFAULT NULL COMMENT '配送仓ID',
`bill_no` varchar(32) COLLATE utf8_bin NOT NULL COMMENT '单据号',
`owner_no` varchar(10) COLLATE utf8_bin DEFAULT NULL COMMENT '货主',
`service_url` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '服务地址',
`status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '处理状态 0=待处理 10=处理成功 9-处理失败 8->任务作废(超最大重试次数仍失败)',
`begin_time` datetime DEFAULT NULL COMMENT '执行开始时间',
`end_time` datetime DEFAULT NULL COMMENT '执行结束时间',
`task_pri` tinyint(4) NOT NULL DEFAULT '0' COMMENT '任务优先级',
`error_message` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '错误信息',
`execute_count` tinyint(4) NOT NULL DEFAULT '0' COMMENT '累计执行次数',
`creator` varchar(48) COLLATE utf8_bin NOT NULL COMMENT '创建人',
`create_time` datetime NOT NULL COMMENT '记录创建时间',
`update_user` varchar(48) COLLATE utf8_bin DEFAULT NULL COMMENT '修改人',
`modify_time` datetime DEFAULT NULL COMMENT '修改时间',
`remarks` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '备注',
`del_tag` varchar(2) COLLATE utf8_bin NOT NULL DEFAULT '0' COMMENT '归档删除标识(0=正常归档,删除后数据同步下游 1=归档删除,删除后数据不同步下游)',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '记录更新时间',
`error_detail_message` varchar(1024) COLLATE utf8_bin DEFAULT NULL COMMENT '错误详细信息',
`reserve_one` varchar(32) COLLATE utf8_bin DEFAULT NULL COMMENT '预留字段1',
`` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT '事件编号',
`next_time` datetime DEFAULT NULL COMMENT '下次执行时间',
`common_no` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT '同一事件公共编号',
PRIMARY KEY (`id`),
KEY `idx_entrepot_no` (`entrepot_no`),
KEY `idx_update_time` (`update_time`),
KEY `idx_next_time` (`next_time`),
KEY `idx_quartcenter_bill_event` (`quartzcenter_id`,`bill_no`,`sub_event_no`),
KEY `idx_bill_no` (`bill_no`)
) ENGINE=InnoDB AUTO_INCREMENT=1666407090736410627 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='异步任务清单';
--事件任务备份表
CREATE TABLE `tms_task_list_backup` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`company_id` bigint(20) NOT NULL COMMENT '租赁公司ID',
`task_topic` varchar(10) COLLATE utf8_bin NOT NULL COMMENT '主题',
`entrepot_no` varchar(20) COLLATE utf8_bin NOT NULL COMMENT '集散中心编码',
`quartzcenter_id` bigint(20) NOT NULL COMMENT '分片ID',
`transport_locno_id` bigint(20) DEFAULT NULL COMMENT '配送仓ID',
`bill_no` varchar(32) COLLATE utf8_bin NOT NULL COMMENT '单据号',
`owner_no` varchar(10) COLLATE utf8_bin DEFAULT NULL COMMENT '货主',
`service_url` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '服务地址',
`status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '处理状态 0=待处理 10=处理成功 9-处理失败',
`begin_time` datetime DEFAULT NULL COMMENT '执行开始时间',
`end_time` datetime DEFAULT NULL COMMENT '执行结束时间',
`task_pri` tinyint(4) NOT NULL DEFAULT '0' COMMENT '任务优先级',
`error_message` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '错误信息',
`execute_count` tinyint(4) NOT NULL DEFAULT '0' COMMENT '累计执行次数',
`creator` varchar(48) COLLATE utf8_bin NOT NULL COMMENT '创建人',
`create_time` datetime NOT NULL COMMENT '记录创建时间',
`update_user` varchar(48) COLLATE utf8_bin DEFAULT NULL COMMENT '修改人',
`modify_time` datetime DEFAULT NULL COMMENT '修改时间',
`remarks` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '备注',
`del_tag` varchar(2) COLLATE utf8_bin NOT NULL DEFAULT '0' COMMENT '归档删除标识(0=正常归档,删除后数据同步下游 1=归档删除,删除后数据不同步下游)',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '记录更新时间',
`error_detail_message` varchar(1024) COLLATE utf8_bin DEFAULT NULL COMMENT '错误详细信息',
`reserve_one` varchar(32) COLLATE utf8_bin DEFAULT NULL COMMENT '预留字段1',
`sub_event_no` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT '事件编号',
`next_time` datetime DEFAULT NULL COMMENT '下次执行时间',
`common_no` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT '同一事件公共编号',
PRIMARY KEY (`id`),
KEY `idx_entrepot_no` (`entrepot_no`),
KEY `idx_update_time` (`update_time`),
KEY `idx_next_time` (`next_time`),
KEY `idx_quartcenter_bill_event` (`quartzcenter_id`,`bill_no`,`sub_event_no`),
KEY `idx_bill_no` (`bill_no`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='备份表'
1.推送事件
1.定义事件枚举 TmsEventRouteEnum , 和路由策略表事件编号保持一致
2.发布事件
2.根据主事件编号, 查询子事件, 子事件批量入库事件表. 推送Spring 事件方法 (TmsTaskEventPublisherUtils)
3.Spring监听事件 异步监听发送事件消息到kafka (AsyncTaskEventListener)
- 配置事务提交后监听, 如果发车逻辑报错回滚,这里就不会收到事件消息了@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT, classes = TmsAsyncTaskEvent.class)
@Component
@Slf4j
public class AsyncTaskEventListener {
@Autowired
private StreamBridge template;
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT, classes = TmsAsyncTaskEvent.class)
@Async("eventExecute")
public void handleTmsTaskEvent(@NotNull TmsAsyncTaskEvent tmsAsyncTaskEvent) {
log.info("发送kafka事件消息 -- 开始: 事件名 = {}", tmsAsyncTaskEvent.getName());
template.send(BindingConstant.TMS_TASK_EXECUTE, (TmsTaskList) tmsAsyncTaskEvent.getSource());
log.info("发送kafka事件消息--成功结束, topic = {} , 参数 = {}" , BindingConstant.TMS_TASK_EXECUTE , JSON.toJSONString(tmsAsyncTaskEvent));
}
}
4.kafka消费者 (TmsTaskExecuteConsumerListener)
这里bean 和 配置文件的 definition 需要保持一致
5.消费逻辑 (executeTask)
- 加锁处理,防止重复消费
2.查询是否存在待处理事件
3.根据事件topic 获取对应执行实现类, ==这里路由策略表的子事件的sub_event_topic 要与这里的枚举编号一致, 如 发车写入托运单轨迹的话, 这个子事件对应的sub_event_topic 为1022,消费则会进入托运单轨迹这个具体的实现类==
如果是转单的子事件也是写入托运单轨迹, 那么这个子事件对应的sub_event_topic也是1022,进入托运单轨迹这个实现类消费, 只是在具体实现类里面, 根据不同的子事件编号sub_event_no判断是哪一种托运单轨迹, 则写入不同的托运单轨迹
6.消费成功
修改事件状态, 迁移成功数据到备份表, 删除原事件表数据 , 缓存事件值-1 已处理
7.消费失败
修改事件表, 设置错误原因,已重试次数,下次执行时间,根据不同的次数,设置不同的重试间隔时间
8.调度重试
实现类注册说明
1.实现类是通过TaskRegister 类, 通过启动类注解@TmsTaskRegisterScan("com.lesoon.tms.district.core.other.task") 扫包获取路径和实现发车类
2.再通过发车实现类的注解和对应枚举 @TmsTask(TmsTaskTopicEnum.TMS_TRANSPORT_PATH) , 获取到value,与常量 BEAN_NAME_PREFIX = "TMS_ASYNC_TASK_" 组成发车的beanName注册到Spring中
3.执行时候通过枚举值和常量就能拿到注册的对应写入托运单轨迹实现类, 执行对应的托运单轨迹逻辑
使用说明
- TmsEventRouteEnum类定义自己的主事件枚举
- 查看消费实现类有哪些,通用的可以复用
- 路由策略表添加自己的子事件
- 发布自己的事件
- 添加对应实现类(实现类需要新建在启动类扫描的包路径下==), 已有的可以直接复用, 譬如写入托运单轨迹, 已有类型的直接复用, 没有的添加switch类型, 添加自己的写入托运单轨迹类型