當應用服務器從單機擴展至多台-集群模式時,這種情況下,原有的簡單配置的定時任務調度方案肯定就行不通了。因為大多數定時任務都不具備冪等性,我們的預期一定也是在某一時刻觸發定時任務執行一次,而不是多次。
我們需要調整對Quarzt的集群控制,解決多台服務器並行運行同一個定時任務的問題。
主要思路:將JOB信息維護在DB里,使用標志位來控制(如enable=Y/N,“Y”表示使用中,“N”表示空閑)。應用節點上觸發某個JOB執行時,先查詢DB中該JOB的狀態:沒有運行,更新狀態為運行中,再開始執行;否則,跳過。
過程/步驟:
- 檢查Job是否在運行中(此處可以通過函數或過程來實現)
- 根據jobname、enable字段查找Job:(select job_id from job_config where job_id = (select job_id from job_define where job_name = #param.JobName#) for update nowait)
- 再根據job_id和enable='N'去更新config記錄,如果更新結果SQL%ROWCOUNT = 0 說明Job已經在運行中了,否則就是正常更新邏輯。
- 返回更新前job的狀態,提交事務
- 執行Job代碼塊邏輯
- 更新db中該job的配置
思考:
做完以上調整基本上已實現Quartz的集群控制,思考另外一個問題,“Job執行異常中斷時,沒有更新Job狀態為空閑狀態,這樣此job以后再也沒法觸發 了”--
--可以從檢查Job是否運行中的邏輯入手,前提所有的Job運行時長的邊界能明確界定
