雖然單個Quartz實例能給予你很好的Job調度能力,但它不能知足典型的企業需求,如可伸縮性、高可靠性知足。假如你須要故障轉移的能力並能運行日益增多的 Job,Quartz集羣勢必成爲你應用的一部分了。使用 Quartz 的集羣能力能夠更好的支持你的業務需求,而且即便是其中一臺機器在最糟的時間崩潰了也能確保全部的 Job 獲得執行。mysql
一個 Quartz 集羣中的每一個節點是一個獨立的 Quartz 應用,它又管理着其餘的節點。意思是你必須對每一個節點分別啓動或中止。不像許多應用服務器的集羣,獨立的 Quartz 節點並不與另外一其的節點或是管理節點通訊。Quartz 應用是經過數據庫表來感知到另外一應用的。
圖:表示了每一個節點直接與數據庫通訊,若離開數據庫將對其餘節點一無所知sql
由於Quartz 集羣依賴於數據庫,因此必須首先建立Quartz數據庫表。Quartz 包括了全部被支持的數據庫平臺的 SQL 腳本。在 <quartz_home>/docs/dbTables 目錄下找到那些 SQL 腳本,這裏的 <quartz_home> 是解壓 Quartz 分發包後的目錄。
這裏採用的Quartz 1.6.0版本,總共12張表,不一樣版本,表個數可能不一樣。數據庫爲mysql,用tables_mysql_innodb.sql建立數據庫表。app
1.配置jdbc.properties文件測試
2.配置applicationContext.xml文件3d
3.3. 配置集羣節點的quartz.properties文件
說明:
org.quartz.scheduler.instanceName屬性可爲任何值,用在 JDBC JobStore 中來惟一標識實例,可是全部集羣節點中必須相同。
org.quartz.scheduler.instanceId屬性爲 AUTO便可,基於主機名和時間戳來產生實例 ID。
org.quartz.jobStore.class屬性爲 JobStoreTX,將任務持久化到數據中。由於集羣中節點依賴於數據庫來傳播 Scheduler 實例的狀態,你只能在使用 JDBC JobStore 時應用 Quartz 集羣。這意味着你必須使用 JobStoreTX 或是 JobStoreCMT 做爲 Job 存儲;你不能在集羣中使用 RAMJobStore。
org.quartz.jobStore.isClustered 屬性爲 true,你就告訴了 Scheduler 實例要它參與到一個集羣當中。這一屬性會貫穿於調度框架的始終,用於修改集羣環境中操做的默認行爲。
org.quartz.jobStore.clusterCheckinInterval 屬性定義了Scheduler 實例檢入到數據庫中的頻率(單位:毫秒)。Scheduler 檢查是否其餘的實例到了它們應當檢入的時候未檢入;這能指出一個失敗的 Scheduler 實例,且當前 Scheduler 會以此來接管任何執行失敗並可恢復的 Job。經過檢入操做,Scheduler 也會更新自身的狀態記錄。clusterChedkinInterval 越小,Scheduler 節點檢查失敗的 Scheduler 實例就越頻繁。默認值是 15000 (即15 秒)。
說明:
由於Job須要持久化到數據庫中,CustService必須實現Serializable接口,在這裏只是簡單打印一下日誌。
可是這裏有一個問題,若是咱們的這個CustService要繼承其餘的基類,並且基類並無實現序列化,那這個時候CustService仍然是沒法持久化到數據庫中的。因此咱們須要在CustService外面再加入一層業務引用,CustService當作一個對象注入到這個引用層裏面,詳細請看代碼:
1 業務引用層MyBusiJob.java
2 實現序列化接口Job2
3 任務引導
applicationContext-quartz.xml
說明:
1這個 MethodInvokingJobDetailFactoryBean ,原本應該採用org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean指定類和方法,可是直接使用會報java.io.NotSerializableException異常,這是由於這個類中的 methodInvoking 方法,是不支持序列化的,所以在把 QUARTZ 的 TASK 序列化進入數據庫時就會拋錯。並且目前最新版的spring也不支持這個問題。這裏咱們使用spring 官方論壇通過修改的類替代,能夠參考:
http://jira.springframework.org/browse/SPR-3797
測試結果:
幾個節點都帶有 quartz 任務,此時只有一臺 quartz 在運行,另幾個節點上的 quartz 沒有運行。
此時手動 shutdown 那臺運行 QUARTZ ,過了 7 秒左右,另外一個節點的 quartz 自動監測到了集羣中運行着的 quartz 的 instance 已經 shutdown ,所以 quartz 集羣會自動把任一臺可用的APP 上啓動起一個 quartz job 的任務。
下面兩種圖片是quartz-cluster正常運行下的任務分發
環境:
WebLogic 10.3.5 + Redhat 5.6 + Quartz 1.6.0 + Spring 2.0.8
有兩點須要注意:
1 集羣配置文件quartz.properties部署的時候必需要一致
2 集羣創建起來以後,若是運行過程當中須要修改quartz調度器的策略,例如:原來每5天執行一次任務,如今要改爲每半個月執行一次,這個時候要修改全部的配置文件,而且要從新執行上述的數據庫腳本!