Quartz學習之入門學習

簡介

Quartz是一個開源的做業調度框架,可讓計劃的程序任務一個預約義的日期和時間運行。Quartz能夠用來建立簡單或複雜的日程安排執行幾十,幾百,甚至是十萬的做業數。
官方連接,戳這裏html

Quartz是什麼?

做業調度庫

Quartz 是一種功能豐富的,開放源碼的做業調度庫,能夠在幾乎任何Java應用程序集成 - 從最小的獨立的應用程序到規模最大電子商務系統。Quartz能夠用來建立簡單或複雜的日程安排執行幾十,幾百,甚至是十萬的做業數 - 做業被定義爲標準的Java組件,能夠執行幾乎任何東西,能夠編程讓它們執行。 Quartz調度包括許多企業級功能,如JTA事務和集羣支持。java

Quartz 是可自由使用,使用Apache 2.0 license受權方式。數據庫

做業調度

若是應用程序須要在給定時間執行任務,或者若是系統有連續維護做業,那麼Quartz是理想的解決方案。編程

做業被安排在一個給定的觸發時運行。觸發器可使用如下指令的接近任何組合來建立:負載均衡

  • 在一天中的某個時間(到毫秒)
  • 在一週的某幾天
  • 在每個月的某一天
  • 在一年中的某些日期
  • 不在註冊的日曆中列出的特定日期(如商業節假日除外)
  • 重複特定次數
  • 重複進行,直到一個特定的時間/日期
  • 無限重複
  • 重複的延遲時間間隔

做業是由其建立者賦予的名字,也能夠組織成命名組。觸發器也能夠給予名稱和放置在組中,以方便地將它們調度內組織。做業能夠被添加到所述調度器一次,而是具備多個觸發器註冊。在企業Java環境中,做業能夠執行本身的工做做爲分佈式(XA)事務的一部分。框架

集羣

  • 故障切換
  • 負載均衡
  • Quartz的內置的羣集功能,經過JDBCJobStore依靠數據庫持久
  • Terracotta擴展Quartz提供集羣功能,而不須要一個支持數據庫

使用的 jar 包

  • quartz-2.2.1.jar
  • quartz-jobs-2.2.1.jar

三個重要的概念簡介

Scheduler

調度器。全部的調度都是由它控制。調度類連接「工做」和「觸發器」到一塊兒,並執行它。分佈式

scheduler 實例化後,能夠啓動(start)、暫停(stand-by)、中止(shutdown)。注意:scheduler 被中止後,除非從新實例化,不然不能從新啓動;只有當 scheduler 啓動後,即便處於暫停狀態也不行,trigger 纔會被觸發(job纔會被執行)ide

Scheduler的生命期,從SchedulerFactory建立它時開始,到Scheduler調用shutdown()方法時結束;Scheduler被建立後,能夠增長、刪除和列舉Job和Trigger,以及執行其它與調度相關的操做(如暫停Trigger)。可是,Scheduler只有在調用start()方法後,纔會真正地觸發trigger(即執行job)函數

Scheduler scheduler = new StdSchedulerFactory().getScheduler();
scheduler.start();
scheduler.scheduleJob(job, trigger);

Scheduler的主要函數:測試

  • start():啓動
  • standby():掛起
  • shutdown():關閉
  • shutdown(true)表示等待全部正在執行的job執行完畢後,在關閉scheduler
  • shutdown(false)即shutdown()表示直接關閉scheduler

注意關閉以後,scheduler不能重新開啓,會拋出異常

Trigger

Trigger用於觸發Job的執行。當你準備調度一個job時,你建立一個Trigger的實例,而後設置調度相關的屬性。Trigger也有一個相關聯的JobDataMap,用於給Job傳遞一些觸發相關的參數。Quartz自帶了各類不一樣類型的Trigger,最經常使用的主要是SimpleTrigger和CronTrigger。

  • SimpleTrigger – 容許設置開始時間,結束時間,重複間隔。主要用於一次性執行的Job(只在某個特定的時間點執行一次),或者Job在特定的時間點執行,重複執行N次,每次執行間隔T個時間單位。
  • CronTrigger – 容許UNIX cron表達式來指定日期和時間來運行做業。在基於日曆的調度上很是有用,如「每一個星期五的正午」,或者「每個月的第十天的上午10:15」等。

SimpleTrigger – 每5秒運行

Trigger trigger = TriggerBuilder
    .newTrigger()
    .withIdentity("dummyTriggerName", "group1")
    .withSchedule(
        SimpleScheduleBuilder.simpleSchedule()
        .withIntervalInSeconds(5).repeatForever())
    .build();

CronTrigger – 每5秒運行。

Trigger trigger = TriggerBuilder
    .newTrigger()
    .withIdentity("dummyTriggerName", "group1")
    .withSchedule(
        CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))
    .build();

JobDetail & Job

JobDetail 定義的是任務數據,而真正的執行邏輯是在Job中。

JobDetail對象是在將job加入scheduler時,由客戶端程序(你的程序)建立的。它包含job的各類屬性設置,以及用於存儲job實例狀態信息的JobDataMap。

例子說明

1.下載 jar 包

能夠從官方網站或 Maven 中央存儲庫下載 Quartz 庫文件;

2.建立一個做業

HelloJob.java

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class HelloJob implements Job{

    @Override
    public void execute(JobExecutionContext arg0) throws JobExecutionException {
        // TODO Auto-generated method stub
        System.out.println("Hello Quartz!");
    }
}

