Quartz 的启动流程分析
一、簡要
1.1、quartz 的核心元素
Scheduler為調度器負責整個定時系統的調度,內部通過線程池進行調度,下文闡述。
Trigger為觸發器記錄著調度任務的時間規則,主要有四種類型:SimpleTrigger、CronTrigger、DataIntervalTrigger、NthIncludedTrigger,在項目中常用的為:SimpleTrigger和CronTrigger。
JobDetail為定時任務的信息載體,可以記錄Job的名字、組及任務執行的具體類和任務執行所需要的參數
Job為任務的真正執行體,承載著具體的業務邏輯。
(像我們昨天的小案例中,簡單定時任務就是實現了 job 接口)
大致流程就是:
- 先由?SchedulerFactory?創建?Scheduler?調度器
- 再由?Scheduler?調度器去調取即將執行的?Trigger?,
- 執行時獲取到對于的?JobDetail?信息,
- 最后找到對應的?Job?類執行業務邏輯。
1.2、quartz中的線程
-
執行線程主要由一個線程池維護,在需要執行定時的時候使用,
-
這里使用的線程池是?org.quartz.simpl.SimpleThreadPool?,默認線程數為 10
(這些在程序啟動過程中的打印信息處就能看到)
- 調度線程主要分為?Regular Scheduler Thread?和?Misfire Scheduler Thread?;
- 其中?Regular Thread 輪詢Trigger?,如果有將要觸發的Trigger,則從任務線程池中獲取一個空閑線程,然后執行與改Trigger關聯的job;
- Misfire Thraed?則是掃描所有的trigger,查看是否有錯失的,如果有的話,根據一定的策略進行處理。
二、quartz 啟動流程
通常是使用?StdSchedulerFactory?創建?Scheduler?調度器。
在?SchedulerFactoryBean?配置類中配了相關的配置及配置文件參數,所以會讀取配置文件參數,初始化各個組件。
啟動流程的大致步驟如下:
2.1、讀取配置文件
這里的讀取,沒有去debug,配置文件的位置是在
org.quartz?的包下,文件名為?quartz.properties
其內容為:
2.2、初始化SchedulerFactoryBean
當服務器啟動時,Spring就加載相關的bean。
SchedulerFactoryBean實現了InitializingBean接口,因此在初始化bean的時候,會執行afterPropertiesSet方法,
該方法將會調用SchedulerFactory,通常是調用StdSchedulerFactory 來創建Scheduler調度器
2.3、初始化SchedulerFactory
這一步是在?SchedulerFactoryBean?的?prepareSchedulerFactory?方法中進行初始化,在上一步也已經看到~
我們接著往下Debug
這一大段都是在獲取配置文件信息,我們直接將斷點放到方法的末尾,看一下里面的值,和接下來要debug的方法
到這之后,我們會回到
this.scheduler = prepareScheduler(prepareSchedulerFactory());?這一步,拿到
prepareSchedulerFactory()?返回的,接著往下走。
上面的if就不看了,直接看create方法做了什么
這里的?this.schedulerName?是?quartzScheduler
這里的?schedulerFactory.getScheduler()?是值得我們注意的,點進去看,我們看看?StdSchedulerFactory?的?getScheduler()?方法做了什么呢?
引來襲來的就是quartz中的重要組件,而且都是null,這說明我們要到下一步啦
2.4、實例化執行線程池(TheadPool)
2.5、實例化數據存儲
2.6、初始化QuartzScheduler
QuartzScheduler?為Scheduler的簡單實現,包括調度作業、注冊JobListener實例等方法。
2.7、new一個?QuartzSchedulerThread?調度線程
QuartzSchedulerThread?負責執行在QuartzScheduler中注冊的觸發觸發器的線程,并開始運行
走到就不在繼續逗留了,我們直接回到方法調用處去。
2.8、注冊監聽器,注冊Job和Trigger
里面不再點進去看如何注冊啦,想看的xdm,繼續去Debug就可以了~
到這里?SchedulerFactoryBean?初始化就算是完成了。接下來就是執行 start()方法
2.9、?SchedulerFactoryBean?執行start()方法
這里的start方法是bean的生命周期中的,我們關注的不是這里,
而是方法內部的?startScheduler(this.scheduler,this.startupDelay)?方法
這兩個不接著往下看啦~,疲啦 ...
添上紅字的這兩個就不繼續看,我們關注一下?this.resources.getJobStore().schedulerStarted();?,這也是下一步驟的開始~
2.10、創建Cluszaizaianager線程、創建MisfireHandler線程
我原本想關注一下?void recoverJobs()?方法
原本我是還想點進?executeInNonManagedTXLock()?方法繼續看一眼,直接看麻了,知道這里是恢復任務就行了,看起來很難受,里面更加龐大啦,主要是沒有思緒~
2.11、QuartzSchedulerThread開始執行run方法
置?QuartzSchedulerThread?的paused=false,調度線程真正開始調度,開始執行run方法
這才是調度的真正開始,前面都只能算是準備工作吧。
什么時候觸發,獲取線程執行任務,怎么查詢數據庫等等,可以說是從這里開始的。不過,咱們今天跑路了,明天或下次再來~
總結
以上是生活随笔為你收集整理的Quartz 的启动流程分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Hot_s 三子一线棋
- 下一篇: 我的iPhone奇遇记