轻量级分布式定时任务框架XXL-Job:
XXL-JOB是一款轻量级的分布式定时任务框架,上手简单,操作容易,XXL-Job可以到官网下载也可以去gitee上拉取源码,其中核心模块分页两个:1:是分布式调度服务, 2:是执行器。启动分布式调度服务模块,可以直接登录后台系统。
首先简单了解一下XXL-JOB的XXL-JOB的有点特性:
1、简单:支持通过Web页面对任务进行CRUD操作,操作简单,一分钟上手;
2、动态:支持动态修改任务状态、启动/停止任务,以及终止运行中任务,即时生效;
3、调度中心HA(中心式):调度采用中心式设计,“调度中心”自研调度组件并支持集群部署,可保证调度中心HA;
4、执行器HA(分布式):任务分布式执行,任务"执行器"支持集群部署,可保证任务执行HA; 5、注册中心: 执行器会周期性自动注册任务,
调度中心将会自动发现注册的任务并触发执行。同时,也支持手动录入执行器地址;
6、弹性扩容缩容:一旦有新执行器机器上线或者下线,下次调度时将会重新分配任务;
7、路由策略:执行器集群部署时提供丰富的路由策略,包括:第一个、最后一个、轮询、随机、一致性HASH、最不经常使用、最近最久未使用、故障转移、忙碌转移等;
8、故障转移:任务路由策略选择"故障转移"情况下,如果执行器集群中某一台机器故障,将会自动Failover切换到一台正常的执行器发送调度请求。
9、阻塞处理策略:调度过于密集执行器来不及处理时的处理策略,策略包括:单机串行(默认)、丢弃后续调度、覆盖之前调度;
10、任务超时控制:支持自定义任务超时时间,任务运行超时将会主动中断任务;
11、任务失败重试:支持自定义任务失败重试次数,当任务失败时将会按照预设的失败重试次数主动进行重试;其中分片任务支持分片粒度的失败重试;
12、任务失败告警;默认提供邮件方式失败告警,同时预留扩展接口,可方便的扩展短信、钉钉等告警方式;
13、分片广播任务:执行器集群部署时,任务路由策略选择"分片广播"情况下,一次任务调度将会广播触发集群中所有执行器执行一次任务,可根据分片参数开发分片任务;
14、动态分片:分片广播任务以执行器为维度进行分片,支持动态扩容执行器集群从而动态增加分片数量,协同进行业务处理;在进行大数据量业务操作时可显著提升任务处理能力和速度。
15、事件触发:除了"Cron方式"和"任务依赖方式"触发任务执行之外,支持基于事件的触发任务方式。调度中心提供触发任务单次执行的API服务,可根据业务事件灵活触发
我将XXL-Job整合到Springboot,赋gitee项目源码练习,注意导入doc文件下的数据库,数据库版本在mysql8.0即可:https://gitee.com/xzq25_com/xxl-job
.
了解XXL-JOB执行原理图:详细的架构图在gitee源码doc目录下有
.
.
项目拉取之后,可以看到项目模块:xxl-job-admin模块是整合框架源码中的调度服务模块
另外xxl-job-test是个人自定义的业务模块,也叫执行器模块,
启动顺序:先启动admin服务,在启动test服务
项目启动之后,http://localhost:8080/xxl-job-admin 进入登录页 ,默认用户:admin 密码:123456
.
接下来就是熟悉一下调度系统具体使用啦:
系统的具体分为报表、日志、执行器管理、任务管理、用户管理。
创建完执行器,接下来就是在任务管理处创建调度任务,关联执行器,如下图所示:
这里需要了解一下上图得调度类型、运行模式、路由策略
1,调度类型分为3种
基本实际工作种选择第二种Cron采用时间表达式来定时触发
.
运行模式: | xxl-job中,不仅支持运行预先编写好的任务类,还可以直接输入代码或脚本运行 |
---|---|
BEAN模式 | 需要指定任务类,通常是Spring中的Bean,这个任务叫做JobHandler,是在执行器端编写的 |
GLUE模式 | 运行代码或脚本,支持Java脚本、Shell脚本、Python脚本、PHP脚本、Node.js脚本等,代码是直接维护在调度器的 |
对于GLUE模式,主要是在调度端直接输入需要执行得脚本,执行一些与业务代码无直接关系的信息。
基本上工作当中是BEAN模式运行,执行器的执行业务代码维护在项目服务器上,这里就简单了解下GLUE模式下脚本运行即可
.
1.第一个:当选择该策略时,会选择执行器注册地址的第一台机器执行,如果第一台机器出现故障,则调度任务失败。
2.最后一个:当选择该策略时,会选择执行器注册地址的最后一台机器执行,如果最后一台机器出现故障,则调度任务失败。
3.轮询:当选择该策略时,会按照执行器注册地址轮询分配任务,如果其中一台机器出现故障,调度任务失败,任务不会转移。
4.随机:当选择该策略时,会按照执行器注册地址随机分配任务,如果其中一台机器出现故障,调度任务失败,任务不会转移。
5.一致性HASH:当选择该策略时,每个任务按照Hash算法固定选择某一台机器。如果那台机器出现故障,调度任务失败,任务不会转移。
6.最不经常使用:当选择该策略时,会优先选择使用频率最低的那台机器,如果其中一台机器出现故障,调度任务失败,任务不会转移。
7.最近最久未使用:当选择该策略时,会优先选择最久未使用的机器,如果其中一台机器出现故障,调度任务失败,任务不会转移。
8.故障转移:当选择该策略时,按照顺序依次进行心跳检测,如果其中一台机器出现故障,则会转移到下一个执行器,若心跳检测成功,会选定为目标执行器并发起调度。
9.忙碌转移:当选择该策略时,按照顺序依次进行空闲检测,如果其中一台机器出现故障,则会转移到下一个执行器,若空闲检测成功,会选定为目标执行器并发起调度。
10.分片广播:当选择该策略时,广播触发对应集群中所有机器执行一次任务,同时系统自动传递分片参数;可根据分片参数开发分片任务。如果其中一台机器出现故障,则该执行器执行失败,不会影响其他执行器。
.
.
其他路由策略是比较好理解得,这里主要讲一下分片广播策略:
例如:现在有这么一个场景:一共5太机器集群,需要分布式定时任务执行同一段代码去查询mysql分表数据,这里分表在代码层面上模拟,利用调度系统分配给机器的分片id,将id经过hash运算之后再将业务数据存入mysql,主键id是分片id+生成业务id得组合。这种场景下,采用分片广播模式,只有当前分片id匹配符合,调度任务才可以业务代码,可以定时任务执行各自不同数据范围得,而不用每次到mysql查询都是全盘扫描。
.
分片广播策略下,有两个很重要的数据分片总数和当前分片数
分片总数:任务集群中任务服务的数量(可以理解执行器绑定了多少个ip:port)
当前分片数:当前的下标,同一片任务机器中,这个数字都是一样。
广播分片提供demo
博客地址:https://blog.csdn.net/weixin_44507274/article/details/105462365
/**
* 分片广播任务
*/
@XxlJob("shardingJobHandler")
public ReturnT<String> shardingJobHandler(String param) throws Exception {
log.info("参数:" + param);
// 分片参数
ShardingUtil.ShardingVO shardingVO = ShardingUtil.getShardingVo();
XxlJobLogger.log("分片参数:当前分片序号 = {}, 总分片数 = {}", shardingVO.getIndex(), shardingVO.getTotal());
log.info("分片参数:当前分片序号 = {}, 总分片数 = {}", shardingVO.getIndex(), shardingVO.getTotal());
// 业务逻辑
for (int i = 0; i < shardingVO.getTotal(); i++) {
if (i == shardingVO.getIndex()) {
XxlJobLogger.log("第 {} 片, 命中分片开始处理", i);
log.info("第 {} 片, 命中分片开始处理", i);
} else {
XxlJobLogger.log("第 {} 片, 忽略", i);
log.info("第 {} 片, 忽略", i);
}
}
return ReturnT.SUCCESS;
}
我这个发布了两个这样的服务,并且开启定时任务3s执行一次
然调度中心每次调度任务都会响应到所有的定时任务上,只是不同的服务命中的分片不一样。分片的值是调度中心分配的。
停了一个服务会怎么样?
如果两个停一个,分片总数会发生变化,并且当前分片数也可能会发生变化。
.
下面是gittee项目源码启动服务:
启动两个服务:一个调度,一个执行器
需要定时执行的一段业务代码:
@Component
public class SampleXxlJob {
private static Logger logger = LoggerFactory.getLogger(SampleXxlJob.class);
private static Integer i=0;
/**
* 1、简单任务示例(Bean模式)
*/
@XxlJob("demoJobHandler")
public void demoJobHandler() throws Exception {
System.out.println("执行任务第 【"+(++i)+"】 次....");
}
}
至此,XXL-JOB的基本了解和应用到此结束啦,希望能帮助到你哦…