# 定时任务的10种方式
**Repository Path**: fpfgitmy_admin/ten-ways-of-timing-task
## Basic Information
- **Project Name**: 定时任务的10种方式
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2021-04-28
- **Last Updated**: 2021-04-28
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
### 定时任务的10种方式
#### Linux自带的crontab
+ 优点:方便修改定时规则,支持一些较复杂的定时规则,通过文件可以统一管理配好的各种定时脚本
+ 缺点:如果定时任务非常多,不太好找,而且必须要求操作系统是 linux
+ 涉及技术:[Linux部署定时任务]()
#### jdk自带的定时任务
+ 优点:简单
+ 缺点:不支持定点,不支持延迟
+ 步骤:
1. 配合[SpringBoot配置项目启动后执行方法]()或者使用其他方法调用即可
2. 使用[Thread]()类的sleep方法,该线程可以定义成[守护线程]()
+ 代码如下:
```
public class TestCron {
public static void init() {
new Thread(() -> {
while (true) {
try {
System.out.println("执行了一些");
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
```
#### 使用jdk提供的Timer
+ 简介:Timer 类是jdk专门提供的定时器工具,用来在后台线程计划执行指定任务,在 java.util 包下,要跟 TimerTask 一起配合使用
+ 优点:非常方便实现多个周期性的定时任务,并且支持延迟执行,还支持在指定时间之后支持
+ 缺点:
1. Timer 是单线程执行任务,如果其中一个任务耗时非常长,会影响其他任务的执行
2. 如果 TimerTask 抛出 RuntimeException ,Timer会停止所有任务的运行
+ 步骤:
1. 创建Timer实例
2. 调用schedule方法,并传入TimerTask抽象类实现其方法
+ 代码如下:
```
public class TestCron {
public static void init() {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println(123);
}
// delay 延时时间(毫秒),period执行频率(毫秒)
},10,1000);
}
}
```
#### ScheduledExecutorService
+ 优点:基于多线程的定时任务,多个任务之间不影响,支持周期性执行,并带延迟功能
+ 缺点:不支持复杂的定时规则
+ 步骤:
1. 使用`Executors.newScheduledThreadPool(i)`创建线程池
2. 使用创建的实例调用对应的方法
+ 涉及技术:[Executors的使用]()、[ScheduledExecutorService的方法]()
+ 代码如下:
```
public static void init() {
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);
scheduledExecutorService.scheduleAtFixedRate(() -> {
System.out.println("执行了一些方法");
// initialDelay 延时时间, period 执行频率, 时间的单位
},1000,1000, TimeUnit.MILLISECONDS);
}
```
#### spring支持的定时任务
+ 简介:spring task 是 spring3 以上版本自带的定时任务,实现定时任务的功能时,需要引入 spring-context 包,目前它支持: xml 和 注解 两种方式
+ 优点:丰富的cron时间规则
+ 缺点:默认单线程,不支持集群,不能做数据存储型定时任务
+ 步骤:
1. 引入依赖
```
org.springframework
spring-context
```
2. 启动类上添加`@EnableScheduling`注解
```
@EnableScheduling
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
```
3. 使用`@Scheduled`定义规则,必须添加`@Component`注解
```
@Component
public class Cron {
// 每秒执行
@Scheduled(cron = "* * * * * ?")
private void testCron(){
System.out.println("具体的业务逻辑");
}
}
```
+ 设计技术:[cron规则]()
#### spring quartz
+ 简介:quartz 是 OpenSymphony 开源组织在 Job scheduling 领域的开源项目,是由java开发的一个开源的任务日程管理系统
+ 图示:
+ 名词示意:
+ Scheduler 代表调度容器,一个调度容器中可以注册多个JobDetail和Trigger
+ Job 代表工作,即要执行的具体内容
+ JobDetail 代表具体的可执行的调度程序,Job是这个可执行程调度程序所要执行的内容
+ JobBuilder 用于定义或构建JobDetail实例
+ Trigger 代表调度触发器,决定什么时候去调
+ TriggerBuilder 用于定义或构建触发器
+ JobStore 用于存储作业和任务调度期间的状态
+ 优点:支持动态的cron表达式填写,支持动态的任务添加
+ 缺点:
+ 步骤:
+ 设计技术:[quartz介绍]()
+ 代码如下:
#### spring支持的定时任务
+ 优点:
+ 缺点:
+ 步骤:
1. 引入pom
```
org.springframework.boot
spring-boot-starter-quartz
```
2. 编写任务执行类
```
public class Job1 extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
String userName = (String) jobExecutionContext.getJobDetail().getJobDataMap().get("jobkey");
System.out.println("jobname:" + userName);
// 执行的真正业务
}
}
```
3. 编写初始化时候的JobDetail和调度器Trigger
```
@Configuration
public class QuartzConfig {
// 提前将detail信息存入数据库
@Autowired
private DetailMapper detailMapper;
// 提前将trigger信息存入数据库
@Autowired
private TriggerMapper triggerMapper;
@Bean
public void startScheduler() {
// 获取有效的job信息
List bjobs = detailMapper.selectList(new LambdaQueryWrapper<>());
for (Bjob bjob : bjobs) {
// 获取有效的trigger信息
Btrigger btrigger = triggerMapper.selectOne(new LambdaQueryWrapper().eq(Btrigger::getJobId, bjob.getJobId()));
if (btrigger != null) {
// 获取quartz的 jobDetail
JobDetail jobDetail = JobDetailFactory.getJobDetail(bjob);
// 获取quartz的 trigger
Trigger trigger = TriggerFactory.getTrigger(btrigger);
// 创建schedulerFactory工厂
StdSchedulerFactory stdSchedulerFactory = new StdSchedulerFactory();
try {
// 获取scheduler
Scheduler scheduler = stdSchedulerFactory.getScheduler();
// 写入信息
scheduler.scheduleJob(jobDetail, trigger);
// 执行job
scheduler.start();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
}
}
```
3. 编写定时任务处理器(体现了其动态性)
```
public class JobHandler {
/**
* 添加一个定时任务
*
* @param bjob
* @param btrigger
*/
public void addJob(Bjob bjob, Btrigger btrigger) {
// 获取quartz的 jobDetail
JobDetail jobDetail = JobDetailFactory.getJobDetail(bjob);
// 获取quartz的 trigger
Trigger trigger = TriggerFactory.getTrigger(btrigger);
// 创建schedulerFactory工厂
StdSchedulerFactory stdSchedulerFactory = new StdSchedulerFactory();
try {
// 获取scheduler
Scheduler scheduler = stdSchedulerFactory.getScheduler();
// 写入信息
scheduler.scheduleJob(jobDetail, trigger);
// 执行job
scheduler.start();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 停止一个定时任务
*
* @param bjob
* @param btrigger
*/
public void stopJob(Bjob bjob, Btrigger btrigger) {
// 获取quartz的 jobDetail
JobDetail jobDetail = JobDetailFactory.getJobDetail(bjob);
// 获取quartz的 trigger
Trigger trigger = TriggerFactory.getTrigger(btrigger);
// 创建schedulerFactory工厂
StdSchedulerFactory stdSchedulerFactory = new StdSchedulerFactory();
try {
// 获取scheduler
Scheduler scheduler = stdSchedulerFactory.getScheduler();
// 写入信息
scheduler.scheduleJob(jobDetail, trigger);
// 停止一个任务
scheduler.shutdown();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 删除一个定时任务
*/
public void removeJob() {
}
}
```
+ 设计技术:[@Configuration注解]()、[@Bean注解]()、[Scheduler类的常用方法]()、[CronScheduleBuilder类的方法]()、[StdSchedulerFactory类的方法]()
#### xxl-job(分布式定时任务)
+ 简介:
+ xxl-job 是大众点评(许雪里)开发的一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展
+ xxl-job 框架对 quartz 进行了扩展,使用 mysql 数据库存储数据,并且内置jetty作为 RPC服务调用
+ 特点:
1. 有界面维护定时任务和触发规则,非常容易管理
2. 能动态启动或停止任务
3. 支持弹性扩容缩容
4. 支持任务失败报警
5. 支持动态分片
6. Rolling实时日志
7. 支持用户和权限管理
+ 整体结构图:
+ quartz架构图:
+ 优点:有界面管理定时任务,支持弹性扩容缩容、动态分片、故障转移、失败报警等功能。它的功能非常强大,很多大厂在用,可以满足绝大多数业务场景
+ 缺点:和 quartz 一样,通过数据库分布式锁,来控制任务不能重复执行。在任务非常多的情况下,有一些性能问题
+ 超链接:[https://blog.csdn.net/f2315895270/article/details/104714692/]()
#### elastic-job(弹性分布式任务调度系统)
+ 简介:
+ elastic-job 是当当网开发的弹性分布式任务调度系统,功能丰富强大,采用zookeeper实现分布式协调,实现任务高可用以及分片。它是专门为高并发和复杂业务场景开发
+ elastic-job 目前是 apache 的 shardingsphere 项目下的一个子项目[官网地址](http://shardingsphere.apache.org/elasticjob/)
+ 特点:
1. 分布式调度协调
2. 弹性扩容缩容
3. 失效转移
4. 错过执行作业重触发
5. 作业分片一致性,保证同一分片在分布式环境中仅一个执行实例
6. 自诊断并修复分布式不稳定造成的问题
7. 支持并行调度
+ 架构图:
+ 优点:持分布式调度协调,支持分片,适合高并发,和一些业务相对来说较复杂的场景
+ 缺点:需要依赖于zookeeper,实现定时任务相对于 xxl-job 要复杂一些,要对分片规则非常熟悉
+ 超链接:[elastic-job](https://www.jianshu.com/p/8411504c53a3)
#### Saturn(分布式定时任务)
+ 简介:
+ Saturn是唯品会开源的一个分布式任务调度平台。取代传统的Linux Cron/Spring Batch Job的方式,做到全域统一配置,统一监控,任务高可用以及分片并发处理
+ Saturn是在当当开源的Elastic-Job基础上,结合各方需求和我们的实践见解改良而成
+ 超链接:[Saturn](https://www.jianshu.com/p/577f1b3980aa?from=singlemessage)
#### TBSchedule(分布式任务调度平台)
+ 简介:TBSchedule是阿里开发的一款分布式任务调度平台,旨在将调度作业从业务系统中分离出来,降低或者是消除和业务系统的耦合度,进行高效异步任务处理
+ gitHub地址:[TBSchedule](https://github.com/taobao/TBSchedule)
+ 超链接:[TBSchedule](https://www.cnblogs.com/zzpblogs/p/10823747.html)