分布式任务调度
文章目录
分布式任务调度
场景
-
报表统计
需要每天或者定时调度产生的报表。
-
日/月结单
金融/支付领域按时结单。
-
爬虫
定时爬取内容。
-
数据归档
数据量较大时,定时进行整理数据并存储。
任务调度框架类型
非分布式任务调度框架
只适用于单机应用,代表框架为Spring自带的@Scheduled。
使用@Scheduled
引入依赖的框架:
|
|
启动类上添加注解启动定时任务:
|
|
使用:
|
|
多线程使用@Scheduled
默认的@Scheduled使用方式是单线程的,也就是说,如果有两个定时任务,会出现两个定时任务抢占调度机会的情况,一个调度任务不能及时被调度的情况发生。这种情况下就需要使用多线程方式。
使用:
在启动类中添加设置定时任务线程池的配置:
|
|
添加两个定时任务:
|
|
启动后可以在控制台中看到类似下面的输出:
|
|
可以看到,此时已经有了两个线程taskScheduler-1
和taskScheduler-2
来分别处理两个定时任务。
异步调度@Scheduled
使用Spring Boot自带的@Async
注解开启异步任务,在定时任务中调用即可实现忽略定时任务执行时间,根据设置好的时间间隔定时调度。
分布式任务调度框架
-
QuartZ
只是简单的提供了分布式任务调度,没有可视化界面,接口不好用。
-
ElasticJob
基于QuartZ开发,使用的中间件较多,复杂度较高。
-
XXL-JOB
美团点评开源的分布式任务调度框架。使用较为简单。
-
SchedulerX
为阿里云商用软件,不开源需要花钱购买。
-
PowerJob
使用QuartZ
引入依赖:
|
|
配置运行规则:
|
|
设置定时任务:
|
|
使用XXL-Job
搭建xxl-job-admin
创建XXL-Job需要的数据库表结构:
|
|
使用Docker搭建xxl-job-admin
任务调度中心:
|
|
容器启动成功后,访问http://127.0.0.1:8080/xxl-job-admin
,可以登录到xxl-job-admin
任务调度中心控制台。默认用户名admin
,默认密码123456
。
可在任务调度中心控制台里看到:
- 运行报表
- 任务管理
- 调度日志
- 执行器管理
- 用户管理
等信息。
使用xxl-job-admin
引入依赖:
|
|
执行器配置信息:
|
|
其余的使用默认配置项即可,可选配置项如下:
|
|
配置执行器:
|
|
启动项目后,可在xxl-job-admin
的执行器管理里看到对应的OnLine机器地址
里出现了注册节点地址为http://192.168.9.223:9999/
的机器(即刚启动成功的Java执行器应用)。
机器注册到任务调度中心之后,就可以创建调度任务并执行了。
在xxl-job-admin
的任务管理里新增任务,配置项如下:
-
任务描述:
-
路由策略:
-
Cron:
指定此任务要遵循的Cron表达式。
-
运行模式
-
BEAN
BEAN模式运行在执行器里。
-
GLUE
包括:
- Java
- Shell
- Python
- PHP
- Nodejs
- PowerShell
GLUE模式运行在任务调度中心。
-
-
JobHandler
**后续需要在执行器中指定,才可实现执行器定时执行该任务。**这里使用
myXxlJobHandler
。 -
隔离处理策略
-
负责人
任务创建人
然后在程序中开发执行器:
|
|
启动项目后,可以在控制台中看到如下的日志:
|
|
然后,可以在任务调度中心里的任务管理里,选择创建的任务,在操作里选择执行一次或启动,启动后,程序会按照对应的Cron表达式的内容定时调度执行任务。并可选择查询日志查看任务执行的结果。
最重要的一点,可以在任务管理中心里直接修改任务的Cron表达式,修改定时计划,执行器程序不需重新启动即可直接生效。
路由策略
任务调度中心里可配置的任务路由策略有:
- 第一个(默认)
- 最后一个
- 轮询
- 随机
- 一致性HASH
- 最不经常使用
- 最近最久未使用
- 故障转移
- 忙碌转移
- 分片广播
当只有一个任务调度中心,而有多个执行器的时候,任务调度中心要选择一个或多个执行器来执行任务,也就是对应的路由策略。
在idea里项目中心里使用Edit Configurations
选项复制现有的任务调度项目,修改项目名为DistributedJobApplication(2)
,端口为8083
。同时启动两个项目。登录任务调度中心查看执行器OnLine机器地址,可以发现其中已经注册了两个执行器。地址的端口分别为两个执行器程序连接时使用的端口。开启定时任务执行,使用默认路由策略(第一个),会发现此时只有第一个注册的执行器会定时调用任务。同理,如果路由策略为最后一个,则正好反过来。如果是轮询策略,则为注册的多个执行器轮流执行。
由官方文档可知,相关配置项的功能如下:
路由策略:当执行器集群部署时,提供丰富的路由策略,包括;
FIRST(第一个):固定选择第一个机器;
LAST(最后一个):固定选择最后一个机器;
ROUND(轮询):;
RANDOM(随机):随机选择在线的机器;
CONSISTENT_HASH(一致性HASH):每个任务按照Hash算法固定选择某一台机器,且所有任务均匀散列在不同机器上。
LEAST_FREQUENTLY_USED(最不经常使用):使用频率最低的机器优先被选举;
LEAST_RECENTLY_USED(最近最久未使用):最久未使用的机器优先被选举;
FAILOVER(故障转移):按照顺序依次进行心跳检测,第一个心跳检测成功的机器选定为目标执行器并发起调度;
BUSYOVER(忙碌转移):按照顺序依次进行空闲检测,第一个空闲检测成功的机器选定为目标执行器并发起调度;
SHARDING_BROADCAST(分片广播):广播触发对应集群中所有机器执行一次任务,同时系统自动传递分片参数;可根据分片参数开发分片任务;
其中故障转移
策略,会优先选择第一个注册的执行器进行调度,如果第一个注册的执行器出现故障无法调用,会转而调用第二个执行器进行调度,直到第一个执行器恢复正常,会再次调度第一个。
轮询策略的特点是流量均摊,故障转移把所有流量都压到一个执行器上。
分片广播策略
:
有时可能定时任务需要处理的数据量很大,单台服务器无法快速完成,可以使用分片广播策略调度多台执行器同时运行,但分别处理一部分与其他执行器不同的数据。
分片广播策略用法:
|
|
其中ShardingUtil.ShardingVO
有两个属性:index
和total
:
index:当前分片序号(从0开始),执行器集群列表中当前执行器的序号;
total:总分片数,执行器集群的总机器数量;
再次启动两个项目后,可以看到,一台执行器只执行1和3的数据,另一台只处理2和4的数据。
同理,即使再增加执行器数量,也可以保证数据只在其中一台执行器执行一次。
阻塞处理策略
阻塞处理可选策略:
单机串行(默认):调度请求进入单机执行器后,调度请求进入FIFO队列并以串行方式运行;
丢弃后续调度:调度请求进入单机执行器后,发现执行器存在运行的调度任务,本次请求将会被丢弃并标记为失败;
覆盖之前调度:调度请求进入单机执行器后,发现执行器存在运行的调度任务,将会终止运行中的调度任务并清空队列,然后运行本地调度任务;
文章作者 punk1u
上次更新 2021-01-12