传统的 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工程动态调度的实现相关推荐

  1. 第四十章:基于SpringBoot Quartz完成定时任务分布式多节点负载持久化

    在上一章[第三十九章:基于SpringBoot & Quartz完成定时任务分布式单节点持久化]中我们已经完成了任务的持久化,当我们创建一个任务时任务会被quartz定时任务框架自动持久化到数 ...

  2. springboot+Quartz整合!!!简单实用

    一.什么是Quartz 在Quartz官网上是这么写的 Quartz官网 1.Quartz 是一个完全由 Java 编写的开源作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制 ...

  3. DEA中创建父子工程与maven打包Springboot聚合工程报错程序包不存在

    DEA中创建父子工程与maven打包Springboot聚合工程报错程序包不存在 问题描述 springboot 项目打包(package)或安装到仓库(install)的时候报错:程序包com.fu ...

  4. 解决springboot + quartz的分布式问题以及dolphinscheduler

    springboot + quartz 将quartz存储默认在内存中, 多节点部署时存在分布式问题. 改成基于数据库的quartz分布式集群解决方案, 参考官方文档, 需要为quartz单独配置da ...

  5. springboot+quartz构建定时任务

    springboot+quartz构建定时任务 开发环境 Quartz的3个基本要素 如何使用 引入相关依赖 resource目录下创建quartz.properties quartz需要用到的表 实 ...

  6. SpringBoot+Quartz动态管理定时任务

    前置理论: 1.小顶堆(适合任务少的,因为向下调整耗费性能) 堆:是一完全二叉树(除了最后一层节点其他层都达到最大节点数,且最后一层都靠左排列):堆中某个节点的值总不大于或不小于其父节点. 定时任务是 ...

  7. SpringBoot+Quartz+数据库存储(附完整代码和数据库脚本)

    目录 1.pom文件依赖 2.Druid连接池的Quartz扩展类 3 .application.yml文件 4 .修改quartz.properties配置 5 . 在数据库中创建quartz相关的 ...

  8. 搭建SpringBoot脚手架工程系列(1):Spring Initializr的超能力

    前言 SpringBoot作为Java后端最主流的技术栈,是每个Java程序员必备的技能.在微服务架构流行的时代,一个普通的企业级项目通常会有5-10个微服务,业务复杂的企业级项目甚至会有20个以上的 ...

  9. 搭建SpringBoot脚手架工程系列(3): 一键启动服务

    前言 接上篇文章SpringBoot脚手架工程系列(2):代码格式化/质量审核/提交检查,赋予了脚手架工程完善的代码格式化/质量审核/提交检查能力.让我们继续来完善脚手架,提高脚手架的工程本地运行&a ...

  10. quartz工程容器启动与 Service注入

    容器启动 因为任务没有定义在 ApplicationContext.xml中,而是放到了数据库中,SpringBoot启动时,怎么读取任务信息? 或者,怎么在 Spring启动完成的时候做一些事情? ...

最新文章

  1. MySQL基本了解与使用
  2. 吴恩达深度学习(53)-Batch Norm 为什么奏效?
  3. LeetCode 626. Exchange Seats
  4. 字节流练习:图片复制
  5. 阅读一款3D引擎的方法备忘
  6. Bug之Yii继承类的
  7. 动态切换数据源(spring+hibernate)
  8. Initialization failed for Block pool
  9. 新手学习jQueryEasyUI
  10. openCVPracticalExercise学习笔记04
  11. # 20162312 2017-2018 《程序设计与数据结构》第7周学习总结
  12. 西瓜书学习笔记2-多元线性回归公式推导
  13. L298N电机驱动模块的使用
  14. 从数据库反向生成er图
  15. 最好用的七大顶级 API 接口测试工具
  16. 浏览器利用框架BeEF测试
  17. 新生报到小程序,微信小程序新生入学,微信小程序新生报到系统毕业设计作品
  18. 乐视账号服务器关闭,乐视手机账号登陆不了最新解决方法,包括恢复出厂后无法登陆问题...
  19. @PersistenceContext和@Autowired在EntityManager上应用的区别。
  20. 关于文案、营销、生活的15条思考!

热门文章

  1. 开源方案搭建可离线的精美矢量切片地图服务-3.Mapbox个性化地图定制入门
  2. velocity 的 escape实现
  3. HDU 3032 Nim or not Nim?
  4. 查询数据库中所有表的行数(sqlserver 2000)
  5. 对Coverage进行编辑
  6. Docker学习笔记_网上资源参考
  7. 结合JDK源码看设计模式——简单工厂、工厂方法、抽象工厂
  8. POJ 1904 King's Quest(强连通图)题解
  9. Nest Secure智能保全系统内建麦克风 引发用户反弹
  10. EMQ源码之--EMQ的启动