基於Quartz的定時任務專案解析
阿新 • • 發佈:2019-01-07
準備寫一下quartz的使用流程、注意事項和原理,畢竟用了很久了,不總結就沒有提高。
用兩天時間建立一個quartz的專案,並根據專案做一下總結,並上傳專案原始碼供大家參考。
quartz的官網地址:http://www.quartz-scheduler.org/
API地址:http://www.quartz-scheduler.org/api/2.2.1/index.html
關於Quartz的介紹 和詳解可以看我的上一篇轉載的部落格,裡面介紹的非常詳細也非常清楚。https://mp.csdn.net/postedit/85157905
我們這篇就只講專案,專案上傳地址:https://github.com/tiedungao/quartz
專案的程式碼結構如下:
使用了:Spring Boot+mySql,相應的介面已經實現並通過了單元測試。本來想把前段配置和管理頁面也寫出來的,發現憑藉自己的前端知識去寫,畫出來的好醜,哈哈,希望前端好的同學能在github上完善完善。
我們下面簡單看一下截至當前時間的程式碼:
主要看service的程式碼。
package com.spring.quartz.service.impl; import com.spring.quartz.service.QuartzService; import com.spring.quartz.utils.SchedulerUtils; import org.quartz.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import static org.quartz.CronScheduleBuilder.cronSchedule; import static org.quartz.JobBuilder.newJob; import static org.quartz.TriggerBuilder.newTrigger; /** * @Author: 高鐵墩 * @Description: * @Date: Create in 17:50 2018/12/23 */ @Service public class QuartzServiceImpl implements QuartzService { private static final Logger log = LoggerFactory.getLogger(QuartzServiceImpl.class); //預設任務組名稱 public static final String DEFAULT_JOB_GROUP_NAME = "defaultJobGroup"; //預設觸發器組名稱 public static final String DEFAULT_TRIGGER_GROUP_NAME = "defaultTriggerGroup"; private static Scheduler scheduler = SchedulerUtils.getScheduler(); public void addJob(String jobName, Class<? extends Job> cls, String cronExpression){ //定義JobDetail JobDetail jobDetail = newJob(cls).requestRecovery(true) .withIdentity(jobName,DEFAULT_JOB_GROUP_NAME) .build(); //定義Trigger Trigger cronTrigger = newTrigger().withIdentity(jobName+"Trigger",DEFAULT_TRIGGER_GROUP_NAME) .startNow() .withSchedule(cronSchedule(cronExpression) .withMisfireHandlingInstructionFireAndProceed()) .forJob(jobDetail) .build(); try { //根據jobDetail和cronTrigger建立任務 scheduler.scheduleJob(jobDetail,cronTrigger); } catch (SchedulerException e) { e.printStackTrace(); log.info("執行方法-addJob-時發生異常,異常資訊為:"+e.getMessage()); } } public void addJobAndData(String jobName,Class<? extends Job> cls,String cronExpression, JobDataMap jobDataMap){ //定義JobDetail JobDetail jobDetail = newJob(cls).requestRecovery(true) .usingJobData(jobDataMap) .withIdentity(jobName,DEFAULT_JOB_GROUP_NAME) .build(); //定義Trigger Trigger cronTrigger = newTrigger().withIdentity(jobName+"Trigger",DEFAULT_TRIGGER_GROUP_NAME) .startNow() .withSchedule(cronSchedule(cronExpression) .withMisfireHandlingInstructionFireAndProceed()) .forJob(jobDetail) .build(); Scheduler scheduler = SchedulerUtils.getScheduler(); try { scheduler.scheduleJob(jobDetail,cronTrigger); } catch (SchedulerException e) { log.info("執行方法-addJobAndData-時發生異常,異常資訊為:"+e.getMessage()); e.printStackTrace(); } } public void pauseJob(String jobName,String triggerGroupName) throws RuntimeException { try { if(null == triggerGroupName) scheduler.pauseTrigger(new TriggerKey(jobName+"Trigger",DEFAULT_TRIGGER_GROUP_NAME)); else scheduler.pauseTrigger(new TriggerKey(jobName+"Trigger",triggerGroupName)); } catch (SchedulerException e) { e.printStackTrace(); log.info("執行方法-pauseJob-時發生異常,異常資訊為:"+e.getMessage()); throw new RuntimeException("在呼叫方法-pauseJob-停止任務"+jobName+"時發生異常,異常資訊為:"+e.getMessage()); } } public void resumeJob(String jobName,String triggerGroupName){ try { if(null == triggerGroupName) scheduler.resumeTrigger(new TriggerKey(jobName+"Trigger",DEFAULT_TRIGGER_GROUP_NAME)); else scheduler.resumeTrigger(new TriggerKey(jobName+"Trigger",triggerGroupName)); } catch (SchedulerException e) { e.printStackTrace(); log.info("執行方法-resumeJob-時發生異常,異常資訊為:"+e.getMessage()); throw new RuntimeException("在呼叫方法-resumeJob-恢復任務"+jobName+"時發生異常,異常資訊為:"+e.getMessage()); } } public void deleteJob(String jobName,String jobGroupName){ try{ if(null == jobGroupName) scheduler.deleteJob(JobKey.jobKey(jobName,DEFAULT_JOB_GROUP_NAME)); else scheduler.deleteJob(JobKey.jobKey(jobName,jobGroupName)); } catch (SchedulerException e) { e.printStackTrace(); log.info("執行方法deleteJob時發生異常,異常資訊為:"+e.getMessage()); throw new RuntimeException("在呼叫方法-deleteJob-刪除任務"+jobName+"時發生異常,異常資訊為:"+e.getMessage()); } } public void startJobs(){ try { scheduler.start(); } catch (SchedulerException e) { e.printStackTrace(); log.info("執行方法-startJobs-時發生異常,異常資訊為:"+e.getMessage()); throw new RuntimeException("在呼叫方法-startJobs-啟動任務時發生異常,異常資訊為:"+e.getMessage()); } } public void shutdownJobs(){ try { scheduler.shutdown(); } catch (SchedulerException e) { e.printStackTrace(); log.info("執行方法-shutdownJobs-時發生異常,異常資訊為:"+e.getMessage()); throw new RuntimeException("在呼叫方法-shutdownJobs-停止任務時發生異常,異常資訊為:"+e.getMessage()); } } }
專案裡有建表語句,可以根據自己的資料庫型別去執行相應的指令碼。
程式碼非常簡單,這裡不做解釋了,工程裡有單元測試類,修改一下資料庫連線配置就可以運行了,跑一跑就明白大致流程了。
在建立多個Job後,可以驗證工程的叢集部署,是可以達到負載均衡的,
當然有不明白的地方在下面留言也可以,這個專案很簡單,也有很多需要補充的地方,希望有感興趣的同學一起添磚添瓦。