Spring boot与Quartz实现任务定时提醒

我们的产品是一款无代码业务流程搭建工具(产品名称轻流),我们的客户经常提出来这样的需求:

“我们要做个进度把控,给每个审核节点加上时间限定,因为如果一个节点上的任务长时间不处理,那就超时啦!”

“任务的时间限定是个比较重要的东西,你们轻流能不能做一个功能,当任务快到时间限定的时候,提醒一下该任务的负责人?”

......

可见,任务的时效性是一个非常重要的东西,我们应该如何实现“到了某个时间节点就去提醒别人”这个目标呢?

我们知道,Spring Boot是自带有调度功能的,可以用@Schedule注解实现定时任务,但是这种方法只能实现固定的时间调度。而用户需要的是可以自定义定时任务的启动时间。重要的是,如果系统重启了,那么原来内存中的定时任务就会被释放!这是一个严重的问题。

这个时候,Quartz这个工具就派上用场了。

Quartz是一个不错的开源调度框架(感谢开源组织的贡献),具有很多优点,例如:

(1)功能强大,支持丰富的调度方法,并且支持成千上万定时任务同时调度;

(2)支持任务的持续,不用担心系统在重启之后,“忘记”之前的调度任务;

(3)支持分布式,你可以设置多个executor来执行调度任务,实现负载平衡和提升可靠性(Linkin的开源调度工具Azkaban就是基于quartz实现的)。

Quartz核心概念

Quartz有几个核心概念,分别是:

Scheduler:任务调度器

Trigger:触发器,它定义了调度的时间规则

Job:任务,即被调度器调度的任务

Key:包括name(名字)和group(分组),我们将trigger和job注册到scheduler时,需要给它们赋上key。

Quartz核心概念的关系如图:

Spring boot与Quartz实现任务定时提醒

(来源:IBM)

组件的工作过程:

(1)使用SchedulerFactory创建Scheduler实例

SchedulerFactory factory = new SchedulerFactory();
Scheduler scheduler = factory.getScheduler();
(2)创建一个任务

JobDetail job = JobBuilder.newJob(CustomJob.class).withIndentity("myJob", "myGroup").build();
CustomJob是一个自定义的定时任务类。

(3)创建一个触发器,指定任务在什么时间执行

Trigger trigger = TriggerBuilder.newTrigger.withIndentity("myTrigger", "myGroup")
.startAt(targerDate).build()
其中,TargetDate是一个java.util.Date类型,用于指定任务在什么时候执行。

(4)注册任务到调度器

scheduler.scheduleJob(job, trigger)
把任务调度上去之后,任务就会在指定的时间执行啦。

在Spring Boot中使用

前面我们只是介绍了Quartz基本工作流程,那么如何在Spring Boot中使用呢?如何把定时任务持续化呢?

在Spring Boot 2.0版本中,已经集成了Quartz 2.3.0版本,Spring Boot已经能够对Quartz进行自动化的配置,省去了很多人工操作,减轻了程序员的开发压力

(1)在已有的Spring Boot项目中的Gradle文件中引入quartz-starter依赖

compile('org.springframework.boot:spring-boot-starter-quartz')
(2)在项目对应的数据源mysql中指定quartz的sql语句,创建所需要的表(代码见文末)

(3)在application.properties里添加quartz的配置

spring.quartz.job-store-type=jdbc
spring.quartz.jdbc.initialize-schema=never
除此之外,不要我们写入其它的配置,Spring Boot会自动为我们配置好。

这样配置之后,所有的quartz任务会自动持续化到mysql中,不会丢失。

(4)在代码中进行任务调度

// 在需要使用Scheduler的地方直接注入Scheduler,Spring Boot已经配置好了

Scheduler实例

