Quartz是一個Java調度框架,當前的最新版本爲2.2.1。數據庫
以Quartz 2.2.1版爲例,Quartz最佳實踐(用於生產系統)總結以下:
一、跳過更新檢查
Quartz內置了一個「更新檢查」特性,所以Quartz項目每次啓動後都會檢查官網,Quartz是否存在新版本。這個檢查是異步的,不影響Quartz項目自己的啓動和初始化。
能夠在Quartz配置文件中,設置org.quartz.scheduler.skipUpdateCheck的屬性爲true來跳過更新檢查。
二、JobDataMap技巧
在JobDataMap應該只存儲原始的數據類型(包括字符串),這樣能夠避免數據序列化的問題以及長期運行的問題。
三、使用合併後的JobDataMap
官方推薦,Job.execute()方法一般應該從JobExecutionContext發現的JobDataMap中取回數據,而不是直接從JobDetail中取數據。
四、使用TriggerUtils
TriggerUtils工具類做用以下:
1)提供了一種更簡單的建立觸發器的方式;
2)提供了帶調度器建立觸發器的各類方法來知足特殊需求,與直接初始化特殊類型的觸發器(SimpleTrigger、CronTrigger),而後調用各類setter方法進行配置相反。
3)提供了更爲簡單的建立日期時間的方法;
4)提供了輔助類來分析觸發器(好比計算將來的激活次數等)。
五、必定不要直接寫數據到Quartz表
經過SQL語句寫調度數據到數據庫表,而不該該使用調度API來寫數據,由於:
1)會致使數據衝突(刪除數據、爭奪的數據)。
2)會致使當觸發器的激活時間到了時,Job會看起來不見了。
3)會致使當觸發器的激活時間到了時,Job會不執行,看起來「僅僅坐在那兒」。
4)可能會致使死鎖
5)還可能致使其餘奇怪的問題和數據崩潰等
六、必定不要把多個非集羣的調度器實例指向同一個數據庫表
若是把多個調度器實例指向同一個數據庫表,並且這些調度器實例沒有作集羣配置,那麼可能會發生:
1)會致使數據衝突(刪除數據、爭奪的數據)。
2)會致使當觸發器的激活時間到了時,Job會看起來不見了。
3)會致使當觸發器的激活時間到了時,Job會不執行,看起來「僅僅坐在那兒」。
4)可能會致使死鎖
5)還可能致使其餘奇怪的問題和數據崩潰等
七、確保適合的數據源鏈接數
官方推薦數據源的最大鏈接數應該配置爲線程池的最小工做線程數的3倍。若是你還須要額外的鏈接(好比頻繁地調用調度器API),若是還使用了JobStoreCMT,那麼非託管的數據源的最大鏈接數應該是至少4倍以上。
八、避免調度Job的時間安排在夏令時轉換的交界處
SimpleTrigger觸發器不受此影響。
九、等待條件
若是鏈接池全部的線程都處於繁忙狀態,那麼長期運行的Job會阻止其餘Job的運行。
若是在工做線程執行Job時調用Thread.sleep()後,Job餘下的工做有可能得不到執行,由於會等待一些條件(好比數據記錄有效後)爲真後再執行。
最佳的解決方案是釋放工做線程(退出Job),容許其餘Job在線程上獲得執行。Job能夠從新調度自身,或者等其餘Job在退出前調度它。
十、Job拋出異常
Job執行方法應該包含try-catch代碼塊,以處理各類可能發生的異常。
若是Job拋出異常,Quartz一般會當即從新執行(看起來會再次拋出一樣的異常)。最佳的方式是讓Job可以捕獲它可能會遇到的全部異常,處理這些異常,而後再重調度Job。
十一、可恢復性和冪等性
標記爲「可恢復的」、在進行中的Job在調度器失效後是能夠自動從新執行的。這意味着一樣的Job工做可能會執行兩次。
十二、在監聽器中保持代碼簡潔高效
不鼓勵監聽器內執行大量的工做,執行Job或完成觸發器並激活另外一個Job等,都應該綁定到監聽器。
1三、監聽器拋出異常
每一個監聽器(TriggerListener、JobListener和SchedulerListener)應該包含try-catch代碼塊,以處理各類可能發生的異常。
若是監聽器拋出異常,它或許會致使其餘監聽器得不到通知或阻止Job的執行等等。
1四、注意安全
一些開發者會經過應用程序的用戶接口暴露Quartz調度器的功能,這頗有用,但也很危險。由於惡意用戶能夠經過這種方式控制或破壞您的系統。安全