Spring4 + Quartz2 Scheduler
主題: |
Spring4 + Quartz2 Scheduler |
文章簡介: |
Spring 搭配 Quartz 排程 |
作者: |
王嘉鴻 |
版本/產出日期: |
版本/產出日期:V1.0/2016.07.22 |
1. 前言
本文件用來提供Java開發人員排程使用,提供多台Server排程管理機制。
2. 目的
初步了解Spring與Quartz的整合。
介紹Quartz Cluster
3. 簡介
Spring框架實現排程主要有三種類型:
1.Java自帶的java.util.Timer,使用這種方式可以讓你的程序按照某一個頻度執行,但不能在指定時間運行。
2.使用Quartz,這是一個功能比較強大的的調度器,
可以讓你的程序在指定時間執行,也可以按照某一個頻度執行,配置起來稍顯複雜。
3.Spring3.0以後自帶的task,可以將它看成一個輕量級的Quartz,而且使用起來比Quartz簡單許多。
Quartz本身提供Cluster的機制比起一般的排程功能來的強大許多,也是最重要的一點。
Spring提供了一些便利工具類直接將Spring中的Bean包裝成合法的任務。
Spring降低了使用Quartz的難度,以Spring的風格來使用Quartz。
它提供了兩方面的支持:
1.為Quartz的重要組件類提供更具Bean風格的擴展類。
2.提供創建Scheduler的BeanFactory類,方便在Spring環境下創建對應的組件對象,並結合。
注意:
spring3.1以下的版本必須使用quartz1.x系列,3.1以上的版本才支持quartz 2.x,不然會出錯。
本文章將以 Spring4 + Quartz2來做示範。
4. 開發前準備
• JDK6
• STS 3.7.2.RELEASE
• SQL SERVER 2008
• Maven3
5. Spring 4 With Quartz 2 Scheduler Using Xml
5.1測試方便使用Maven建立Simple Project
5.2 Pom.xml 使用jar檔設定
Spring:
org.springframework.spring-webmvc
org.springframework.spring-context-support
org.springframework.spring-tx
Quartz:
org.quartz-scheduler.quartz
Log:
org.slf4j.slf4j-api
ch.qos.logback.logback-classic
DB:
net.sourceforge.jtds.jtds
5.3建立Job
繼承 QuartzJobBean
複寫 method: executeInternal把邏輯寫在其中
@DisallowConcurrentExecution:
會等待上一個job跑完再起新的job
Ex: 設定一個job五秒跑一次,但這個job可能花十秒跑完
設定DisallowConcurrentExecution 會等待任務執行完畢以後再去執行,否則會在五秒時再啟用新的job
@PersistJobDataAfterExecution:
每個job都擁有獨立JobDataMap,互不相影響
5.4 Spring設定檔中設定排程
在Spring設定中加入
JobDetailFactoryBean 建立job工作
jobClass: job程式
group: group name
name: job name
durability: 表示任務完成之後是否依然保留到數據庫,默認為false
CronTriggerFactoryBean 建立排程時間
jobDetail: 設定好的job
cronExpression: 啟用的時間格式 ex: 0 0/1 * * * ? 每分鐘跑一次
group: group name
name: trigger name
startDelay: 開始延遲
SchedulerFactoryBean 建立排程
configLocation: 自訂義設定檔,也可使用預設,稍後說明
jobFactory: Spring Inject,稍後說明
triggers: 建立好的排程
5.5 測試
測試方便,使用下列語法啟動Spring:
AbstractApplicationContext context = new
ClassPathXmlApplicationContext("application-config.xml");
在log中看到job是每分鐘啟動,至於其他訊息稍後會說明
6. Spring 4 With Quartz 2 Scheduler Using JavaConfig
6.1 請依第四點做到第三步驟
6.2 使用 JavaConfig 設定排程
與xml設定是一樣的,改用code來做設定
6.3 測試
啟動Spring:
ApplicationContext appCtx = new AnnotationConfigApplicationContext(QuartzConfiguration.class);
測試結果一樣
7. Inject Bean To Quartz Job
因為 Quartz 並不是一個 Spring 的 Bean,使用Inject是不會生效
會出現下列錯誤:
錯誤
這時候我們需要幫Quartz做Inject的動作
Xml 設定:
JavaConfig 設定
測試
8. Quartz Cluster
8.1 概述:
Quartz Cluster 提供排程的管理能力,透過與DB連結,在多台Server中確認只有一台執行Job,即使是其中一台
Server出現問題也能確保所有的 Job 得到執行。
8.2 Quartz 官網中下載 Quartz 裡面包含各種DB的Script,建立DB
8.3 quartz.properties 設定 db連線與Cluster
如果是在單一Server是不需要自定義quartz.properties,除非需要設定
ThreadPool數量,這邊介紹db的連線設定,其他參數在官網有提供說明
org.quartz.jobStore.dataSource:
名稱設定這邊使用 myDs
org.quartz.jobStore.isClustered:
是否為Cluster
org.quartz.jobStore.driverDelegateClass:
各種DB有不同的Delegate,這邊使用mssql設定
org.quartz.dataSource.myDS.driver:
DB driver
org.quartz.dataSource.myDS.URL:
連結url
org.quartz.dataSource.myDS.user:
使用者
org.quartz.dataSource.myDS.password:
密碼
也有提供jndi設定,一樣在官網上有說明
8.4 測試
模擬一樣的程式,部屬在多台Server
設定trigger時間在 14:06啟動job
下列兩張圖得知只有一台Server去執行Job
搶到執行的Server
未搶到執行的Server
可以看到Log的資訊 Lock 'TRIGGER_ACCESS'
當trigger時間到時,Server會去DB lock資料,由哪台Server先lock到
資料,Job就由哪台Server執行,確保Job只被一台Server執行,
也確保當有Server 掛掉時Job會有別台Server執行。
8.5 注意
Quartz Cluster 在啟動時會去DB塞資料
如要修改資料,例如像是Trigger時間修改,程式重新佈署他是不會同步到DB中,所以建議在換版時先清空DB,
再由Quartz去新增DB資料
清除DB如下:
delete from QRTZ_SIMPLE_TRIGGERS;
delete from QRTZ_TRIGGERS;
delete from QRTZ_JOB_DETAILS;
delete from QRTZ_CRON_TRIGGERS;
9. 參考來源
quartz 官網
http://www.quartz-scheduler.org/
Spring + quartz 設定
quartz中cronExpression配置说明
http://www.blogjava.net/javainthink/archive/2006/10/19/76077.html
quartz介紹
http://www.360doc.com/content/10/0907/16/1794186_51886356.shtml