文章目录
- 什么是定时任务调度平台
- JAVA语言实现定时任务的几种方式
- Thead实现定时任务
- TImeTask实现任务调度
- 使用线程池实现定时任务
- 使用Quartz实现任务
- 定时任务执行出错的几种处理情况
- 分布式定时任务幂等性问题
- xxl-job的执行原理
- 部署搭建流程
什么是定时任务调度平台
指定时间去执行任务的管理平台
JAVA语言实现定时任务的几种方式
java语言能实现定时定时任务德方式主要有一下几种
1: Thead线程实现定时任务
2: TimeTask
3:定时任务线程池
4:quartz
5:springboot 内置注解@schedul
Thead实现定时任务
public class Demo01 {
static long count = 0;
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
count++;
System.out.println(count);
} catch (Exception e) {
// TODO: handle exception
}
}
}
};
Thread thread = new Thread(runnable);
thread.start();
}
}
TImeTask实现任务调度
/**
* 使用TimerTask类实现定时任务
*/
public class Demo02 {
static long count = 0;
public static void main(String[] args) {
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
count++;
System.out.println(count);
}
};
Timer timer = new Timer();
// 天数
long delay = 0;
// 秒数
long period = 1000;
timer.scheduleAtFixedRate(timerTask, delay, period);
}
}
使用线程池实现定时任务
public class Demo003 {
public static void main(String[] args) {
Runnable runnable = new Runnable() {
public void run() {
// task to run goes here
System.out.println("Hello !!");
}
};
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
// 第二个参数为首次执行的延时时间,第三个参数为定时执行的间隔时间
service.scheduleAtFixedRate(runnable, 1, 1, TimeUnit.SECONDS);
}
}
使用Quartz实现任务
引入依赖
<dependencies>
<!-- 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>
任务调度类
public class MyJob implements Job {
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("quartz MyJob date:" + new Date().getTime());
}
}
启动类
简单版本
public class HelloScheduler {
public static void main(String[] args) throws SchedulerException {
/**
* withIdentity param 为工作的JobKey命名name元素
*/
JobDetail myjob = JobBuilder.newJob(QuartzTest.class).withIdentity("myjob").build();
/**
* //创建一个Trigger触发器的实例,定义该job立即执行,并且每2秒执行一次,一直执行
*/
SimpleTrigger myTrigger = TriggerBuilder.newTrigger().withIdentity("myTrigger").startNow().withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2).repeatForever()).build();
/**
* //创建schedule实例
*/
StdSchedulerFactory stdSchedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = stdSchedulerFactory.getScheduler();
scheduler.start();
scheduler.scheduleJob(myjob,myTrigger);
}
}
//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();
案例
Quartz表达式
定时任务执行出错的几种处理情况
思考:如果定时任务在高兵发的情况下,宕机了该如何解决?—使用心跳检测监控自动重启,使用补偿机制(每个任务打个小标记)
定时任务在执行代码的时候突然报错啦,如何解决? —使用日志记录错误,跳过错误,继续执行
定时任务在执行的整个过程中都是报错的,如何解决? ---- 发送邮件通知运维人员
分布式定时任务幂等性问题
问题的出现,在三个war包当中,如何保证任务执行的唯一性呢?如何防止多个任务同时执行?
①使用zookeeper实现分布式锁 缺点(需要创建临时节点、和事件通知不易于扩展)
②使用配置文件做一个开关 缺点发布后,需要重启 — 在war包加上一个标识比如flag=true 就代码执行,为false代码不执行
③数据库唯一约束,缺点效率低
④使用分布式任务调度平台XXLJOB、Elastric-Job、TBSchedule
xxl-job的执行原理