springboot-quartz工程动态调度的实现
传统的 Spring方式集成,由于任务信息全部配置在 xml文件中,如果需要操作任务或者修改任务运行频率,只能重新编译、打包、部署、重启,如果有紧急问题需要处理,会浪费很多的时间。
有没有可以动态调度任务的方法?比如停止一个 Job?启动一个 Job?修改 Job的触发频率?
读取配置文件、写入配置文件、重启 Scheduler或重启应用明显是不可取的。
对于这种频繁变更并且需要实时生效的配置信息,我们可以放到哪里?ZK、Redis、DB tables。
并且,我们可以提供一个界面,实现对数据表的轻松操作。
配置管理
这里我们用最简单的数据库的实现。
问题
1:建一张什么样的表?参考 JobDetail的属性。
CREATE TABLE `sys_job` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID', `job_name` varchar(512) NOT NULL COMMENT '任务名称 ', `job_group` varchar(512) NOT NULL COMMENT '任务组名 ', `job_cron` varchar(512) NOT NULL COMMENT '时间表达式 ', `job_class_path` varchar(1024) NOT NULL COMMENT '类路径 ,全类型 ', `job_data_map` varchar(1024) DEFAULT NULL COMMENT '传递 map参数 ', `job_status` int(2) NOT NULL COMMENT '状态 :1启用 0停用 ', `job_describe` varchar(1024) DEFAULT NULL COMMENT '任务功能描述 ', PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=utf8;
数据操作与任务调度
操作数据表非常简单,SSM增删改查。
但是在修改了表的数据之后,怎么让调度器知道呢?
调度器的接口:Scheduler
在我们的需求中,我们需要做的事情:
1、新增一个任务
2、删除一个任务
3、启动、停止一个任务
4、修改任务的信息(包括调度规律)
因此可以把相关的操作封装到一个工具类中。
public class SchedulerUtil {private static Logger logger = LoggerFactory.getLogger(SchedulerUtil.class);/*** 新增定时任务* @param jobClassName 类路径* @param jobName 任务名称* @param jobGroupName 组别* @param cronExpression Cron表达式* @param jobDataMap 需要传递的参数* @throws Exception*/public static void addJob(String jobClassName,String jobName, String jobGroupName, String cronExpression,String jobDataMap) throws Exception {// 通过SchedulerFactory获取一个调度器实例SchedulerFactory sf = new StdSchedulerFactory();Scheduler scheduler = sf.getScheduler();// 启动调度器scheduler.start();// 构建job信息JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass()).withIdentity(jobName, jobGroupName).build();// JobDataMap用于传递任务运行时的参数,比如定时发送邮件,可以用json形式存储收件人等等信息if (StringUtils.isNotEmpty(jobDataMap)) {JSONObject jb = JSONObject.parseObject(jobDataMap);Map<String, Object> dataMap =(Map<String, Object>) jb.get("data");for (Map.Entry<String, Object> m:dataMap.entrySet()) {jobDetail.getJobDataMap().put(m.getKey(),m.getValue());}}// 表达式调度构建器(即任务执行的时间)CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);// 按新的cronExpression表达式构建一个新的triggerCronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName).withSchedule(scheduleBuilder).startNow().build();try {scheduler.scheduleJob(jobDetail, trigger);} catch (SchedulerException e) {logger.info("创建定时任务失败" + e);throw new Exception("创建定时任务失败");}}/*** 停用一个定时任务* @param jobName 任务名称* @param jobGroupName 组别* @throws Exception*/public static void jobPause(String jobName, String jobGroupName) throws Exception {// 通过SchedulerFactory获取一个调度器实例SchedulerFactory sf = new StdSchedulerFactory();Scheduler scheduler = sf.getScheduler();scheduler.pauseJob(JobKey.jobKey(jobName, jobGroupName));}/*** 启用一个定时任务* @param jobName 任务名称* @param jobGroupName 组别* @throws Exception*/public static void jobresume(String jobName, String jobGroupName) throws Exception {// 通过SchedulerFactory获取一个调度器实例SchedulerFactory sf = new StdSchedulerFactory();Scheduler scheduler = sf.getScheduler();scheduler.resumeJob(JobKey.jobKey(jobName, jobGroupName));}/*** 删除一个定时任务* @param jobName 任务名称* @param jobGroupName 组别* @throws Exception*/public static void jobdelete(String jobName, String jobGroupName) throws Exception {// 通过SchedulerFactory获取一个调度器实例SchedulerFactory sf = new StdSchedulerFactory();Scheduler scheduler = sf.getScheduler();scheduler.pauseTrigger(TriggerKey.triggerKey(jobName, jobGroupName));scheduler.unscheduleJob(TriggerKey.triggerKey(jobName, jobGroupName));scheduler.deleteJob(JobKey.jobKey(jobName, jobGroupName));}/*** 更新定时任务表达式* @param jobName 任务名称* @param jobGroupName 组别* @param cronExpression Cron表达式* @throws Exception*/public static void jobReschedule(String jobName, String jobGroupName, String cronExpression) throws Exception {try {SchedulerFactory schedulerFactory = new StdSchedulerFactory();Scheduler scheduler = schedulerFactory.getScheduler();TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);// 表达式调度构建器CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);// 按新的cronExpression表达式重新构建triggertrigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).startNow().build();// 按新的trigger重新设置job执行scheduler.rescheduleJob(triggerKey, trigger);} catch (SchedulerException e) {System.out.println("更新定时任务失败" + e);throw new Exception("更新定时任务失败");}}/*** 检查Job是否存在* @throws Exception*/public static Boolean isResume(String jobName, String jobGroupName) throws Exception {SchedulerFactory sf = new StdSchedulerFactory();Scheduler scheduler = sf.getScheduler();TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);Boolean state = scheduler.checkExists(triggerKey);return state;}/*** 暂停所有任务* @throws Exception*/public static void pauseAlljob() throws Exception {SchedulerFactory sf = new StdSchedulerFactory();Scheduler scheduler = sf.getScheduler();scheduler.pauseAll();}/*** 唤醒所有任务* @throws Exception*/public static void resumeAlljob() throws Exception {SchedulerFactory sf = new StdSchedulerFactory();Scheduler sched = sf.getScheduler();sched.resumeAll();}/*** 获取Job实例* @param classname* @return* @throws Exception*/public static BaseJob getClass(String classname) throws Exception {try {Class<?> c = Class.forName(classname);return (BaseJob) c.newInstance();} catch (Exception e) {throw new Exception("类["+classname+"]不存在!");}}}
springboot-quartz工程动态调度的实现相关推荐
- 第四十章:基于SpringBoot Quartz完成定时任务分布式多节点负载持久化
在上一章[第三十九章:基于SpringBoot & Quartz完成定时任务分布式单节点持久化]中我们已经完成了任务的持久化,当我们创建一个任务时任务会被quartz定时任务框架自动持久化到数 ...
- springboot+Quartz整合!!!简单实用
一.什么是Quartz 在Quartz官网上是这么写的 Quartz官网 1.Quartz 是一个完全由 Java 编写的开源作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制 ...
- DEA中创建父子工程与maven打包Springboot聚合工程报错程序包不存在
DEA中创建父子工程与maven打包Springboot聚合工程报错程序包不存在 问题描述 springboot 项目打包(package)或安装到仓库(install)的时候报错:程序包com.fu ...
- 解决springboot + quartz的分布式问题以及dolphinscheduler
springboot + quartz 将quartz存储默认在内存中, 多节点部署时存在分布式问题. 改成基于数据库的quartz分布式集群解决方案, 参考官方文档, 需要为quartz单独配置da ...
- springboot+quartz构建定时任务
springboot+quartz构建定时任务 开发环境 Quartz的3个基本要素 如何使用 引入相关依赖 resource目录下创建quartz.properties quartz需要用到的表 实 ...
- SpringBoot+Quartz动态管理定时任务
前置理论: 1.小顶堆(适合任务少的,因为向下调整耗费性能) 堆:是一完全二叉树(除了最后一层节点其他层都达到最大节点数,且最后一层都靠左排列):堆中某个节点的值总不大于或不小于其父节点. 定时任务是 ...
- SpringBoot+Quartz+数据库存储(附完整代码和数据库脚本)
目录 1.pom文件依赖 2.Druid连接池的Quartz扩展类 3 .application.yml文件 4 .修改quartz.properties配置 5 . 在数据库中创建quartz相关的 ...
- 搭建SpringBoot脚手架工程系列(1):Spring Initializr的超能力
前言 SpringBoot作为Java后端最主流的技术栈,是每个Java程序员必备的技能.在微服务架构流行的时代,一个普通的企业级项目通常会有5-10个微服务,业务复杂的企业级项目甚至会有20个以上的 ...
- 搭建SpringBoot脚手架工程系列(3): 一键启动服务
前言 接上篇文章SpringBoot脚手架工程系列(2):代码格式化/质量审核/提交检查,赋予了脚手架工程完善的代码格式化/质量审核/提交检查能力.让我们继续来完善脚手架,提高脚手架的工程本地运行&a ...
- quartz工程容器启动与 Service注入
容器启动 因为任务没有定义在 ApplicationContext.xml中,而是放到了数据库中,SpringBoot启动时,怎么读取任务信息? 或者,怎么在 Spring启动完成的时候做一些事情? ...
最新文章
- MySQL基本了解与使用
- 吴恩达深度学习(53)-Batch Norm 为什么奏效?
- LeetCode 626. Exchange Seats
- 字节流练习:图片复制
- 阅读一款3D引擎的方法备忘
- Bug之Yii继承类的
- 动态切换数据源(spring+hibernate)
- Initialization failed for Block pool
- 新手学习jQueryEasyUI
- openCVPracticalExercise学习笔记04
- # 20162312 2017-2018 《程序设计与数据结构》第7周学习总结
- 西瓜书学习笔记2-多元线性回归公式推导
- L298N电机驱动模块的使用
- 从数据库反向生成er图
- 最好用的七大顶级 API 接口测试工具
- 浏览器利用框架BeEF测试
- 新生报到小程序,微信小程序新生入学,微信小程序新生报到系统毕业设计作品
- 乐视账号服务器关闭,乐视手机账号登陆不了最新解决方法,包括恢复出厂后无法登陆问题...
- @PersistenceContext和@Autowired在EntityManager上应用的区别。
- 关于文案、营销、生活的15条思考!