SpringBoot2.0實戰 | 第三十三章:整合Quartz之最簡配置

在前面的文章中,我們已實現了在 SpringBoot 項目中執行定時任務

但是,自帶的定時任務有其侷限性,比如在分佈式環境中無法協調多節點,就會導致一個任務會在多個節點同時執行。
接下來,我們將實現對開源作業調度框架 Quartz 的整合。

相關知識

什麼是 Quartz

Quartz 是一個完全由 Java 編寫的開源作業調度框架,爲在 Java 應用程序中進行作業調度提供了簡單卻強大的機制。

Quartz 的特點

作爲一個優秀的開源調度框架,Quartz 具有以下特點:

  • 強大的調度功能,例如支持豐富多樣的調度方法,可以滿足各種常規及特殊需求
  • 靈活的應用方式,例如支持任務和調度的多種組合方式,支持調度數據的多種存儲方式
  • 分佈式和集羣能力,Terracotta 收購後在原來功能基礎上作了進一步提升
  • Quartz 很容易與 Spring 集成實現靈活可配置的調度功能

Quartz 相關概念

  • scheduler:任務調度器

Quartz 提供了 DirectSchedulerFactory 及 StdSchedulerFactory 工廠類用於創建。通常使用 StdSchedulerFactory 進行創建。

  • trigger:觸發器,用於定義任務調度時間規則。

Quartz 中主要提供了四種類型的 trigger:SimpleTrigger,CronTirgger,DateIntervalTrigger,和 NthIncludedDayTrigger。這四種 trigger 可以滿足企業應用中的絕大部分需求。

  • job:被調度的任務,一個 job 可以被多個 trigger 關聯,但是一個 trigger 只能關聯一個 job

job 有兩種類型:無狀態的(stateless)和有狀態的(stateful)。
對於同一個 trigger 來說,有狀態的 job 不能被並行執行,只有上一次觸發的任務被執行完之後,才能觸發下一次執行。
Job 主要有兩種屬性:volatility 和 durability,
其中 volatility 表示任務是否被持久化到數據庫存儲,
而 durability 表示在沒有 trigger 關聯的時候任務是否被保留。
兩者都是在值爲 true 的時候任務被持久化或保留。

目標

簡單整合 Quartz,實現使用 Quartz 執行定時任務

操作步驟

添加依賴

引入 Spring Boot Starter 父工程

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.5.RELEASE</version>
</parent>

添加 spring-boot-starter-quartz 的依賴,添加後的整體依賴如下

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-quartz</artifactId>
    </dependency>
</dependencies>

編碼

編寫定時任務執行類
  • @DisallowConcurrentExecution 用於處理任務併發執行的問題。
  • @PersistJobDataAfterExecution 成功執行了job類的execute方法後(沒有發生任何異常),更新JobDetail中JobDataMap的數據,
    使得該job(即JobDetail)在下一次執行的時候,JobDataMap中是更新後的數據,而不是更新前的舊數據。
    最好與 @DisallowConcurrentExecution 註解同時使用,以防止併發造成 JobDataMap 中存儲的數據不確定。
@Data
@DisallowConcurrentExecution
@PersistJobDataAfterExecution
public class TimeJob extends QuartzJobBean {

    private String name;

    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        System.out.println("execute timeJob at " +
                LocalDateTime.now().format(DateTimeFormatter.ofPattern("hh:mm:ss")) +
                ": hello " + this.name);
    }

}
註冊定時任務
  • 註冊 JobDetail,內部維護了一個 JobDataMap 數據容器與外界進行交互,可以通過 usingJobData 方法,爲定時任務傳遞數據
  • 註冊 Trigger,關聯 JobDetail,並設置定時任務執行策略
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
    
    @Bean
    public JobDetail sampleJobDetail() {
        return JobBuilder.newJob(TimeJob.class).withIdentity("timeJob")
                .usingJobData("name", "Quartz").storeDurably().build();
    }

    @Bean
    public Trigger sampleJobTrigger() {
        // 如果需要使用 cronExpression 表達式,則使用 CronScheduleBuilder 進行創建
        SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
                .withIntervalInSeconds(2).repeatForever();

        return TriggerBuilder.newTrigger().forJob(sampleJobDetail())
                .withIdentity("timeTrigger").withSchedule(scheduleBuilder).build();
    }

}

驗證

啓動項目,查看日誌

execute timeJob at 08:24:06: hello Quartz
execute timeJob at 08:24:08: hello Quartz
execute timeJob at 08:24:10: hello Quartz

源碼地址

本章源碼 : https://gitee.com/gongm_24/spring-boot-tutorial.git

結束語

本文實現了對 Quartz 框架的基本整合,通過硬編碼實現任務及執行策略的註冊。
接下來我們將實現動態管理任務及執行策略,包括增刪查改、暫停及重啓任務,敬請期待。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章