springboot-quartz工程动态调度的实现
傳統(tǒng)的 Spring方式集成,由于任務(wù)信息全部配置在 xml文件中,如果需要操作任務(wù)或者修改任務(wù)運(yùn)行頻率,只能重新編譯、打包、部署、重啟,如果有緊急問題需要處理,會浪費(fèi)很多的時(shí)間。
有沒有可以動態(tài)調(diào)度任務(wù)的方法?比如停止一個(gè) Job?啟動一個(gè) Job?修改 Job的觸發(fā)頻率?
讀取配置文件、寫入配置文件、重啟 Scheduler或重啟應(yīng)用明顯是不可取的。
對于這種頻繁變更并且需要實(shí)時(shí)生效的配置信息,我們可以放到哪里?ZK、Redis、DB tables。
并且,我們可以提供一個(gè)界面,實(shí)現(xiàn)對數(shù)據(jù)表的輕松操作。?
配置管理
這里我們用最簡單的數(shù)據(jù)庫的實(shí)現(xiàn)。
問題?
1:建一張什么樣的表?參考 JobDetail的屬性。?
數(shù)據(jù)操作與任務(wù)調(diào)度
操作數(shù)據(jù)表非常簡單,SSM增刪改查。
但是在修改了表的數(shù)據(jù)之后,怎么讓調(diào)度器知道呢?
調(diào)度器的接口:Scheduler
在我們的需求中,我們需要做的事情:
1、新增一個(gè)任務(wù)
2、刪除一個(gè)任務(wù)
3、啟動、停止一個(gè)任務(wù)
4、修改任務(wù)的信息(包括調(diào)度規(guī)律)
因此可以把相關(guān)的操作封裝到一個(gè)工具類中。
public class SchedulerUtil {private static Logger logger = LoggerFactory.getLogger(SchedulerUtil.class);/*** 新增定時(shí)任務(wù)* @param jobClassName 類路徑* @param jobName 任務(wù)名稱* @param jobGroupName 組別* @param cronExpression Cron表達(dá)式* @param jobDataMap 需要傳遞的參數(shù)* @throws Exception*/public static void addJob(String jobClassName,String jobName, String jobGroupName, String cronExpression,String jobDataMap) throws Exception {// 通過SchedulerFactory獲取一個(gè)調(diào)度器實(shí)例SchedulerFactory sf = new StdSchedulerFactory();Scheduler scheduler = sf.getScheduler();// 啟動調(diào)度器scheduler.start();// 構(gòu)建job信息JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass()).withIdentity(jobName, jobGroupName).build();// JobDataMap用于傳遞任務(wù)運(yùn)行時(shí)的參數(shù),比如定時(shí)發(fā)送郵件,可以用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());}}// 表達(dá)式調(diào)度構(gòu)建器(即任務(wù)執(zhí)行的時(shí)間)CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);// 按新的cronExpression表達(dá)式構(gòu)建一個(gè)新的triggerCronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName).withSchedule(scheduleBuilder).startNow().build();try {scheduler.scheduleJob(jobDetail, trigger);} catch (SchedulerException e) {logger.info("創(chuàng)建定時(shí)任務(wù)失敗" + e);throw new Exception("創(chuàng)建定時(shí)任務(wù)失敗");}}/*** 停用一個(gè)定時(shí)任務(wù)* @param jobName 任務(wù)名稱* @param jobGroupName 組別* @throws Exception*/public static void jobPause(String jobName, String jobGroupName) throws Exception {// 通過SchedulerFactory獲取一個(gè)調(diào)度器實(shí)例SchedulerFactory sf = new StdSchedulerFactory();Scheduler scheduler = sf.getScheduler();scheduler.pauseJob(JobKey.jobKey(jobName, jobGroupName));}/*** 啟用一個(gè)定時(shí)任務(wù)* @param jobName 任務(wù)名稱* @param jobGroupName 組別* @throws Exception*/public static void jobresume(String jobName, String jobGroupName) throws Exception {// 通過SchedulerFactory獲取一個(gè)調(diào)度器實(shí)例SchedulerFactory sf = new StdSchedulerFactory();Scheduler scheduler = sf.getScheduler();scheduler.resumeJob(JobKey.jobKey(jobName, jobGroupName));}/*** 刪除一個(gè)定時(shí)任務(wù)* @param jobName 任務(wù)名稱* @param jobGroupName 組別* @throws Exception*/public static void jobdelete(String jobName, String jobGroupName) throws Exception {// 通過SchedulerFactory獲取一個(gè)調(diào)度器實(shí)例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));}/*** 更新定時(shí)任務(wù)表達(dá)式* @param jobName 任務(wù)名稱* @param jobGroupName 組別* @param cronExpression Cron表達(dá)式* @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);// 表達(dá)式調(diào)度構(gòu)建器CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);// 按新的cronExpression表達(dá)式重新構(gòu)建triggertrigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).startNow().build();// 按新的trigger重新設(shè)置job執(zhí)行scheduler.rescheduleJob(triggerKey, trigger);} catch (SchedulerException e) {System.out.println("更新定時(shí)任務(wù)失敗" + e);throw new Exception("更新定時(shí)任務(wù)失敗");}}/*** 檢查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;}/*** 暫停所有任務(wù)* @throws Exception*/public static void pauseAlljob() throws Exception {SchedulerFactory sf = new StdSchedulerFactory();Scheduler scheduler = sf.getScheduler();scheduler.pauseAll();}/*** 喚醒所有任務(wù)* @throws Exception*/public static void resumeAlljob() throws Exception {SchedulerFactory sf = new StdSchedulerFactory();Scheduler sched = sf.getScheduler();sched.resumeAll();}/*** 獲取Job實(shí)例* @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+"]不存在!");}}}?
總結(jié)
以上是生活随笔為你收集整理的springboot-quartz工程动态调度的实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Quartz集成到 Spring
- 下一篇: quartz工程容器启动与 Servic