定時調度
做爲後端開發人員,咱們總會遇到這樣的業務場景:每週同步一批數據;每半個小時檢查一遍服務器運行情況;天天早上八點給用戶發送一份包含今日待辦事項的郵件,等等。java
這些場景中都離不開「定時器」,就像一個定好時間規則的鬧鐘,它會在指定時間觸發,執行咱們想要定義的調度任務。那麼咱們今天就來數一下,那些年咱們用過的「定時調度」。linux
1.job (oracle)
從剛工做就一直使用oracle數據庫,最先接觸的定時任務就是oracle數據庫的job。job有定時執行的功能,能夠在指定的時間點或天天的某個時間點自行執行任務。 並且oracle從新啓動後,job會繼續運行,不用從新啓動。
並且job的機制很是完備,能夠查詢相關的表或視圖,查詢job的定時規則和執行狀況。缺點是做爲oracle數據庫層面的工具,自定義功能擴展,二次開發的難度比較大。spring
1.1 建立job數據庫
1.2 刪除jobwindows
1.3 查詢job
2.crontab (linux)
crond 是linux下用來週期性的執行某種任務或等待處理某些事件的一個守護進程,與windows下的計劃任務相似,當安裝完成操做系統後,默認會安裝此服務 工具,而且會自動啓動crond進程,crond進程每分鐘會按期檢查是否有要執行的任務,若是有要執行的任務,則自動執行該任務。後端
cron是服務名稱,crond是後臺進程,crontab則是定製好的計劃任務表。大部分linux系統默認都安裝了cron,能夠檢查一下。springboot
crontab基本操做命令服務器
crontab表達式格式併發
3.Timer和ScheduledExecutorService (java)
Timer是jdk中提供的一個定時器工具,使用的時候會在主線程以外起一個單獨的線程執行指定的計劃任務,能夠指定執行一次或者反覆執行屢次。oracle
TimerTask是一個實現了Runnable接口的抽象類,表明一個能夠被Timer執行的任務。
TimerTask類是一個抽象類,由Timer 安排爲一次執行或重複執行的任務。它有一個抽象方法run()方法,該方法用於執行相應計時器任務要執行的操做。所以每個具體的任務類都必須繼承TimerTask,而後重寫run()方法。 另外它還有兩個非抽象的方法
固然,通常使用Timer的比較少,由於它的缺點比較明顯:
1.單線程,當多個timer同時運行時,會等上一個執行完成,再執行下一個。
2.Timer線程是不會捕獲異常的,若是TimerTask拋出的了未檢查異常則會致使Timer線程終止。
因此通常使用ScheduledExecutorService替代Timer。 ScheduledExecutorService:也是jdk自帶的一個基於線程池設計的定時任務類。其每一個調度任務都會分配到線程池中的一個線程執行,因此其任務是併發執行的,互不影響。
4.SpringTask (spring)
Timer和ScheduledExecutorService都是屬於jdk層面上實現定時調度的類,功能還不足以讓咱們滿意,那麼如今介紹一個比較完善的定時調度工具 - SpringTask,是Spring提供的,支持註解和配置文件形式,支持crontab表達式,使用簡單但功能強大。我我的很是喜歡SpringTask,僅僅是由於支持crontab表達式。
在springboot裏面使用方式很是簡單:
1.啓動類添加開啓定時調度的註解 @EnableScheduling
2.在須要定時執行的方法上,增長註解 @Scheduled(cron ="crontab表達式")
默認的簡單的使用步驟只有以上兩步,可是SpringTask的默認使用方式也有一些不足:
1.默認線程池的poolsize爲1,能夠理解爲Timer相似的單線程模式。
沒法動態修改crontab表達式,修改完只能從新部署後,才能生效。
問題1的解決方式,能夠經過自定義 TaskExecutor來修改當前的線程池。問題2,則能夠直接使用 threadPoolTaskScheduler類實現自定義的定時調度規則。
附解決兩個問題的源碼 TaskTimer.class
5.Quartz (其餘產品)
Quartz是一個徹底由 Java 編寫的開源做業調度框架,爲在 Java 應用程序中進行做業調度提供了簡單卻強大的機制。它是一個功能強大、十分紅熟的重量級產品,還支持負載均衡,實現分佈式調度。
不過,對於Quartz的安裝你要多花點功夫了,從數據庫要建哪些表,到應用程序該如何部署。對於這樣一個龐大的產品,本篇文章就不附上它的使用說明書了。
本人創業團隊產品MadPecker,主要作BUG管理、測試管理、應用分發,網址:www.madpecker.com,有須要的朋友歡迎試用、體驗!本文爲MadPecker團隊技術人員編寫,轉載請標明出處