精通Quartz-01入門介紹和簡單示例

1 Quartz 簡介

Quartz 是基於Java 實現的一個開源的調度框架, 是開源組織OpenSymphony 的產品。該項目於 2009 年被 Terracotta 收購,目前是 Terracotta 旗下的一個項目。官方網站:www.quartz-scheduler.org/ 。java

本人在產品開發中使用的是版本 2.3.0,所以本文內容也基於該版本。
web

2 Quartz功能及特色

運行環境 spring

Quartz 能經過JVM獨立運行
apache

 Quartz 能在一個應用服務器裏被實例化(或servlet容器), 而且能夠做爲XA事務的一部分來運行springboot

 Quartz 能被集羣化部署運行, 也能夠單機方式運行bash

任務調度

任務有多種調度方式, 很是靈活:服務器

  • 指定按某個時間間隔無限循環,例,每3分鐘,每30秒
  • 指定到一天的某個時間點(精確到毫秒級), 例,天天的01:00:00, 天天的17:25:30
  • 指定只在一個固定時間點運行,例 2019-05-22 13:52:20
  • 經過Calendar排除某些時間 (例如節假日)
  • 循環重複的更靈活配置等等

任務執行

  • 任務能夠是任何實現Job接口的Java類。一個任務能夠有多種調度方式,任務與調度之間是解耦的,可自由組合。

任務持久化

  • 能夠經過配置JobStoreCMT或JobStoreTX,能夠實現任務的持久化。
  • 經過配置RAMJobStore, 能夠將任務和觸發器存儲在內存裏,運行性能更高。

事務

  • 使用JobStoreCMT(JDBCJobStore的子類),Quartz任務能做爲JTA事務的一部分運行。

集羣

開啓集羣模式部署運行後,系統具備集羣的通用特性框架

  • Fail-over  
  • Load balancing  

監聽器和插件

  • 經過實現一個或多個監聽接口,應用程序能捕捉調度事件來監控或控制任務/觸發器的行爲。
  • 插件機制能夠給Quartz增長功能,例如保持任務執行的歷史記錄,或從一個定義好的文件里加載任務和觸發器。
  • Quartz 在運行過程當中,不少地方都會回調監聽器和插件。

容易與Spring集成maven

做爲 Spring 默認的調度框架,Quartz 很容易與 Spring 集成ide

3 核心元素

Quartz 核心元素之間的關係以下圖所示:

圖 1. Quartz 核心元素關係圖

圖 1. Quartz 核心元素關係圖


Quartz 任務調度的核心元素是 scheduler, trigger 和 job,其中 trigger 和 job 是任務調度的元數據, scheduler 是實際執行調度的控制器。scheduler 由 schedulerFactory建立, 默認實現是 StdSchedulerFactory。 

4.簡單實例

本文爲了方便介紹Quartz, 使用springboot來搭建項目,maven的pom文件以下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.6.RELEASE</version>
        <!-- <relativePath></relativePath> -->
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>springboot-job</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- Quartz -->
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.3.0</version>
        </dependency>
        <!--代碼更簡潔-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.14</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
</project>複製代碼

添加代碼HelloJob

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Calendar;
import java.util.concurrent.TimeUnit;

/**
 * 第一個Quartz Job
 * @author 深谷
 */
public class HelloJob implements Job {
    
    private static Logger log = LoggerFactory.getLogger(HelloJob.class);
    
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        log.info("HelloJob 任務正在執行,當前時間: {}", Calendar.getInstance().getTime());
    }


    public static void main(String[] args) throws Throwable {
        SchedulerFactory factory = new StdSchedulerFactory();
        // 從工廠裏面拿到一個scheduler實例
        Scheduler scheduler = factory.getScheduler();
        String name = "name_1";
        // 真正執行的任務並非Job接口的實例,而是用反射的方式實例化的一個JobDetail實例
        JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity(name, null).build();
        // 定義一個觸發器,調度策略是每隔30秒執行一次
        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/30 * * * * ?").withMisfireHandlingInstructionDoNothing();
        Trigger trigger = TriggerBuilder.newTrigger().withIdentity(name, null).withSchedule(cronScheduleBuilder).build();
        // 將任務和Trigger放入scheduler
        scheduler.scheduleJob(job, trigger);
        scheduler.start();
        // 休眠一分鐘,以便任務能夠執行
        TimeUnit.MINUTES.sleep(1L);
        // scheduler結束
        scheduler.shutdown(true);
    }
}複製代碼

運行一下,看一下輸出

11:36:08.021 logback [main] INFO  org.quartz.core.QuartzScheduler[initialize-294] - Scheduler meta-data: Quartz Scheduler (v2.3.0) 'DefaultQuartzScheduler' with instanceId 'NON_CLUSTERED'
  Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
  NOT STARTED.
  Currently in standby mode.
  Number of jobs executed: 0
  Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.
  Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.

11:36:08.021 logback [main] INFO  org.quartz.impl.StdSchedulerFactory[instantiate-1362] - Quartz scheduler 'DefaultQuartzScheduler' initialized from default resource file in Quartz package: 'quartz.properties'
11:36:08.021 logback [main] INFO  org.quartz.impl.StdSchedulerFactory[instantiate-1366] - Quartz scheduler version: 2.3.0
11:36:08.035 logback [main] INFO  org.quartz.core.QuartzScheduler[start-547] - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started.
11:36:30.017 logback [DefaultQuartzScheduler_Worker-1] INFO  com.ff.job.HelloJob[execute-21] - HelloJob 任務正在執行,當前時間: Thu Dec 06 11:36:30 CST 2018
11:37:00.004 logback [DefaultQuartzScheduler_Worker-2] INFO  com.ff.job.HelloJob[execute-21] - HelloJob 任務正在執行,當前時間: Thu Dec 06 11:37:00 CST 2018
11:37:08.036 logback [main] INFO  org.quartz.core.QuartzScheduler[shutdown-666] - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED shutting down.
複製代碼
相關文章
相關標籤/搜索