700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Spring boot与Quartz实现任务定时提醒

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

时间:2023-08-30 10:15:18

相关推荐

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核心概念的关系如图:

(来源: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 {

@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的集群配置更加复杂以下,如果对它感兴趣,可以移步/@Hronom/spring-boot-quartz-scheduler-in-cluster-mode-457f4535104d,Quartz的更多特性等着你探索!

附录代码:

/*Navicat MySQL Data TransferSource Server : localSource Server Version : 50505Source Host : localhost:3306Source Database : quartzTarget Server Type : MYSQLTarget Server Version : 50505File Encoding : 65001Date: -11-05 18:01:51*/SET FOREIGN_KEY_CHECKS=0;-- ------------------------------ Table structure for basic_good_info-- ----------------------------DROP TABLE IF EXISTS `basic_good_info`;CREATE TABLE `basic_good_info` (`BGI_ID` int(11) NOT NULL AUTO_INCREMENT COMMENT '商品编号',`BGI_NAME` varchar(20) DEFAULT NULL COMMENT '商品名称',`BGI_PRICE` decimal(8,2) DEFAULT NULL COMMENT '单价',`BGI_UNIT` varchar(10) DEFAULT NULL COMMENT '单位',PRIMARY KEY (`BGI_ID`)) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 COMMENT='商品基本信息';-- ------------------------------ Table structure for qrtz_blob_triggers-- ----------------------------DROP TABLE IF EXISTS `qrtz_blob_triggers`;CREATE TABLE `qrtz_blob_triggers` (`SCHED_NAME` varchar(120) NOT NULL,`TRIGGER_NAME` varchar(200) NOT NULL,`TRIGGER_GROUP` varchar(200) NOT NULL,`BLOB_DATA` blob DEFAULT NULL,PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),KEY `SCHED_NAME` (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),CONSTRAINT `qrtz_blob_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `qrtz_triggers` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ------------------------------ Table structure for qrtz_calendars-- ----------------------------DROP TABLE IF EXISTS `qrtz_calendars`;CREATE TABLE `qrtz_calendars` (`SCHED_NAME` varchar(120) NOT NULL,`CALENDAR_NAME` varchar(200) NOT NULL,`CALENDAR` blob NOT NULL,PRIMARY KEY (`SCHED_NAME`,`CALENDAR_NAME`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ------------------------------ Table structure for qrtz_cron_triggers-- ----------------------------DROP TABLE IF EXISTS `qrtz_cron_triggers`;CREATE TABLE `qrtz_cron_triggers` (`SCHED_NAME` varchar(120) NOT NULL,`TRIGGER_NAME` varchar(200) NOT NULL,`TRIGGER_GROUP` varchar(200) NOT NULL,`CRON_EXPRESSION` varchar(120) NOT NULL,`TIME_ZONE_ID` varchar(80) DEFAULT NULL,PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),CONSTRAINT `qrtz_cron_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `qrtz_triggers` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ------------------------------ Table structure for qrtz_fired_triggers-- ----------------------------DROP TABLE IF EXISTS `qrtz_fired_triggers`;CREATE TABLE `qrtz_fired_triggers` (`SCHED_NAME` varchar(120) NOT NULL,`ENTRY_ID` varchar(95) NOT NULL,`TRIGGER_NAME` varchar(200) NOT NULL,`TRIGGER_GROUP` varchar(200) NOT NULL,`INSTANCE_NAME` varchar(200) NOT NULL,`FIRED_TIME` bigint(13) NOT NULL,`SCHED_TIME` bigint(13) NOT NULL,`PRIORITY` int(11) NOT NULL,`STATE` varchar(16) NOT NULL,`JOB_NAME` varchar(200) DEFAULT NULL,`JOB_GROUP` varchar(200) DEFAULT NULL,`IS_NONCONCURRENT` varchar(1) DEFAULT NULL,`REQUESTS_RECOVERY` varchar(1) DEFAULT NULL,PRIMARY KEY (`SCHED_NAME`,`ENTRY_ID`),KEY `IDX_QRTZ_FT_TRIG_INST_NAME` (`SCHED_NAME`,`INSTANCE_NAME`),KEY `IDX_QRTZ_FT_INST_JOB_REQ_RCVRY` (`SCHED_NAME`,`INSTANCE_NAME`,`REQUESTS_RECOVERY`),KEY `IDX_QRTZ_FT_J_G` (`SCHED_NAME`,`JOB_NAME`,`JOB_GROUP`),KEY `IDX_QRTZ_FT_JG` (`SCHED_NAME`,`JOB_GROUP`),KEY `IDX_QRTZ_FT_T_G` (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),KEY `IDX_QRTZ_FT_TG` (`SCHED_NAME`,`TRIGGER_GROUP`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ------------------------------ Table structure for qrtz_job_details-- ----------------------------DROP TABLE IF EXISTS `qrtz_job_details`;CREATE TABLE `qrtz_job_details` (`SCHED_NAME` varchar(120) NOT NULL,`JOB_NAME` varchar(200) NOT NULL,`JOB_GROUP` varchar(200) NOT NULL,`DESCRIPTION` varchar(250) DEFAULT NULL,`JOB_CLASS_NAME` varchar(250) NOT NULL,`IS_DURABLE` varchar(1) NOT NULL,`IS_NONCONCURRENT` varchar(1) NOT NULL,`IS_UPDATE_DATA` varchar(1) NOT NULL,`REQUESTS_RECOVERY` varchar(1) NOT NULL,`JOB_DATA` blob DEFAULT NULL,PRIMARY KEY (`SCHED_NAME`,`JOB_NAME`,`JOB_GROUP`),KEY `IDX_QRTZ_J_REQ_RECOVERY` (`SCHED_NAME`,`REQUESTS_RECOVERY`),KEY `IDX_QRTZ_J_GRP` (`SCHED_NAME`,`JOB_GROUP`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ------------------------------ Table structure for qrtz_locks-- ----------------------------DROP TABLE IF EXISTS `qrtz_locks`;CREATE TABLE `qrtz_locks` (`SCHED_NAME` varchar(120) NOT NULL,`LOCK_NAME` varchar(40) NOT NULL,PRIMARY KEY (`SCHED_NAME`,`LOCK_NAME`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ------------------------------ Table structure for qrtz_paused_trigger_grps-- ----------------------------DROP TABLE IF EXISTS `qrtz_paused_trigger_grps`;CREATE TABLE `qrtz_paused_trigger_grps` (`SCHED_NAME` varchar(120) NOT NULL,`TRIGGER_GROUP` varchar(200) NOT NULL,PRIMARY KEY (`SCHED_NAME`,`TRIGGER_GROUP`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ------------------------------ Table structure for qrtz_scheduler_state-- ----------------------------DROP TABLE IF EXISTS `qrtz_scheduler_state`;CREATE TABLE `qrtz_scheduler_state` (`SCHED_NAME` varchar(120) NOT NULL,`INSTANCE_NAME` varchar(200) NOT NULL,`LAST_CHECKIN_TIME` bigint(13) NOT NULL,`CHECKIN_INTERVAL` bigint(13) NOT NULL,PRIMARY KEY (`SCHED_NAME`,`INSTANCE_NAME`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ------------------------------ Table structure for qrtz_simple_triggers-- ----------------------------DROP TABLE IF EXISTS `qrtz_simple_triggers`;CREATE TABLE `qrtz_simple_triggers` (`SCHED_NAME` varchar(120) NOT NULL,`TRIGGER_NAME` varchar(200) NOT NULL,`TRIGGER_GROUP` varchar(200) NOT NULL,`REPEAT_COUNT` bigint(7) NOT NULL,`REPEAT_INTERVAL` bigint(12) NOT NULL,`TIMES_TRIGGERED` bigint(10) NOT NULL,PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),CONSTRAINT `qrtz_simple_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `qrtz_triggers` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ------------------------------ Table structure for qrtz_simprop_triggers-- ----------------------------DROP TABLE IF EXISTS `qrtz_simprop_triggers`;CREATE TABLE `qrtz_simprop_triggers` (`SCHED_NAME` varchar(120) NOT NULL,`TRIGGER_NAME` varchar(200) NOT NULL,`TRIGGER_GROUP` varchar(200) NOT NULL,`STR_PROP_1` varchar(512) DEFAULT NULL,`STR_PROP_2` varchar(512) DEFAULT NULL,`STR_PROP_3` varchar(512) DEFAULT NULL,`INT_PROP_1` int(11) DEFAULT NULL,`INT_PROP_2` int(11) DEFAULT NULL,`LONG_PROP_1` bigint(20) DEFAULT NULL,`LONG_PROP_2` bigint(20) DEFAULT NULL,`DEC_PROP_1` decimal(13,4) DEFAULT NULL,`DEC_PROP_2` decimal(13,4) DEFAULT NULL,`BOOL_PROP_1` varchar(1) DEFAULT NULL,`BOOL_PROP_2` varchar(1) DEFAULT NULL,PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),CONSTRAINT `qrtz_simprop_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `qrtz_triggers` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ------------------------------ Table structure for qrtz_triggers-- ----------------------------DROP TABLE IF EXISTS `qrtz_triggers`;CREATE TABLE `qrtz_triggers` (`SCHED_NAME` varchar(120) NOT NULL,`TRIGGER_NAME` varchar(200) NOT NULL,`TRIGGER_GROUP` varchar(200) NOT NULL,`JOB_NAME` varchar(200) NOT NULL,`JOB_GROUP` varchar(200) NOT NULL,`DESCRIPTION` varchar(250) DEFAULT NULL,`NEXT_FIRE_TIME` bigint(13) DEFAULT NULL,`PREV_FIRE_TIME` bigint(13) DEFAULT NULL,`PRIORITY` int(11) DEFAULT NULL,`TRIGGER_STATE` varchar(16) NOT NULL,`TRIGGER_TYPE` varchar(8) NOT NULL,`START_TIME` bigint(13) NOT NULL,`END_TIME` bigint(13) DEFAULT NULL,`CALENDAR_NAME` varchar(200) DEFAULT NULL,`MISFIRE_INSTR` smallint(2) DEFAULT NULL,`JOB_DATA` blob DEFAULT NULL,PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),KEY `IDX_QRTZ_T_J` (`SCHED_NAME`,`JOB_NAME`,`JOB_GROUP`),KEY `IDX_QRTZ_T_JG` (`SCHED_NAME`,`JOB_GROUP`),KEY `IDX_QRTZ_T_C` (`SCHED_NAME`,`CALENDAR_NAME`),KEY `IDX_QRTZ_T_G` (`SCHED_NAME`,`TRIGGER_GROUP`),KEY `IDX_QRTZ_T_STATE` (`SCHED_NAME`,`TRIGGER_STATE`),KEY `IDX_QRTZ_T_N_STATE` (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`,`TRIGGER_STATE`),KEY `IDX_QRTZ_T_N_G_STATE` (`SCHED_NAME`,`TRIGGER_GROUP`,`TRIGGER_STATE`),KEY `IDX_QRTZ_T_NEXT_FIRE_TIME` (`SCHED_NAME`,`NEXT_FIRE_TIME`),KEY `IDX_QRTZ_T_NFT_ST` (`SCHED_NAME`,`TRIGGER_STATE`,`NEXT_FIRE_TIME`),KEY `IDX_QRTZ_T_NFT_MISFIRE` (`SCHED_NAME`,`MISFIRE_INSTR`,`NEXT_FIRE_TIME`),KEY `IDX_QRTZ_T_NFT_ST_MISFIRE` (`SCHED_NAME`,`MISFIRE_INSTR`,`NEXT_FIRE_TIME`,`TRIGGER_STATE`),KEY `IDX_QRTZ_T_NFT_ST_MISFIRE_GRP` (`SCHED_NAME`,`MISFIRE_INSTR`,`NEXT_FIRE_TIME`,`TRIGGER_GROUP`,`TRIGGER_STATE`),CONSTRAINT `qrtz_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`) REFERENCES `qrtz_job_details` (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。