spring中的任務調度Quartz quartz 不一樣時間間隔調度任務

Spring 整合 Quartz 任務調度

  主要有兩種方式。html

  Quartz的官網:http://www.quartz-scheduler.org/spring

  這兩種只是一些配置文件簡單配置就OK了,可是根本沒法明白其中的內涵所在,在上一篇的   quartz 不一樣時間間隔調度任務  有所介紹,能夠仔細參考併發

  話很少說直接上方案ide

  第一種:xml配置形式


 

  第一步post

  以Maven形式添加依賴url

   <dependency>
      <groupId>org.quartz-scheduler</groupId>
      <artifactId>quartz</artifactId>
      <version>2.2.3</version>
    </dependency>
    <dependency>
      <groupId>org.quartz-scheduler</groupId>
      <artifactId>quartz-jobs</artifactId>
      <version>2.2.3</version>
    </dependency>

  第二步spa

  配置xml   spring-quartz.xml  線程

  你須要將這個配置<import resource="spring-quartz.xml"></import>到你的spring中code

  這其中也沒啥orm

  建立 MethodInvokingJobDetailFactoryBean  基本屬性的配置 須要執行的任務類方法

  建立 CronTriggerFactoryBean                       主要是觸發任務的,配置任務觸發的時間,能夠又多個觸發器

  建立 SchedulerFactoryBean       調度工廠的做用,你們都把任務放入其中,在其中執行

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd"
       default-autowire="byType">
    <!-- ======================== 任務 Task配置 ======================== -->
    <!--由MethodInvokingJobDetailFactoryBean實現-->
    <bean id="WxPayBillTask" class="com.jlnku.task.WxPayBillTask"></bean>
    <bean id="importOneJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="WxPayBillTask" />          <!--//執行類的實例-->
        <property name="targetMethod" value="run" />                   <!--//執行方法-->
        <property name="concurrent" value="false" />
        <property name="arguments">
            <list></list>
        </property>
    </bean>

    <!-- ======================== 配置定時調度 觸發器 ======================== -->
    <!--由CronTriggerFactoryBean實現-->
    <bean id="cronTrigger2" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="jobDetail" ref="importOneJob" />                <!-- //上面任務的Task配置bean-->
        <property name="cronExpression" value="0 02 17 ? * *"  />         <!--//觸發時機表達式  cron表達式在文章的最末尾會說-->
    </bean>
    <!-- ======================== 調度工廠(中心調度器) ======================== -->
    <bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"
          autowire="no">
        <property name="triggers">
            <list>
                <ref bean="cronTrigger2" />                           <!--//上面配置的觸發器-->
            </list>
        </property>
    </bean>
</beans>

  第三步

  建立你的任務,以線程的形式

  其中寫你的須要調度的任務邏輯,根據需求編寫再次 方法中就ok

/**
 * @author zhouguanglin
 * @date 2018/7/5 15:08
 */
@Component("WxPayBillTask")
public class WxPayBillTask implements Runnable{
    @Autowired
    WXPayService wxPayService;
    @Override
    public void run() {
        try {
            SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            calendar.add(Calendar.DATE, -6);
            String date = df.format(calendar.getTime());
            wxPayService.insertWxDownloadBill(null, null, date);
        } catch (Exception e) {

        }
    }
}

  第二種:註解形式


 

  第一步

  加入依賴

   <!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->
    <dependency>
        <groupId>org.quartz-scheduler</groupId>
        <artifactId>quartz</artifactId>
        <version>2.2.1</version>
    </dependency>

  第二步

  在Spring配置開啓task任務註解 ,注意你的類也是須要被掃描到的

<!-- task -->
<task:annotation-driven />

  第三步

  本身隨便建立一個任務調度的類,內部寫和調用本身的邏輯

  

@Component
public class JobDemo {
    @Autowired
    WXPayService wxPayService;
    @Scheduled(cron = "5 * * * * ?")
    public void FaceBookMessage() {
        System.out.println("----------------------------任務調度器---------------------------");
    }