3.建立觸發器,以及經過調度執行做業

SimpleTrigger.java

import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;

public class SimpleTrigger {

    public static void main(String[] args) throws Exception {

        JobDetail job = JobBuilder.newJob(HelloJob.class)
                .withIdentity("dummyJobName", "group1").build();

         // 定義一個Trigger
        Trigger trigger = TriggerBuilder
                .newTrigger()
                .withIdentity("dummyTriggerName", "group1")        // 定義 name/group
                .withSchedule(
                        SimpleScheduleBuilder.simpleSchedule()
                                .withIntervalInSeconds(5).repeatForever())
                .build();
        
        Scheduler scheduler = new StdSchedulerFactory().getScheduler();
        scheduler.start();
        scheduler.scheduleJob(job, trigger);
    }
}

CronTrigger.java

import org.quartz.CronScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;

public class CronTrigger {

    public static void main(String[] args) throws Exception {
        JobDetail job = JobBuilder.newJob(HelloJob.class)
                .withIdentity("dummyJobName", "group").build();

        Trigger trigger = TriggerBuilder
                .newTrigger()
                .withIdentity("dummyJobName", "group")
                .withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))
                .build();

        Scheduler scheduler = new StdSchedulerFactory().getScheduler();
        scheduler.start();
        scheduler.scheduleJob(job, trigger);
    }
}

輸出的結果以下:

每隔五分鐘就會打印出一條 Hello Quartz!

Hello Quartz!
Hello Quartz!
Hello Quartz!

Quartz 的其餘概念

JobExecutionContext

  • 當 Schedule 調用一個 Job,就會將 JobExecutionContext 傳遞給 Job 的 execute() 方法
  • Job 能經過 JobExecutionContext 對象訪問到 Quartz 運行時候的環境以及 Job自己的明細數據

JobDataMap

  • 在進行任務調度時 JobDataMap存儲在JobExecutionContext中,很是方便獲取
  • JobDataMap 能夠用來裝載任何可序列化的數據對象,當job 實例對象被執行時這些參數對象會傳遞給它
  • JobDataMap實現了JDK的Map接口,而且添加了一些很是方便的方法用來存取數據基本類型

key

  • 將Job和Trigger註冊到Scheduler時,能夠爲它們設置key,配置其身份屬性。
  • Job和Trigger的key(JobKey和TriggerKey)能夠用於將Job和Trigger放到不一樣的分組(group)裏,而後基於分組進行操做。
  • 同一個分組下的Job或Trigger的名稱必須惟一,即一個Job或Trigger的key由名稱(name)和分組(group)組成。

實例說明

第一步:建立一個 Job。

在這個類中,咱們經過 JobExecutionContext 來獲取 JobDataMapkey以及經過自定義傳入的信息。代碼中有備註,仔細看下就知道了。

HelloJob.java

import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.quartz.TriggerKey;

public class HelloJob implements Job{

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        // TODO Auto-generated method stub
        System.out.println("Hello Quartz!");
        
        // 獲取 JobDetail 的 key 和 group
        JobKey key = context.getJobDetail().getKey();
        System.out.println("JobDetail key name: "+key.getName());
        System.out.println("JobDetail key Group: "+key.getGroup());
        
        // 從 JobExecutionContext 中獲取一個實例,  獲取從 jobDetail 傳入的數據
        JobDataMap dataMap = context.getJobDetail().getJobDataMap();
        String JobMsg = dataMap.getString("message");
        Float floatMsg = dataMap.getFloat("floatData");
        System.out.println("JobDetial:"+ JobMsg);
        System.out.println("floatMsg:"+ floatMsg);
        
        //獲取 trigger 的 key 和 group
        TriggerKey triggerKey = context.getTrigger().getKey();
        System.out.println("TriggerKey key name: "+triggerKey.getName());
        System.out.println("TriggerKey key Group: "+triggerKey.getGroup());
        
        // 獲取一個 trigger 的 jobDataMap 實例
        JobDataMap triggerMap = context.getTrigger().getJobDataMap();
        String triggerMsg = dataMap.getString("message");
        System.out.println("triggerMsg:"+ triggerMsg);
    }
}

第二步:測試類

import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;

public class SimpleTrigger {

    public static void main(String[] args) throws Exception {

        JobDetail job = JobBuilder.newJob(HelloJob.class)
                .withIdentity("dummyJobName", "group1")
                .usingJobData("message", "hello myJob1")    //傳入自定義的數據
                .usingJobData("floatData", 1.2F)
                .build();

         // 定義一個Trigger
        Trigger trigger = TriggerBuilder
                .newTrigger()
                .withIdentity("dummyTriggerName", "group1")        // 定義 name/group
                .usingJobData("message", "hello myTrigger")
                .withSchedule(
                        SimpleScheduleBuilder.simpleSchedule()
                                .withIntervalInSeconds(5).repeatForever())
                .build();
        
        Scheduler scheduler = new StdSchedulerFactory().getScheduler();
        scheduler.start();
        scheduler.scheduleJob(job, trigger);
    }
}

輸出結果

Hello Quartz!
JobDetail key name: dummyJobName
JobDetail key Group: group1
JobDetial:hello myJob1
floatMsg:1.2
TriggerKey key name: dummyTriggerName
TriggerKey key Group: group1
triggerMsg:hello myJob1

相關文章
相關標籤/搜索