SpringBoot定時任務:schedule、quartz

2020-12-14 馬家軍談Java

Scheduled

只適合處理簡單的計劃任務,不能處理分布式計劃任務。優勢:是spring框架提供的計劃任務,開發簡單,執行效率比較高。且在計劃任務數量太多的時候,可能出現阻塞,崩潰,延遲啟動等問題。

Scheduled定時任務是spring3.0版本之後自帶的一個定時任務。其所屬Spring的資源包為:spring-context-support。所以需要使用Scheduled定時任務機制時,需要在工程中依賴對應資源,具體如下:

如果在spring應用中需要啟用Scheduled定時任務,則需要在啟動類上增加註解@EnableScheduling,代表啟用Scheduled定時任務機制。具體如下:

Scheduled定時任務的核心在於註解@Scheduled,這個註解的核心屬性是cron,代表定時任務的觸發計劃表達式。這個表達式的格式為:

@Scheduled(cron="seconds minutes hours day month week")

@Scheduled(cron="seconds minutes hours day month week year")

推薦使用第一種表達式形式,因為在很多其他技術中都有不同的定時任務機制,其中用於設置觸發計劃的表達式都是第一種cron表達式。第二種表達式不能說是Spring Scheduled特有的,也是只有少數技術支持的。

cron表達式中,每個位置的約束如下:

星號(*):可用在所有欄位中,表示對應時間域的每一個時刻,例如,*在分鐘欄位時,表示「每分鐘」;

問號(?):該字符只在日期和星期欄位中使用,它通常指定為「無意義的值」,相當於佔位符;

減號(-):表達一個範圍,如在小時欄位中使用「10-12」,則表示從10到12點,即10,11,12;

逗號(,):表達一個列表值,如在星期欄位中使用「MON,WED,FRI」,則表示星期一,星期三和星期五;

斜槓(/):x/y表達一個等步長序列,x為起始值,y為增量步長值。如在秒數欄位中使用0/15,則表示為0,15,30和45秒,而5/15在分鐘欄位中表示5,20,35,50,你也可以使用*/y,它等同於0/y;

L:該字符只在日期和星期欄位中使用,代表「Last」的意思,但它在兩個欄位中意思不同。L在日期欄位中,表示這個月份的最後一天,如一月的31號,非閏年二月的28號;如果L用在星期中,則表示星期六,等同於7。但是,如果L出現在星期欄位裡,而且在前面有一個數值X,則表示「這個月的最後X天」,例如,6L表示該月的最後星期五;

W:該字符只能出現在日期欄位裡,是對前導日期的修飾,表示離該日期最近的工作日。例如15W表示離該月15號最近的工作日,如果該月15號是星期六,則匹配14號星期五;如果15日是星期日,則匹配16號星期一;如果15號是星期二,那結果就是15號星期二。但必須注意關聯的匹配日期不能夠跨月,如你指定1W,如果1號是星期六,結果匹配的是3號星期一,而非上個月最後的那天。W字符串只能指定單一日期,而不能指定日期範圍;

LW組合:在日期欄位可以組合使用LW,它的意思是當月的最後一個工作日;

