基於Quartz.Net的任務管理平台開發(1) —— 基本原理


 由於工作原因,需要用到任務監控平台,經過一番摸索,發現了Quratz.net這個開源的作業調度框架。防止忘記,做個備忘。

1 Quartz.Net概述

 

       開源組件Quartz.Net,這是一個開源的作業調度框架,是OpenSymphony 的 Quartz API的.NET移植,它用C#寫成,可用於winform和asp.net應用中。它提供了巨大的靈活性而不犧牲簡單性。能夠用它來為執行一個作業而創建簡單的或復雜的調度。

  Quartz於很多特征,如:數據庫支持,集群,插件,支持cron-like表達式等等。

  Quartz.net是一個開源的任務調度工具,相當於數據庫中的 Job、Windows 的計划任務、Unix/Linux 下的 Cron,但 Quartz 可以把排程控制的更精細,對任務調度的領域問題進行了高度的抽象,實現作業的靈活調度。

2 Quartz基本概念

 

  Quartz由幾個基本的接口組成,如下圖:

 

   

 

 

 

Scheduler:

 

計划調度器,里面可以盛放眾多的JobDetail和trigger,當容器啟動后,里面的每個JobDetail都會根據trigger按部就班自動去執行。

 

Trigger:

 

觸發器,配置調度參數的配置,什么時候去調。描述觸發Job執行的時間觸發規則。主要有SimpleTrigger和CronTrigger這兩個子類。當僅需觸發一次或者以固定時間間隔周期執行,SimpleTrigger是最適合的選擇;而CronTrigger則可以通過Cron表達式定義出各種復雜時間規則的調度方案:如每早晨9:00執行,周一、周三、周五下午5:00執行等;

 

Job:

 

任務是一個接口,只有一個方法void execute(JobExecutionContext context),開發者實現該接口定義運行任務,JobExecutionContext類提供了調度上下文的各種信息。Job運行時的信息保存在JobDataMap實例中;

 

JobDetail:

 

可執行的工作,它本身可能是有狀態的。Quartz在每次執行Job時,都重新創建一個Job實例,所以它不直接接受一個Job的實例,相反它接收一個Job實現類,以便運行時通過newInstance()的反射機制實例化Job。因此需要通過一個類來描述Job的實現類及其它相關的靜態信息,如Job名字、描述、關聯監聽器等信息,JobDetail承擔了這一角色。

 

JobDataMap:

 

存放Job運行時的信息。

 

Calendar:

 

日歷功能,一個Trigger可以和多個Calendar關聯,以便排除或包含某些時間點。假設,我們安排每周星期一早上10:00執行任務,但是如果碰到法定的節日,任務則不執行,這時就需要在Trigger觸發機制的基礎上使用Calendar進行定點排除。

 

ThreadPool:

 

Scheduler使用一個線程池作為任務運行的基礎設施,任務通過共享線程池中的線程提高運行效率。

 

SchedulerContext:

 

調度器的上下文

3 Quartz運行原理

3.1 任務調度原理

啟動過程:

(1) 實例化一個調度器工廠SchedulerFactory,可以使用配置文件,或者代碼實現自定義的實例。

(2) 通過getScheduler()方法從調度器工廠里得到調度器實例

(3) Scheduler有一個QuartzSchedulerThread(Thread的子類)屬性,在scheduler實例化的時候,實例化了一個對象,並用ThreadExecutor啟動該線程對象。該線程就是調度線程,主要任務就是不停的從JobStore中獲取即將被觸發的觸發器(默認30s調度一次)。在這個時候調度線程雖然啟動,但是處於pause狀態。

調度過程:

(4) 通過scheduleJob()方法將任務和觸發器存儲在JobStore中,通過start()方法將QuartzSchedulerThread的pause狀態設為false,通知調度線程執行任務,此后調度線程不停的從JobStore中去取即將觸發的任務。

3.2 任務執行原理

(1) 調度線程首先去線程池中獲取可用的線程,如果沒有的話,就阻塞。

(2) JobStore(從存儲介質中獲取觸發器,存儲介質可以是內存也可以是數據庫)獲取(接下來30s內的)觸發器,然后等待該觸發器觸發。

(3) 調度線程創建一個JobRunShell(就是一個Runnable),然后從線程池中調用線程執行該任務。

獲取trigger、JobDetail以及生成Job實例,然后執行job的execute接口函數。

3.3 任務持久化

 

Quartz提供兩種基本作業存儲類型。第一種類型叫做RAMJobStore,第二種類型叫做JDBC作業存儲。在默認情況下Quartz將任務調度的運行信息保存在內存中,這種方法提供了最佳的性能,因為內存中數據訪問最快。不足之處是缺乏數據的持久性,當程序路途停止或系統崩潰時,所有運行的信息都會丟失。也不方便於集群處理,因此本模塊采用JDBC作業存儲的方案,Quartz.net支持多種數據庫進行任務持久化的存儲。

 

官方提供的各種數據庫腳本:https://github.com/quartznet/quartznet/tree/master/database/tables

3.4 Quartz表結構

1、QRTZ_JOB_DETAILS:存儲的是job的詳細信息,包括:[DESCRIPTION]描述,[IS_DURABLE]是否持久化,[JOB_DATA]持久化對象等基本信息。

2、QRTZ_TRIGGERS:觸發器信息,包含:job的名,組外鍵,[DESCRIPTION]觸發器的描述等基本信息,還有[START_TIME]開始執行時間,[END_TIME]結束執行時間,[PREV_FIRE_TIME]上次執行時間,[NEXT_FIRE_TIME]下次執行時間,[TRIGGER_TYPE]觸發器類型:simple和cron,[TRIGGER_STATE]執行狀態:WAITING,PAUSED,ACQUIRED分別為:等待,暫停,運行中。

3、QRTZ_CRON_TRIGGERS:保存cron表達式。

4、QRTZ_SCHEDULER_STATE:存儲集群中note實例信息,quartz會定時讀取該表的信息判斷集群中每個實例的當前狀態,INSTANCE_NAME:之前配置文件中org.quartz.scheduler.instanceId配置的名字,就會寫入該字段,如果設置為AUTO,quartz會根據物理機名和當前時間產生一個名字。  [LAST_CHECKIN_TIME]上次檢查時間,[CHECKIN_INTERVAL]檢查間隔時間。

5、QRTZ_PAUSED_TRIGGER_GRPS:暫停的任務組信息。

6、QRTZ_LOCKS,悲觀鎖發生的記錄信息。

7、QRTZ_FIRED_TRIGGERS,正在運行的觸發器信息。

8、QRTZ_SIMPLE_TRIGGERS,簡單的出發器詳細信息。

9、QRTZ_BLOB_TRIGGERS,觸發器存為二進制大對象類型(用於Quartz用戶自己觸發數據庫定制自己的觸發器,然而JobStore不明白怎么存放實例的時候)。

 

以上為Quartz.Net的基本原理。


免責聲明!

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



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