# 定时任务的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开发的一个开源的任务日程管理系统 + 图示:![输入图片说明](https://images.gitee.com/uploads/images/2021/0428/170222_bbe251a9_1942182.png "屏幕截图.png") + 名词示意: + 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. 支持用户和权限管理 + 整体结构图:![输入图片说明](https://images.gitee.com/uploads/images/2021/0428/170247_bb8f92d3_1942182.png "屏幕截图.png") + quartz架构图:![输入图片说明](https://images.gitee.com/uploads/images/2021/0428/170256_3fe4eccc_1942182.png "屏幕截图.png") + 优点:有界面管理定时任务,支持弹性扩容缩容、动态分片、故障转移、失败报警等功能。它的功能非常强大,很多大厂在用,可以满足绝大多数业务场景 + 缺点:和 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. 支持并行调度 + 架构图:![输入图片说明](https://images.gitee.com/uploads/images/2021/0428/170308_3c8aff90_1942182.png "屏幕截图.png") + 优点:持分布式调度协调,支持分片,适合高并发,和一些业务相对来说较复杂的场景 + 缺点:需要依赖于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)