    @Scheduled(cron = "0 43 17 ? * *")
    public void wxPayBillTask(){
        try {
            SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            calendar.add(Calendar.DATE, -1);
            String date = df.format(calendar.getTime());
            wxPayService.insertWxDownloadBill(null, null, date);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

  這樣就完事了


 

Trigger


 

在開始詳解每一種Trigger以前,須要先了解一下Trigger的一些共性。

StartTime & EndTime

startTime和endTime指定的Trigger會被觸發的時間區間。在這個區間以外,Trigger是不會被觸發的。

** 全部Trigger都會包含這兩個屬性 **

優先級(Priority)

當scheduler比較繁忙的時候,可能在同一個時刻,有多個Trigger被觸發了,但資源不足(好比線程池不足)。那麼這個時候比剪刀石頭布更好的方式,就是設置優先級。優先級高的先執行。

須要注意的是,優先級只有在同一時刻執行的Trigger之間纔會起做用,若是一個Trigger是9:00,另外一個Trigger是9:30。那麼不管後一個優先級多高,前一個都是先執行。

優先級的值默認是5,當爲負數時使用默認值。最大值彷佛沒有指定,但建議遵循Java的標準,使用1-10,否則鬼才知道看到【優先級爲10】是時,上頭還有沒有更大的值。

Misfire(錯失觸發)策略

相似的Scheduler資源不足的時候,或者機器崩潰重啓等,有可能某一些Trigger在應該觸發的時間點沒有被觸發,也就是Miss Fire了。這個時候Trigger須要一個策略來處理這種狀況。每種Trigger可選的策略各不相同。

這裏有兩個點須要重點注意:

  • MisFire的觸發是有一個閥值,這個閥值是配置在JobStore的。比RAMJobStore是org.quartz.jobStore.misfireThreshold。只有超過這個閥值,纔會算MisFire。小於這個閥值,Quartz是會所有從新觸發。

全部MisFire的策略實際上都是解答兩個問題:

  1. 已經MisFire的任務還要從新觸發嗎?
  2. 若是發生MisFire,要調整現有的調度時間嗎?

好比SimpleTrigger的MisFire策略有:

  • MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY

    這個不是忽略已經錯失的觸發的意思,而是說忽略MisFire策略。它會在資源合適的時候,從新觸發全部的MisFire任務,而且不會影響現有的調度時間。

    好比,SimpleTrigger每15秒執行一次,而中間有5分鐘時間它都MisFire了,一共錯失了20個,5分鐘後,假設資源充足了,而且任務容許併發,它會被一次性觸發。

    這個屬性是全部Trigger都適用。

  • MISFIRE_INSTRUCTION_FIRE_NOW

    忽略已經MisFire的任務,而且當即執行調度。這一般只適用於只執行一次的任務。

  • MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT

    將startTime設置當前時間,當即從新調度任務,包括的MisFire的

  • MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT

    相似MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT,區別在於會忽略已經MisFire的任務

  • MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT

    在下一次調度時間點,從新開始調度任務,包括的MisFire的

  • MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT

    相似於MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT,區別在於會忽略已經MisFire的任務。

  • MISFIRE_INSTRUCTION_SMART_POLICY

    全部的Trigger的MisFire默認值都是這個,大體意思是「把處理邏輯交給聰明的Quartz去決定」。基本策略是,

    1. 若是是隻執行一次的調度,使用MISFIRE_INSTRUCTION_FIRE_NOW
    2. 若是是無限次的調度(repeatCount是無限的),使用MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT
    3. 不然,使用MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT  

Cron表達式

位置 時間域 容許值 特殊值
1 0-59 , - * /
2 分鐘 0-59 , - * /
3 小時 0-23 , - * /
4 日期 1-31 , - * ? / L W C
5 月份 1-12 , - * /
6 星期 1-7 , - * ? / L C #
7 年份(可選) 1-31 , - * /

星號():可用在全部字段中,表示對應時間域的每個時刻,例如, 在分鐘字段時,表示「每分鐘」;

問號(?):該字符只在日期和星期字段中使用,它一般指定爲「無心義的值」,至關於點位符;

減號(-):表達一個範圍,如在小時字段中使用「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表達式對特殊字符的大小寫不敏感,對錶明星期的縮寫英文大小寫也不敏感。

一些例子:

 

表示式 說明
0 0 12 * * ? 天天12點運行
0 15 10 ? * * 天天10:15運行
0 15 10 * * ? 天天10:15運行
0 15 10 * * ? * 天天10:15運行
0 15 10 * * ? 2008 在2008年的天天10:15運行
0 * 14 * * ? 天天14點到15點之間每分鐘運行一次,開始於14:00,結束於14:59。
0 0/5 14 * * ? 天天14點到15點每5分鐘運行一次,開始於14:00,結束於14:55。
0 0/5 14,18 * * ? 天天14點到15點每5分鐘運行一次,此外天天18點到19點每5鍾也運行一次。
0 0-5 14 * * ? 天天14:00點到14:05,每分鐘運行一次。
0 10,44 14 ? 3 WED 3月每週三的14:10分到14:44,每分鐘運行一次。
0 15 10 ? * MON-FRI 每週一,二,三,四,五的10:15分運行。
0 15 10 15 * ? 每個月15日10:15分運行。
0 15 10 L * ? 每個月最後一天10:15分運行。
0 15 10 ? * 6L 每個月最後一個星期五10:15分運行。
0 15 10 ? * 6L 2007-2009 在2007,2008,2009年每月的最後一個星期五的10:15分運行。
0 15 10 ? * 6#3 每個月第三個星期五的10:15分運行。

   

 

 

         【版本聲明】本文爲博主原創文章,轉載請註明出處

相關文章
相關標籤/搜索