单体定时任务到分布式集群定时平台搭建

503 阅读4分钟

task-scheduling

模块:corn、Timer、ScheduledExecutor、scheduled、quartz、elastic-job
gitee地址(开源项目):
gitee.com/flowerAndJa…
开源源码
timer-demo模块:Timer定时案例;
scheduledExecutor-demo模块:为ScheduledExecutor线程池定时任务;
springboot-scheduled模块:SpringBoot自带的定时任务;
quartz-monomer-demo模块:quartz实现单体任务调度;
quartz-cluster-demo模块:quartz搭建集群任务调度;
spring-elasticjob模块:spring集成elasticjob;
elasticjob-springboot-starter模块:自定义elasticjob启动类;
elasticjob-test模块:springboot使用elasticjob测试定时任务;

知识模块
参考下方文档;

一 corn

代表任务执行时间

1.1 corn长度

例如: 0 * * * * ?

七个域 秒 分 时 日 月 星期 年
六个域(常用) 秒 分 时 日 月 星期

1.2 每个域取值

域           允许值                  允许的特殊字符
秒           0-59                   , - * /
分           0-59                   , - * /
小时         0~23                    , - * /
日           1-31                   , - * / ? L W
月           1-12 or JAN-DEC        , - * /
周           1-7 or SUN-SAT         , - * / ? L #
年           1970-2099              , - * /

备注:
每个域允许上面数字和特殊应字符。'-'代表数字取值范围 ','代表枚举 '*'代表任意数字' '/'代表递增。
'?'当表示月的第几天,周需要用'?'。当表示周的第几天,月用'?'。

案例:
0 0 10 * * ? 每天10点触发一次 
0 */1 * * * ? 每隔1分钟执行一次 
0 0-5 14 * * ? 在每天下午2点到下午2:05期间的每1分钟触发  
0 0 17 ? * TUES,THUR,SAT 每周二、四、六下午五点

1.3 在线生成corn表达式生成校验

https://cron.qqe2.com/

二 Timer

JDK提供的任务调度。每个Timer对应一个线程,因此可以同时启动多个Timer并行执行多个任务,同一个Timer中的任务是串行执行。 已经被ScheduledExecutor替换掉了,知道有Timer就行。

三 ScheduledExecutor

Java 5 推出了基于线程池设计的定时任务。每个定时任务会从线程池中取出一个线程执行,并发执行,互不干扰。

总结 Timer和ScheduledExecutor只能执行延时多久,并以一定的周期来执行。复杂的任务调度不能完成。

四 Quartz

支持复杂的定时任务。支持集群,不支持分布式。

1.4.1 概述

1. 核心角色(Trigger,JobDetail ,Scheduler) Trigger:定义调度规则
JobDetail:封装job,job定义具体业务。
Scheduler:将Trigger和JobDetail注册到Scheduler。Scheduler根据Trigger规则调用JobDetail中业务。

2. 单体任务调度使用 配置文件中配置scheduler名称
定义job类继承QuartzJobBean
在配置类中定义JobDetail、Triggerd对象

1.4.2 集群服务搭建(需要mysql分布式锁)

1. 集群环境,如何防止任务重复执行? a 每个quartz服务只有一个Scheduler实例 b Scheduler实例要想执行任务,需要qrtz_locks表中行锁; 锁被占用:等到其他Scheduler释放锁; 获取到锁:获取qrtz_triggers表中Waiting状态,并且即将出发的trigger; 将Trigger状态由Waiting修改为Acquired; 将trigger信息插入qrtz_fire_triggers表; c qrtz_fired_triggers修改为executing; 执行Job;修改qrtz_triggers中下次触发时间;将状态修改为Waiting;

2. 故障判断 每个Quartz服务中Scheduler会定时更新qrtz_scheduler_state表中的LAST_CHECK_TIME字段。当集群中有 一个Scheduler更新时,会检查其它的Scheduler是否按预期更新,如果为否,认为节点故障。

3. 失败迁移 删除qrtz_scheduler_state表中对应的schedular信息,将任务可以由其他schedular执行;

五 Elastic-job(重要,经常使用)

支持分布式任务调度技术。

1. 使用步骤(参考elasticjob-test代码参考引用)
a 安装Zookeerper注册中心
b 导入elasticjob启动类(就是代码elasticjob-springboot-starter模块)
c 自定义监听器、分片规则(直接使用默认分片规则)
c 编写任务类

2. 名词讲解 Elastic-Job-lite 以jar包形式提供轻量级的分布式任务; 依赖zookeeper: 分布式协调和任务信息管理;; 分片:定时任务执行最小单位; 一个项目分成几片,这个定时任务方法就执行几次。所以你可能存在疑问,那不就造成任务重复执行。 我们处理自己的业务,将任务分到不同的分片。然后将分片放到不同的服务。即实现分布式调度, 而且还不会重复执行任务。

3. 高级特性 作业分片 elasticjob自定义平均分片略,我们也可以自定义分片策略。需要继承JobShardingStrategy。(具体实现参考elasticjob-test模块代码) 弹性扩容 新增一个服务。zookeeper监听到新的服务注册进来,服务重新选举主节点,主节点调用分片策略,从新分片到各个服务上。 失效转移 片分布到若干个服务器上,如果其中一个服务死机了,则该服务分片会被别的服务抢占。保证任务完整性。开启,failover="true" 幂等性 一个任务准备执行,但是上次定时任务还没执行完毕。这次任务不执行,等待下次任务执行。monitorExecution=true,开启幂等性。