Spring4 + Quartz2 Scheduler

王嘉鴻 2016/07/22 18:41:19
4984


主題

Spring4 + Quartz2 Scheduler

文章簡介:

Spring 搭配 Quartz 排程

作者:

王嘉鴻

版本/產出日期:

版本/產出日期:V1.0/2016.07.22










1. 前言

本文件用來提供Java開發人員排程使用,提供多台Server排程管理機制。





2. 目的

初步了解SpringQuartz的整合。

介紹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.提供創建SchedulerBeanFactory類,方便在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是不會生效

會出現下列錯誤:



錯誤




這時候我們需要幫QuartzInject的動作




Xml 設定:



JavaConfig 設定




測試






8. Quartz Cluster


8.1 概述:


Quartz Cluster 提供排程的管理能力,透過與DB連結,在多台Server中確認只有一台執行Job,即使是其中一台

Server出現問題也能確保所有的 Job 得到執行。





8.2 Quartz 官網中下載 Quartz 裡面包含各種DBScript,建立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資料,由哪台Serverlock

資料,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 設定

http://www.concretepage.com/spring-4/spring-4-quartz-2-scheduler-integration-annotation-example-using-javaconfig

quartzcronExpression配置说明

http://www.blogjava.net/javainthink/archive/2006/10/19/76077.html

quartz介紹

http://www.360doc.com/content/10/0907/16/1794186_51886356.shtml

王嘉鴻