井號(#):該字符只能在星期欄位中使用,表示當月某個工作日。如6#3表示當月的第三個星期五(6表示星期五,#3表示當前的第三個),而4#5表示當月的第五個星期三,假設當月沒有第五個星期三,忽略不觸發;

C:該字符只在日期和星期欄位中使用,代表「Calendar」的意思。它的意思是計劃所關聯的日期,如果日期沒有被關聯,則相當於日曆中所有日期。例如5C在日期欄位中就相當於日曆5日以後的第一天。1C在星期欄位中相當於星期日後的第一天。

Cron表達式對特殊字符的大小寫不敏感,對代表星期的縮寫英文大小寫也不敏感。

計劃任務Scheduled是通過一個線程池實現的。是一個多線程的調度。SpringBoot會初始化一個線程池,線程池默認大小為1,專門用於執行計劃任務。每個計劃任務啟動的時候,都從線程池中獲取一個線程執行,如果發生異常,只是執行當前任務的線程發生異常,而不是計劃任務調度線程發生異常。如果當前定時任務還未執行完成,當相同的定時任務又進入到執行周期時,不會觸發新的定時任務。如:

如結果所示(每次的線程名稱一致,由於前一個定時任務未執行完成,因此造成後一個任務的推遲,而不是1秒執行一次,而是3秒):

quartz

Quartz是OpenSymphony開源組織在Job scheduling領域又一個開源項目,它可以與J2EE與J2SE應用程式相結合也可以單獨使用。Quartz可以用來創建簡單或為運行十個,百個,甚至是好幾萬個Jobs這樣複雜的程序。

Quartz是一個完全由java編寫的開源作業調度框架。不要讓作業調度這個術語嚇著你。儘管Quartz框架整合了許多額外功能, 但就其簡易形式看,你會發現它易用得簡直讓人受不了!

在開發Quartz相關應用時,只要定義了Job(任務),Trigger(觸發器)和Scheduler(調度器),即可實現一個定時調度能力。其中Scheduler是Quartz中的核心,Scheduler負責管理Quartz應用運行時環境,Scheduler不是靠自己完成所有的工作,是根據Trigger的觸發標準,調用Job中的任務執行邏輯,來完成完整的定時任務調度。

Job - 定時任務內容是什麼。Trigger - 在什麼時間上執行job。Scheduler - 維護定時任務環境,並讓觸發器生效。

在SpringBoot中應用Quartz,需要依賴下述資源:

啟動器添加註解@EnableScheduling:

定義JOB任務以及JOB任務調用的模擬業務對象:

創建Trigger以及JobDetail對象,並用Schedule配置定時任務:

重寫JobFactory:

分布式quartz配置

1、資源依賴配置:由於分布式的原因,Quartz中提供分布式處理的jar包以及資料庫及連接相關的依賴。

2、提供資料庫相關配置:

3、提供Quartz配置信息,為Quartz提供資料庫配置信息,如資料庫,表格的前綴之類的。

4、初始化資料庫

建表語句可以自己在官方網站中查找(Quartz-lib中),使用tables-mysql.sql建表。

5、定義JOB類

啟動器和普通quartz無差異,但是JOB自身定義有些許差異:

6、QuartzConfiguration類型定義

相關焦點

  • 實戰Spring Boot 2.0系列:單機定時任務的幾種實現
    前言定時任務一般會存在 中大型企業級 項目中,為了減少 伺服器、資料庫 的壓力,往往會以 定時任務 的方式去完成某些業務邏輯。創建一個線程數量為 4 的 任務線程池,同一時刻並向它提交 4 個定時任務,用於測試延時任務的 並發處理。
  • Spring Boot實現定時任務新解,你是否能get到?
    在日常的開發過程中經常使用到定時任務,在springMVC的開發中,經常和quartz框架進行集成使用,但在springboot中沒有這麼做,而是使用了java的線程池來實現定時任務。一、概述在springboot中使用定時任務非常簡單,只需要簡單的幾步即可完成。
  • python定時任務管理
    '''def timedTask():''' 第一個參數: 延遲多長時間執行任務(單位: 秒) 第二個參數: 要執行的任務, 即函數 第三個參數: 調用函數的參數(tuple) '''Timer(10, task, ()).start()# 定時任務
  • Spring 整合 Quartz 分布式調度
    為了保證應用的高可用和高並發性,一般都會部署多個節點;對於定時任務,如果每個節點都執行自己的定時任務,一方面耗費了系統資源,另一方面有些任務多次執行,可能引發應用邏輯問題,所以需要一個分布式的調度系統,來協調每個節點執行定時任務。
  • Java實現終止線程池中正在運行的定時任務
    最近項目中遇到了一個新的需求,就是實現一個可以動態添加定時任務的功能。說到這裡,有人可能會說簡單啊,使用quartz就好了,簡單粗暴。然而quartz框架太重了,小項目根本不好操作啊。當然,也有人會說,jdk提供了timer的接口啊,完全夠用啊。
  • 為什麼你的 Spring Task 定時任務沒有定時執行?
    前言定時任務的使用,在開發中可謂是家常便飯了,定時發送郵件、簡訊。 避免資料庫,數據表過大,定時將數據轉儲。通知、對帳等等。當然實現定時任務的方式也有很多,比如使用 linux 下的 contab 腳本,jdk 中自帶的 Timer 類。
  • 幾種任務調度的 Java 實現方法與比較
    Timer 的優點在於簡單易用,但由於所有任務都是由同一個線程來調度,因此所有任務都是串行執行的,同一時間只能有一個任務在執行,前一個任務的延遲或異常都將會影響到之後的任務。;import org.quartz.JobDetail;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import org.quartz.Scheduler;import org.quartz.SchedulerFactory;import org.quartz.Trigger;import
  • Uncode-Schedule 1.0.3 發布,分布式任務調度組件
    Uncode-Schedule分布式任務調度組件,非常小巧,無需任何修改就可以使quartz/spring task具備分布式特性
  • 定時後臺運行Python程序
    大型程序中經常會需要定時運行某些任務,比如生成報表,發郵件等。複雜的方法會用到消息隊列,用API調用一個接口定時運行你的任務。簡單的用Cron或者Windows裡的計劃任務。而Python提供了一個更簡單的方法。Cron需要的是給出一行指定時間範圍。
  • 定時任務實現原理詳解
    一、摘要在很多業務的系統中,我們常常需要定時的執行一些任務,例如定時發簡訊、定時變更數據、定時發起促銷活動等等。在上篇文章中,我們簡單的介紹了定時任務的使用方式,不同的架構對應的解決方案也有所不同,總結起來主要分單機和分布式兩大類,本文會重點分析下單機的定時任務實現原理以及優缺點,分布式框架的實現原理會在後續文章中進行分析。
  • Python定時任務(上)
    Photo from Unsplash 在項目中,我們可能遇到有定時任務的需求其一:定時執行任務。例如每天早上 8 點定時推送早報。其二:每隔一個時間段就執行任務。比如:每隔一個小時提醒自己起來走動走動,避免長時間坐著。今天,我跟大家分享下 Python 定時任務的實現方法。第一種辦法是最簡單又最暴力。
  • 《堡壘之夜》車輛定時實驗任務攻略 車輛定時實驗任務怎麼完成
    導 讀 堡壘之夜第6賽季第10周更新了不少任務,車輛定時實驗正是當中之一,該任務需要宣召光標,那麼這些光標位置在哪
  • 深入 Java Timer 定時任務調度器實現原理
    點擊上方「linkoffer」,選擇關注公眾號高薪職位第一時間送達使用 Java 來調度定時任務時
  • 一日一技:為什麼不建議使用 time.sleep 實現定時功能?
    有時候,我們想實現一個非常簡單的定時功能,例如讓一個程序每天早上8點調用某個函數。
  • opencron v1.0.1 發布,分布式任務調度系統
    opencron 是一個功能完善且通用的開源定時任務調度系統,擁有先進可靠的自動化任務管理調度功能,提供可操作的web圖形化管理滿足多種場景下各種複雜的定時任務調度
  • Python 中為什麼不建議使用 time.sleep 實現定時功能?
    有時候,我們想實現一個非常簡單的定時功能
  • Springboot @EnableWebMvc 註解
    }並且如果容器中存在  WebMvcConfigurationSupport 這個類,那麼 springboot 對於 springmvc 的自動配置將會失效可以看到這個類中都是一些空方法,只是保留了最基本的 MVC 的功能,並不具備其它的擴展功能如下:springboot 對於 mvc 模塊的配置就在 WebMvcAutoConfiguration
  • SpringBoot開發常用的註解及作用
    隨著網際網路的快速發展,不斷的湧出新的技術,springboot是什麼呢?springboot它是spring開源組織下的子項目,主要是用來簡化spring的難度以及不足,節省程式設計師的繁重的配置,為程式設計師開發過程中各種啟動器。