- 資訊首頁(yè) > 開(kāi)發(fā)技術(shù) >
- SpringBoot2整合QuartJob如何實(shí)現定時(shí)器實(shí)時(shí)管理功能
這篇文章主要介紹了SpringBoot2整合QuartJob如何實(shí)現定時(shí)器實(shí)時(shí)管理功能,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著(zhù)大家一起了解一下。
1、一句話(huà)描述
Quartz是一個(gè)完全由java編寫(xiě)的開(kāi)源作業(yè)調度框架,形式簡(jiǎn)易,功能強大。
2、核心API
(1)、Scheduler
代表一個(gè) Quartz 的獨立運行容器,Scheduler 將 Trigger 綁定到特定 JobDetail, 這樣當 Trigger 觸發(fā)時(shí), 對應的 Job 就會(huì )被調度。
(2)、Trigger
描述 Job 執行的時(shí)間觸發(fā)規則。主要有 SimpleTrigger 和 CronTrigger 兩個(gè)子類(lèi),通過(guò)一個(gè) TriggerKey 唯一標識。
(3)、Job
定義一個(gè)任務(wù),規定了任務(wù)是執行時(shí)的行為。JobExecutionContext 提供了調度器的上下文信息,Job 的數據可從 JobDataMap 中獲取。
(4)、JobDetail
Quartz 在每次執行 Job 時(shí),都重新創(chuàng )建一個(gè) Job 實(shí)例,所以它不直接接受一個(gè) Job 的實(shí)例,相反它接收一個(gè) Job 實(shí)現類(lèi)。描述 Job 的實(shí)現類(lèi)及其它相關(guān)的靜態(tài)信息,如 Job 名字、描述等。
1、項目結構
版本描述
spring-boot:2.1.3.RELEASEquart-job:2.3.0
2、定時(shí)器配置
import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.quartz.SchedulerFactoryBean;import javax.sql.DataSource;import java.util.Properties;@Configurationpublic class ScheduleConfig { @Bean public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) { // Quartz參數配置 Properties prop = new Properties(); // Schedule調度器的實(shí)體名字 prop.put("org.quartz.scheduler.instanceName", "HuskyScheduler"); // 設置為AUTO時(shí)使用,默認的實(shí)現org.quartz.scheduler.SimpleInstanceGenerator是基于主機名稱(chēng)和時(shí)間戳生成。 prop.put("org.quartz.scheduler.instanceId", "AUTO"); // 線(xiàn)程池配置 prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool"); prop.put("org.quartz.threadPool.threadCount", "20"); prop.put("org.quartz.threadPool.threadPriority", "5"); // JobStore配置:Scheduler在運行時(shí)用來(lái)存儲相關(guān)的信息 // JDBCJobStore和JobStoreTX都使用關(guān)系數據庫來(lái)存儲Schedule相關(guān)的信息。 // JobStoreTX在每次執行任務(wù)后都使用commit或者rollback來(lái)提交更改。 prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX"); // 集群配置:如果有多個(gè)調度器實(shí)體的話(huà)則必須設置為true prop.put("org.quartz.jobStore.isClustered", "true"); // 集群配置:檢查集群下的其他調度器實(shí)體的時(shí)間間隔 prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000"); // 設置一個(gè)頻度(毫秒),用于實(shí)例報告給集群中的其他實(shí)例 prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1"); // 觸發(fā)器觸發(fā)失敗后再次觸犯的時(shí)間間隔 prop.put("org.quartz.jobStore.misfireThreshold", "12000"); // 數據庫表前綴 prop.put("org.quartz.jobStore.tablePrefix", "qrtz_"); // 從 LOCKS 表查詢(xún)一行并對這行記錄加鎖的 SQL 語(yǔ)句 prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?"); // 定時(shí)器工廠(chǎng)配置 SchedulerFactoryBean factory = new SchedulerFactoryBean(); factory.setDataSource(dataSource); factory.setQuartzProperties(prop); factory.setSchedulerName("HuskyScheduler"); factory.setStartupDelay(30); factory.setApplicationContextSchedulerContextKey("applicationContextKey"); // 可選,QuartzScheduler 啟動(dòng)時(shí)更新己存在的Job factory.setOverwriteExistingJobs(true); // 設置自動(dòng)啟動(dòng),默認為true factory.setAutoStartup(true); return factory; }}
3、定時(shí)器管理工具
import com.quart.job.entity.ScheduleJobBean;import org.quartz.*;/** * 定時(shí)器工具類(lèi) */public class ScheduleUtil { private ScheduleUtil (){} private static final String SCHEDULE_NAME = "HUSKY_" ; /** * 觸發(fā)器 KEY */ public static TriggerKey getTriggerKey(Long jobId){ return TriggerKey.triggerKey(SCHEDULE_NAME+jobId) ; } /** * 定時(shí)器 Key */ public static JobKey getJobKey (Long jobId){ return JobKey.jobKey(SCHEDULE_NAME+jobId) ; } /** * 表達式觸發(fā)器 */ public static CronTrigger getCronTrigger (Scheduler scheduler,Long jobId){ try { return (CronTrigger)scheduler.getTrigger(getTriggerKey(jobId)) ; } catch (SchedulerException e){ throw new RuntimeException("getCronTrigger Fail",e) ; } } /** * 創(chuàng )建定時(shí)器 */ public static void createJob (Scheduler scheduler, ScheduleJobBean scheduleJob){ try { // 構建定時(shí)器 JobDetail jobDetail = JobBuilder.newJob(TaskJobLog.class).withIdentity(getJobKey(scheduleJob.getJobId())).build() ; CronScheduleBuilder scheduleBuilder = CronScheduleBuilder .cronSchedule(scheduleJob.getCronExpression()) .withMisfireHandlingInstructionDoNothing() ; CronTrigger trigger = TriggerBuilder.newTrigger() .withIdentity(getTriggerKey(scheduleJob.getJobId())) .withSchedule(scheduleBuilder).build() ; jobDetail.getJobDataMap().put(ScheduleJobBean.JOB_PARAM_KEY,scheduleJob); scheduler.scheduleJob(jobDetail,trigger) ; // 如果該定時(shí)器處于暫停狀態(tài) if (scheduleJob.getStatus() == 1){ pauseJob(scheduler,scheduleJob.getJobId()) ; } } catch (SchedulerException e){ throw new RuntimeException("createJob Fail",e) ; } } /** * 更新定時(shí)任務(wù) */ public static void updateJob(Scheduler scheduler, ScheduleJobBean scheduleJob) { try { // 構建定時(shí)器 TriggerKey triggerKey = getTriggerKey(scheduleJob.getJobId()); CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression()) .withMisfireHandlingInstructionDoNothing(); CronTrigger trigger = getCronTrigger(scheduler, scheduleJob.getJobId()); trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build(); trigger.getJobDataMap().put(ScheduleJobBean.JOB_PARAM_KEY, scheduleJob); scheduler.rescheduleJob(triggerKey, trigger); // 如果該定時(shí)器處于暫停狀態(tài) if(scheduleJob.getStatus() == 1){ pauseJob(scheduler, scheduleJob.getJobId()); } } catch (SchedulerException e) { throw new RuntimeException("updateJob Fail",e) ; } } /** * 停止定時(shí)器 */ public static void pauseJob (Scheduler scheduler,Long jobId){ try { scheduler.pauseJob(getJobKey(jobId)); } catch (SchedulerException e){ throw new RuntimeException("pauseJob Fail",e) ; } } /** * 恢復定時(shí)器 */ public static void resumeJob (Scheduler scheduler,Long jobId){ try { scheduler.resumeJob(getJobKey(jobId)); } catch (SchedulerException e){ throw new RuntimeException("resumeJob Fail",e) ; } } /** * 刪除定時(shí)器 */ public static void deleteJob (Scheduler scheduler,Long jobId){ try { scheduler.deleteJob(getJobKey(jobId)); } catch (SchedulerException e){ throw new RuntimeException("deleteJob Fail",e) ; } } /** * 執行定時(shí)器 */ public static void run (Scheduler scheduler, ScheduleJobBean scheduleJob){ try { JobDataMap dataMap = new JobDataMap() ; dataMap.put(ScheduleJobBean.JOB_PARAM_KEY,scheduleJob); scheduler.triggerJob(getJobKey(scheduleJob.getJobId()),dataMap); } catch (SchedulerException e){ throw new RuntimeException("run Fail",e) ; } }}
4、定時(shí)器執行和日志
import com.quart.job.entity.ScheduleJobBean;import com.quart.job.entity.ScheduleJobLogBean;import com.quart.job.service.ScheduleJobLogService;import org.quartz.JobExecutionContext;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.scheduling.quartz.QuartzJobBean;import java.lang.reflect.Method;import java.util.Date;/** * 定時(shí)器執行日志記錄 */public class TaskJobLog extends QuartzJobBean { private static final Logger LOG = LoggerFactory.getLogger(TaskJobLog.class) ; @Override protected void executeInternal(JobExecutionContext context) { ScheduleJobBean jobBean = (ScheduleJobBean)context.getMergedJobDataMap().get(ScheduleJobBean.JOB_PARAM_KEY) ; ScheduleJobLogService scheduleJobLogService = (ScheduleJobLogService)SpringContextUtil.getBean("scheduleJobLogService") ; // 定時(shí)器日志記錄 ScheduleJobLogBean logBean = new ScheduleJobLogBean () ; logBean.setJobId(jobBean.getJobId()); logBean.setBeanName(jobBean.getBeanName()); logBean.setParams(jobBean.getParams()); logBean.setCreateTime(new Date()); long beginTime = System.currentTimeMillis() ; try { // 加載并執行定時(shí)器的 run 方法 Object target = SpringContextUtil.getBean(jobBean.getBeanName()); Method method = target.getClass().getDeclaredMethod("run", String.class); method.invoke(target, jobBean.getParams()); long executeTime = System.currentTimeMillis() - beginTime; logBean.setTimes((int)executeTime); logBean.setStatus(0); LOG.info("定時(shí)器 === >> "+jobBean.getJobId()+"執行成功,耗時(shí) === >> " + executeTime); } catch (Exception e){ // 異常信息 long executeTime = System.currentTimeMillis() - beginTime; logBean.setTimes((int)executeTime); logBean.setStatus(1); logBean.setError(e.getMessage()); } finally { scheduleJobLogService.insert(logBean) ; } }}
1、定時(shí)器初始化
@Servicepublic class ScheduleJobServiceImpl implements ScheduleJobService { @Resource private Scheduler scheduler ; @Resource private ScheduleJobMapper scheduleJobMapper ; /** * 定時(shí)器初始化 */ @PostConstruct public void init (){ ScheduleJobExample example = new ScheduleJobExample() ; List<ScheduleJobBean> scheduleJobBeanList = scheduleJobMapper.selectByExample(example) ; for (ScheduleJobBean scheduleJobBean : scheduleJobBeanList) { CronTrigger cronTrigger = ScheduleUtil.getCronTrigger(scheduler,scheduleJobBean.getJobId()) ; if (cronTrigger == null){ ScheduleUtil.createJob(scheduler,scheduleJobBean); } else { ScheduleUtil.updateJob(scheduler,scheduleJobBean); } } }}
2、添加定時(shí)器
@Override@Transactional(rollbackFor = Exception.class)public int insert(ScheduleJobBean record) { ScheduleUtil.createJob(scheduler,record); return scheduleJobMapper.insert(record);}
3、立即執行一次定時(shí)器
@Override@Transactional(rollbackFor = Exception.class)public void run(Long jobId) { ScheduleJobBean scheduleJobBean = scheduleJobMapper.selectByPrimaryKey(jobId) ; ScheduleUtil.run(scheduler,scheduleJobBean);}
4、更新定時(shí)器
@Override@Transactional(rollbackFor = Exception.class)public int updateByPrimaryKeySelective(ScheduleJobBean record) { ScheduleUtil.updateJob(scheduler,record); return scheduleJobMapper.updateByPrimaryKeySelective(record);}
5、停止定時(shí)器
@Override@Transactional(rollbackFor = Exception.class)public void pauseJob(Long jobId) { ScheduleJobBean scheduleJobBean = scheduleJobMapper.selectByPrimaryKey(jobId) ; ScheduleUtil.pauseJob(scheduler,jobId); scheduleJobBean.setStatus(1); scheduleJobMapper.updateByPrimaryKeySelective(scheduleJobBean) ;}
6、恢復定時(shí)器
@Override@Transactional(rollbackFor = Exception.class)public void resumeJob(Long jobId) { ScheduleJobBean scheduleJobBean = scheduleJobMapper.selectByPrimaryKey(jobId) ; ScheduleUtil.resumeJob(scheduler,jobId); scheduleJobBean.setStatus(0); scheduleJobMapper.updateByPrimaryKeySelective(scheduleJobBean) ;}
7、刪除定時(shí)器
@Override@Transactional(rollbackFor = Exception.class)public void delete(Long jobId) { ScheduleUtil.deleteJob(scheduler, jobId); scheduleJobMapper.deleteByPrimaryKey(jobId) ;}
四、配置一個(gè)測試的定時(shí)器
1、定時(shí)接口封裝
public interface TaskService { void run(String params);}
2、測試定時(shí)器
@Component("getTimeTask")public class GetTimeTask implements TaskService { private static final Logger LOG = LoggerFactory.getLogger(GetTimeTask.class.getName()) ; private static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") ; @Override public void run(String params) { LOG.info("Params === >> " + params); LOG.info("當前時(shí)間::::"+format.format(new Date())); }}
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系QQ:712375056 進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。
Copyright ? 2009-2021 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 珠海市特網(wǎng)科技有限公司 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站