@Autowire
private Scheduler scheduler;
// 任务调度
String jobKey = UUID.randomUUID().toString();
String triggerKey = UUID.randomUUID().toString();
JobDetail jobDetail = JobBuilder.newJob(CustomNotifyTask.class)
.withIdentity(jobKey, CustomTask.class.getName())
.build();
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity(triggerKey, CustomTask.class.getName())
.startAt(targetDate).build();
// 启动调度
scheduler.scheduleJob(jobDetail, trigger);
CustomTask是一个任务类,它继承了QuartzJobBean并且实现了其executeInternal接口。

public class CustomTask extends QuartzJobBean {br/>@Override
protected void executeInternal(JobExecutionContext context) {
System.out.println("hello world");
}
}
至此,我们展示了一个单节点持续化的Quartz调度器的使用。

Bonus:向定时任务传递参数
一般来说,定时任务是需要接收参数的,这样才能实现丰富的功能。比如,我们要在定时任务中向自定义的邮箱发送邮件,那么邮件地址是可以通过参数传递进去的。

在Quartz框架中,向定时任务传递参数也是非常方便的。

在调度任务时,传递参数myNumber。

JobDetail jobDetail = JobBuilder.newJob(CustomNotifyTask.class)
.withIdentity(jobKey, CustomTask.class.getName())
.usingJobData("mynum", myNumber)
.usingJobData("email", email)
.build();
在执行任务时,获取参数myNumber。

@Override
protected void executeInternal(JobExecutionContext context) {
JobDataMap dataMap = context.getJobDetail().getJobDataMap();
Integer applyId = dataMap.getInt("mynum");
String email = dataMap.getInt("email");
// .......
}

扩展:Quartz集群

虽然单个的Quartz调度实例(单机版)可以让我们很好的进行任务的调度,但是无法满足日益复杂的企业应用的要求,比如可靠性,可用性和扩展性。如果我们调度的任务多,那么Quartz集群就是要考虑的。当一个Quartz实例崩溃的时候,集群里的另外一个实例可以快速地接替它的工作,确保Job的执行。

Quartz的集群配置更加复杂以下,如果对它感兴趣,可以移步https://medium.com/@Hronom/spring-boot-quartz-scheduler-in-cluster-mode-457f4535104d,Quartz的更多特性等着你探索!

Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标准的Java组件或 EJBs。 Quartz的优势: 1、Quartz是一个任务调度框架(库),它几乎可以集成到任何应用系统中。 2、Quartz是非常灵活的,它让您能够以最“自然”的方式来编写您的项目的代码,实现您所期望的行为 3、Quartz是非常轻量级的,只需要非常少的配置 —— 它实际上可以被跳出框架来使用,如果你的需求是一些相对基本的简单的需求的话。 4、Quartz具有容错机制,并且可以在重启服务的时候持久化(”记忆”)你的定时任务,你的任务也不会丢失。 5、可以通过Quartz,封装成自己的分布式任务调度,实现强大的功能,成为自己的产品。6、有很多的互联网公司也都在使用Quartz。比如美团 Spring是一个很优秀的框架,它无缝的集成了Quartz,简单方便的让企业级应用更好的使用Quartz进行任务的调度。   课程说明:在我们的日常开发中,各种大型系统的开发少不了任务调度,简单的单机任务调度已经满足不了我们的系统需求,复杂的任务会让程序猿头疼, 所以急需一套专门的框架帮助我们去管理定时任务,并且可以在多台机器去执行我们的任务,还要可以管理我们的分布式定时任务。本课程从Quartz框架讲起,由浅到深,从使用到结构分析,再到源码分析,深入解析QuartzSpring+Quartz,并且会讲解相关原理, 让大家充分的理解这个框架和框架的设计思想。由于互联网的复杂性,为了满足我们特定的需求,需要对Spring+Quartz进行二次开发,整个二次开发过程都会进行讲解。Spring被用在了越来越多的项目中, Quartz也被公认为是比较好用的定时器设置工具,学完这个课程后,不仅仅可以熟练掌握分布式定时任务,还可以深入理解大型框架的设计思想。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值