1. 程式人生 > >Spring4整合Quartz2.2.3定時任務叢集配置

Spring4整合Quartz2.2.3定時任務叢集配置

Quartz與Spring整合及叢集環境配置

  • Quartz介紹

Quartz是一個開源專案,專注於任務排程器,它可以與J2EE應用程式相結合也可以單獨使用。簡單的使用方法建立一個實現org.quartz.Job介面的java類,實現Job介面包含的唯一方法:execute()。將定時任務邏輯新增到execute()方法中。

當在叢集環境下,當有配置Quartz多個客戶端(節點)時,採用Quartz的叢集和分散式處理時,有如下幾點好處 :

1.一個節點無法完成的任務,會被叢集中擁有相同的任務的節點取代執行。

2.分散式體現在當相同的任務定時在一個時間點,在那個時間點,不會被兩個節點同時執行。

  • Quartz叢集原理
  1. Quartz叢集架構

一個Quartz叢集中的每個節點是一個獨立的Quartz應用,它又管理著其他的節點。這就意味著你必須對每個節點分別啟動或停止。Quartz叢集中,獨立的Quartz節點並不與另一其的節點或是管理節點通訊,而是通過相同的資料庫表來感知到另一Quartz應用的,排程任務儲存在資料庫中,當叢集任務操作資料庫,資料庫就會被加鎖,防止其他相同的任務也讀取到該任務,避免任務的重複執行。如圖:

  1. Quartz叢集相關資料庫表

因為Quartz叢集依賴於資料庫,所以必須首先建立Quartz資料庫表,Quartz釋出包中包括了所有被支援的資料庫平臺的SQL指令碼。這些SQL指令碼存放於<quartz_home>/docs/dbTables 目錄下,Quartz版本2.2.3,其中包含了11張表。

  • Spring整合Quartz

完成初次整合,後續新增定時任務只需按照第5步方式新增即可。

  1. 新增Quartz依賴jar包

<dependency>

    <groupId>org.quartz-scheduler</groupId>

    <artifactId>quartz</artifactId>

    <version>2.2.3</version>

</dependency>

<dependency>

    <groupId>org.quartz-scheduler</groupId>

    <artifactId>quartz-jobs</artifactId>

    <version>2.2.3</version>

</dependency>  

  1. 建立資料庫表結構

根據Quartz下載包提供的標準SQL,選擇對應的資料庫型別,進行資料庫表結構建立。如下,框內為與叢集定時任務緊密相關聯表。

  1. 建立Quartz配置檔案quartz.properties

org.quartz.scheduler.instanceName屬性可為任何值,用在 JDBC JobStore 中來唯一標識例項,但是所有叢集節點中必須相同。

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 秒)。

  1. 配置applicationContext-quartz.xml檔案

本檔案主要是配置觸發器的屬性和定時任務的路徑和執行規則。

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xsi:schemaLocation="http://www.springframework.org/schema/beans                      http://www.springframework.org/schema/beans/spring-beans.xsd">

       <bean name="quartzScheduler"

      class="org.springframework.scheduling.quartz.SchedulerFactoryBean">

              <property name="dataSource">

                     <ref bean="dataSource" />

              </property>

              <property name="overwriteExistingJobs" value="true" />

              <property name="startupDelay" value="2" />    

              <property name="applicationContextSchedulerContextKey" value="applicationContextKey" />

              <property name="configLocation" value="classpath:quartz.properties" />

              <property name="triggers">

                     <list>

                            <ref bean="trigger1" />

                     </list>

              </property>

       </bean>

       <bean id="jobDetail1"

      class="org.springframework.scheduling.quartz.JobDetailFactoryBean">

              <property name="jobClass">

                     <value>com.genersoft.pub.quartz.MyJob</value>

              </property>

              <property name="durability" value="true" />

              <property name="requestsRecovery" value="true" />

       </bean>

       <bean id="trigger1"

      class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">

              <property name="jobDetail" ref="jobDetail1" />

              <property name="cronExpression" value="0 43,44,45 11 * * ?" />

       </bean>

</beans>

dataSource:專案中用到的資料來源,裡面包含了quartz用到的11張資料庫表。

configLocation:用於指明quartz的配置檔案的位置。

requestsRecovery屬性必須設定為 true,當Quartz服務被中止後,再次啟動或叢集中其他機器接手任務時會嘗試恢復執行之前未完成的所有任務。

overwriteExistingJobs屬性設定為true,當QuartzScheduler 啟動時更新己存在的Job。

startupDelay屬性控制QuartzScheduler 延時啟動,應用啟動完成後QuartzScheduler 再啟動。

  1. 如何新增一個或多個定時任務

在applicationContext-quartz.xml檔案中配置多個觸發器實現多個定時任務的配置。每個觸發器對應一個任務訊息描述。如下:

注意事項:

當使用quartz叢集模式時,當叢集中的程式碼版本不一致,會出現qrtz_triggers中trigger_state的狀態變為error的情況,原因是叢集模式先quartz執行排程任務,是根據資料庫表中的排程記錄進行執行,當執行到有對應程式碼的節點上,不會出現問題,但是當執行到沒有對應程式碼的節點上,就會變為error, 
因此在叢集環境下,節點較多的時候使用quartz,需要注意每個節點的程式碼版本一定要保持一致。

  1. 執行規則生成介紹(cron表示式)

本文中Quartz定時任務採用cron表示式來定製執行規則。Cron表示式可線上生成。如圖所示:

線上生成網址:

http://cron.qqe2.com/

  • 參考文件