107:XXL-JOB原理的分析
1 xxl-job分布式任务调度平台演示
课题内容
- 传统的定时任务存在哪些缺陷
- 定时任务有哪些实现方案
- 基于XXL-JOB实现分布式任务调度
- XXL-JOB集群方案部署的原理
2 传统的定时任务存在哪些缺陷
传统的定时任务存在哪些缺陷?
1.定时任务代码和业务逻辑代码放入同一个jar中,如果定时任务挂了也会影响到业务逻辑,需要将定时任务和业务逻辑代码完全分开项目部署;
2.如果服务器集群的情况下,可能存在定时任务会重复触发执行;
3 集群中的定时任务如何保证执行幂等性
如何保证定时任务在集群中只会执行一个?
- 将定时任务代码单独部署一个jar包中,不参与业务逻辑服务器集群部署;
- 在jar中开启一个定时任务配置开关,判断是否需要将定时任务类加载到spring容器中;
- 使用分布式锁。项目启动中,只要谁能够拿到分布式锁,谁就能够将定时任务的配置类加载到spring容器中,否则不加载;
- 数据库中插入主键id,只要谁能够往数据库中插入一条相同的主键,插入成功就可以加载定时任务配置类;
以上方案只适合小项目,不适合互联网级别项目 - 采用分布式任务调度平台框架
4 传统的定时任务的实现方案
传统定时任务的实现方案
多线程形式、timertask、线程池、springboot注解形式、quartz
Maven依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.11.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- quartz -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
</dependency>
</dependencies>
1.基于多线程方式实现
public class ThreadJob {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
while(true){
try{
Thread.sleep(1000);
System.out.println("定时任务每隔1s触发");
}catch (Exception e){
e.printStackTrace();
}
}
}
}).start();
}
}
2.TimerTask
public class TimerTaskDemo {
public static void main(String[] args) {
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "定时任务触发");
}
};
Timer timer = new Timer();
// 天数
long delay = 0;
// 耗秒数
long period = 1000;
timer.scheduleAtFixedRate(timerTask, delay, period);
}
}
3.线程池
public class ScheduledExecutorServiceDemo {
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "定时任务触发..");
}
};
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(10);
scheduledExecutorService.scheduleAtFixedRate(runnable, 1, 1, TimeUnit.SECONDS);
}
}
4.SpringBoot注解形式
@Component
public class UserScheduled {
@Scheduled(cron = "0/1 * * * * *")
public void taskUserScheduled() {
System.out.println("定时任务触发...");
}
}
@SpringBootApplication
@EnableScheduling
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class);
}
}
5.基于Quartz实现
public class QuartzTest {
public static void main(String[] args) throws SchedulerException {
//1.创建Scheduler的工厂
SchedulerFactory sf = new StdSchedulerFactory();
//2.从工厂中获取调度器实例
Scheduler scheduler = sf.getScheduler();
//3.创建JobDetail
JobDetail jb = JobBuilder.newJob(MyJob.class)
.withDescription("this is a ram job") //job的描述
.withIdentity("ramJob", "ramGroup") //job 的name和group
.build();
//任务运行的时间,SimpleSchedle类型触发器有效
long time = System.currentTimeMillis() + 3 * 1000L; //3秒后启动任务
Date statTime = new Date(time);
//4.创建Trigger
//使用SimpleScheduleBuilder或者CronScheduleBuilder
Trigger t = TriggerBuilder.newTrigger()
.withDescription("")
.withIdentity("ramTrigger", "ramTriggerGroup")
//.withSchedule(SimpleScheduleBuilder.simpleSchedule())
.startAt(statTime) //默认当前时间启动
.withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?")) //两秒执行一次
.build();
//5.注册任务和定时器
scheduler.scheduleJob(jb, t);
//6.启动 调度器
scheduler.start();
}
}
public class MyJob implements Job {
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("quartz MyJob date:" + new Date().getTime());
}
}
5 分布式任务调度平台实现原理
常用式任务调度框架
Xxl-job(推荐)、elasticjob、SpringAlibaba Cloud SchedulerX
设计分布式任务调度平台
定时任务的项目一定是集群部署,但是最终只会执行一台服务器;
为了能够提高定时任务集群执行的效率,一定是分片执行;
原理分析:
- 手动的将定时任务的项目(执行器)服务器ip和端口号统一存放到分布式任务调度平台的注册中心;
- 所有的定时任务触发规则,先在“分布式任务调度中心”先触发,再查询注册中心执行器集群地址,采用负载均衡的算法只会取一个地址;
- 获取该地址之后,再使用rpc远程调用该接口,通知它可以去触发定时任务。
一句话总结分布式任务调度平台的原理:
1 将定时任务项目(执行器)服务ip和端口号统一注册到分布式任务调度平台中,触发定时任务的时候先走分布式任务调度中心;
2 分布式任务调度中心获取执行器集群列表,采用负载均衡算法获取一个地址,采用rpc通知执行器执行定时任务。
6 构建XXL-JOBAdmin调度中心
XXL-JOB任务调度平台
官网:https://www.xuxueli.com/xxl-job/
XXL-Job Admin平台搭建 任务调度中心
1、官方下载XXL-Job Admin的源代码
2、导入xxl-job需要依赖的sql(xxl-job\doc\db\tables_xxl_job.sql)
3、在xxl-job jdbc连接配置加上&serverTimezone=UTC否则报错(xxl-job\xxl-job-admin\src\main\resources\application.properties)
4、启动项目XxlJobAdminApplication和XxlJobExecutorApplication