Spring+Quartz 整合二:調度管理與定時任務分離


  新的應用場景:很多時候,我們常常會遇到需要動態的添加或修改任務,而spring中所提供的定時任務組件卻只能夠通過修改xml中trigger的配置才能控制定時任務的時間以及任務的啟用或停止,這在帶給我們方便的同時也失去了動態配置任務的靈活性。所有的配置都在xml中完成,包括cronExpression表達式,十分的方便。但是如果我的任務信息是保存在數據庫的,想要動態的初始化,而且任務較多的時候不是得有一大堆的xml配置?或者說我要修改一下trigger的表達式,使原來5秒運行一次的任務變成10秒運行一次,這時問題就來了,試過在配置文件中不傳入cronExpression等參數,但是啟動時就報錯了,難道我每次都修改xml文件然后重啟應用嗎,這顯然不合適的。最理想的是在與spring整合的同時又能實現動態任務的添加、刪除及修改配置。

場景要求:
1、減少spring的配置文件,為了實現一個定時任務,spring的配置代碼太多了。
2、用戶可以通過頁面等方式添加、啟用、禁用某個任務。
3、用戶可以修改某個已經在運行任務的運行時間表達式,CronExpression。
4、為方便維護,簡化任務的運行調用處理,任務的運行入口即Job實現類最好只有一個,該Job運行類相當於工廠類,在實際調用時把任務的相關信息通過參數方式傳入,由該工廠類根據任務信息來具體執行需要的操作。

分析:配置文件的模式是將配置中中job、trigger等取出來排程,采用數據庫存儲也是一樣的 取出來組裝排程

步驟:
步驟一:spring配置文件

1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
5 
6     <bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"/>
7 </beans>

步驟二:創建任務,將任務存入數據庫,對人物進行啟動、刪除、暫停、恢復、立即運行一次處理

注意:任務的處理不僅僅是任務 還有觸發器 等  而且有些操作有先后限制  比如刪除,要先暫停觸發器  后移除觸發器 然后移除任務等

 步驟三:創建定時任務:兩種創建方式:實現Job接口或者繼承QuartzJobBean抽象類。名字和實體bean里的jobname一致。

public class QuartzJob extends QuartzJobBean{}

public class QuartzJob implements Job {} 

 

注意:
1、trigger各狀態說明:
None:Trigger已經完成,且不會在執行,或者找不到該觸發器,或者Trigger已經被刪除 NORMAL:正常狀態 PAUSED:暫停狀態 COMPLETE:觸發器完成,但是任務可能還正在執行中 BLOCKED:線程阻塞狀態 ERROR:出現錯誤
2、更新任務 直接更新不起作用,要先刪除后新創建;
3、同步和異步:同步和異步在quartz 2.2的版本中對於使用者來說區別只在於是否在job類上添加了@DisallowConcurrentExecution注解,需要注意在定時任務運行時更新是沒有辦法改變同步和異步的
4、集群、分布式架構實現探討:使用消息機制,通過分發和接收信息來實現對集群中定時任務的管理。

5、執行多次的問題:triger在定義時有一個默認的參數startTime,如果不設置的話會默認設置為now
CronTrigger trigger = newTrigger().withIdentity("trigger1", "group1").startNow().withSchedule(cronSchedule("0/2 * * * * ?")).build();

6、scheduler.getCurrentlyExecutingJobs():獲取的不是打開狀態的任務,而是正在執行的任務。比如我五秒鍾打一行字符串,如果我在程序打字符串的時候正好執行scheduler.getCurrentlyExecutingJobs(),那么就可以得到。但是程序打字符串的時間是極短的,所以基本得不到。
7、定時任務啟停:scheduler.isShutdown()將關閉定時任務的線程和相關資源 無法再次重啟,所以如果要停止所有定時任務不要使用這個方法,可以使用standby或者遍歷所有任務進行unscheduleJob(TriggerKey triggerKey),開啟使用start(),系統啟動后 默認是standby模式 需要start()一下才能開啟所有任務;
系統啟動后定時任務框架啟動概述信息:
Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally. --Scheduler排程類 以及加載是否成功
NOT STARTED. --當前是否開啟
Currently in standby mode. --默認啟動模式
Number of jobs executed: 0 --目前執行過的定時任務數目
Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.--默認啟動十個線程支持
Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.--使用RAMJobStore不支持持久化

參考:
http://www.dexcoder.com/selfly/article/308
http://www.dexcoder.com/selfly/article/1822?curPage=83#comment
http://blog.csdn.net/pengpegv5yaya/article/details/37595889

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM