补充组件依赖
前言
对于供应链业务,一般对数据一致性要求高。且由于业务复杂,可能会存在一个业务功能触发几个异步操作的场景,且要保证相关操作同时触发或不触发。
为了降低技术设计难度、代码编写难度,特意设计最终一致性框架,将复杂度转移到底层组件,释放业务层设计难度,提高一致性,减少线上问题。
需求分析
应用场景
- 供应链复杂业务,需要确保 MQ、数据库事务的一致性,但是不希望在业务层过多设计
- 供应链复杂业务,发送多个 MQ 消息,且要保证这些 MySQL事务、MQ 同时成功或失败
- 对于C端商城业务,此中间件作为选项。如果不采用这套方案,需要为具体的业务场景设计最终一致性方案
- 主要针对功能:异步类型功能,例如:MQ、异步任务等
原理
- 原理:基于 MySQL 事务,将异步功能,先转换为一行数据存储到 MySQL。存储后再用异步线程执行任务。同时,设置有后台定时任务对任务表进行轮询补偿。
功能
2. 管理后台:拥有在管理后台,查询相关接口并进行重试的能力
3. 监控:监控执行的相关性能:生成任务的速率、异步线程消费任务的速率、定时任务消费任务的速率
组件依赖
- xx-mybatis-plus-starter
a. 依赖 xx mysql 规范,使用基础组件的 orm starter - xx-threadpool-starter
- xx-redis-starter
- xx-rocketmq-starter
- xx-actuator-starter
- promethues
a. 需要对相关指标做监控
使用注意事项
- 对使用的需求:上述执行的任务,要是幂等的。在MQ层面,要求MQ消费者幂等;在异步任务层,要求异步任务是幂等的
概要设计
功能交互
后台管理功能
- 管理列表
- 重试单个失败任务
- 批量重试失败任务
详细设计
API接口设计
- 管理列表
接口说明 列表分页查询
分页方式:使用{@link ConsistencyListDto#getStartId()}(默认为0)作为起始ID进行查询,返回size大小的数据。
前端点「下一页」时需要将当前页最大的id赋值给startId作为参数传递
todo 不能返回上一页,或前端记录上一页的startId??
排序:默认使用主键排序,不支持自定义
{@link ConsistencyListDto#getSize()}为必填,最大限制50
接口地址 /consistency/getByPage
入参 com.xx.support.consistency.core.entity.dto.ConsistencyListDto
出参 com.xx.support.consistency.core.entity.vo.ConsistencyVo - 手动重试已失败的任务
接口说明 单个失败任务重试
执行方式:立即执行任务
接口地址 /consistency/retryFailedTaskById
入参 com.xx.support.consistency.core.entity.dto.ConsistencyIdDto
出参 无 - 手动批量重试已失败的任务
接口说明 1. 可根据consumerBeanName进行重试 - 如果consumerBeanName为空则重试全部已失败的任务
执行方式:接口操作内容为修改已失败任务的状态由FAIL改为PENDING,修改后后台定时任务会进行扫描执行这些任务
接口地址 /consistency/retryFailedTaskAll
入参 com.xx.support.consistency.core.entity.dto.ConsistencyBeanNameDto
出参 无
表设计
CREATE TABLE support_consistency
(
id
bigint unsigned NOT NULL AUTO_INCREMENT COMMENT ‘id’,
consumer_bean_name
varchar(32) NOT NULL DEFAULT ‘’ COMMENT ‘消费本地消息的bean的名称’,
consistency_state
varchar(16) NOT NULL DEFAULT ‘’ COMMENT ‘消息状态’,
msg_type
varchar(16) NOT NULL DEFAULT ‘’ COMMENT ‘消息类型’,
exec_count
int unsigned NOT NULL DEFAULT ‘0’ COMMENT ‘执行次数(默认为0,当消息发送一次 进行加1)’,
max_exec_count
int unsigned NOT NULL DEFAULT ‘3’ COMMENT ‘最大重试次数’,
exec_priority
int unsigned NOT NULL DEFAULT ‘100’ COMMENT ‘执行优先级,数字越小,优先级越高’,
expected_exec_time
datetime NOT NULL DEFAULT ‘1970-01-01 00:00:00’ COMMENT ‘预期执行时间’,
latest_exec_time
datetime NOT NULL DEFAULT ‘1970-01-01 00:00:00’ COMMENT ‘最后一次执行时间’,
success_time
datetime NOT NULL DEFAULT ‘1970-01-01 00:00:00’ COMMENT ‘执行成功时间’,
fail_time
datetime NOT NULL DEFAULT ‘1970-01-01 00:00:00’ COMMENT ‘失败时间’,
exec_user
varchar(32) NOT NULL DEFAULT ‘’ COMMENT ‘执行人’,
create_time
datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘创建时间’,
create_user
varchar(32) NOT NULL DEFAULT ‘’ COMMENT ‘创建人’,
update_time
datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ‘更新时间’,
update_user
varchar(32) NOT NULL DEFAULT ‘’ COMMENT ‘更新人’,
del_timestamp
bigint unsigned NOT NULL DEFAULT ‘0’ COMMENT ‘是否删除(0:未删除,非0(14位时间戳):已删除)’,
version
int unsigned NOT NULL DEFAULT ‘1’ COMMENT ‘版本号’,
PRIMARY KEY (id
),
KEY idx_support_consistency_1
(consistency_state
,msg_type
,exec_priority
,expected_exec_time
) USING BTREE,
KEY idx_support_consistency_2
(consumer_bean_name
,consistency_state
) USING BTREE
) ENGINE=InnoDB COMMENT=‘一致性本地消息-主表’;
CREATE TABLE support_consistency_text
(
id
bigint unsigned NOT NULL AUTO_INCREMENT COMMENT ‘id’,
support_consistency_id
bigint unsigned NOT NULL DEFAULT ‘0’ COMMENT ‘主表id’,
error_msg
varchar(255) NOT NULL DEFAULT ‘’ COMMENT ‘执行错误信息’,
msg_text
text COMMENT ‘消息文本’,
create_time
datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘创建时间’,
create_user
varchar(32) NOT NULL DEFAULT ‘’ COMMENT ‘创建人’,
update_time
datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ‘更新时间’,
update_user
varchar(32) NOT NULL DEFAULT ‘’ COMMENT ‘更新人’,
del_timestamp
bigint unsigned NOT NULL DEFAULT ‘0’ COMMENT ‘是否删除(0:未删除,非0(14位时间戳):已删除)’,
version
int unsigned NOT NULL DEFAULT ‘1’ COMMENT ‘版本号’,
PRIMARY KEY (id
),
KEY idx_support_consistency_text_1
(support_consistency_id
) USING BTREE
) ENGINE=InnoDB COMMENT=‘一致性本地消息-报文表’;