Quartz调度系统入门和调度高可用实现方案

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Quartz调度系统入门和调度高可用实现方案相关的知识,希望对你有一定的参考价值。

参考技术A

** 版本:2.2.1 **

策略选择 (指的是CronTrigger,而SimpleTrigger有其对应的策略,在这里不做探讨):

SimpleTrigger 有一堆的另外的MisFire机制,这里先不做讨论,以后有机会再更新,如下:
withMisfireHandlingInstructionFireNow 、 withMisfireHandlingInstructionIgnoreMisfires 、 withMisfireHandlingInstructionNextWithExistingCount 、 withMisfireHandlingInstructionNowWithExistingCount 、 withMisfireHandlingInstructionNextWithRemainingCount 、 withMisfireHandlingInstructionNowWithRemainingCount 、 MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT

这些时间是在某一次的调度作业的作业执行过程中可以获取到的时间戳

Quartz自身提供了对任务调度本身的不重不漏的高可用保证,但是一个任务确实被Quartz正确调度之后呢,Quartz系统中的记录已经标记为这个任务执行完成了,但是这个任务在执行过程中出错了,怎么办?

Spring Quartz实现任务调度

任务调度

在企业级应用中,经常会制定一些“计划任务”,即在某个时间点做某件事情 核心是以时间为关注点,即在一个特定的时间点,系统执行指定的一个操作 任务调度涉及多线程并发、线程池维护、运行时间规则解析、运行现场的保护以恢复等方面 Quartz框架是一个开源的企业级任务调度服务,已经被作为任务调度的良好解决方案.

Quartz框架核心

Quartz对任务调度进行了高度抽象,提出了3个核心概念,并在org.quartz包中通过接口和类进行了描述

任务:就是执行的工作内容。Quartz提供Job接口来支持任务定义

触发器:定义触发Job执行的时间触发规则。Quartz提供Trigger类及其子类支持触发器功能

调度器:Quartz提供了Scheduler接口,将工作任务触发器绑定,保证任务可以在正确的时间执行

运行环境

任务调度

任务执行

任务持久化

事务

集群

监听器和插进

Quartz案例

 

1.找到Quartz框架的jar包

2.开始创建entity实体层定义任务的模板

package cn.entity;

public class Plan {
      //时间
    private String date;
    //任务
    private String task;
    
    public Plan() {
        super();
    }
    
    public Plan(String date, String task) {
        super();
        this.date = date;
        this.task = task;
    }

    @Override
    public String toString() {
        return "Plan [date=" + date + ", task=" + task + "]";
    }
    public String getDate() {
        return date;
    }
    public void setDate(String date) {
        this.date = date;
    }
    public String getTask() {
        return task;
    }
    public void setTask(String task) {
        this.task = task;
    }
    
}

 

 

3.定制一个泛型集合用户存储多个Plan对象,提供一个方法读取该泛型集合中的data

package cn.service;

import java.util.ArrayList;
import java.util.List;

import cn.entity.Plan;
/**
 * 提醒服务类
 * @author 景佩佩
 *
 */
public class RemindService {
     //01.创建一个集合,并且方法返回值是一个集合类型
    public List<Plan> getPlansForToday(){
        List<Plan> list=new ArrayList<Plan>();
        Plan plan1=new Plan("2016年12月16日","2016最后一个月");
        Plan plan2=new Plan("2016年12月18日","Quartz");
        
        list.add(plan1);
        list.add(plan2);
        
        return list;
    }
    
    
    //02.用来打印集合中提醒内容的方法
    public void printMessage(){
        List<Plan> list = getPlansForToday();
        for (Plan plan : list) {
            //单个的plan
            System.out.println("计划的时间"+plan.getDate()+"\\t计划内容"+plan.getTask());
        }
    }
}

4.提醒业务类

package cn.quartz;

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

import cn.service.RemindService;
/**
 * 提醒业务
 * @author 景佩佩
 *
 */
//让一个普通类变成计划
public class RemindJob implements Job {
    //植入service 对象
    private RemindService service=new RemindService();
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        service.printMessage();
    }
    public RemindService getService() {
        return service;
    }
    public void setService(RemindService service) {
        this.service = service;
    }

    
}

Job接口中只有一个 execute()方法,在实现类中 实现该方法以执行具体任务。   

5.真正的任务对象和触发器对象

package cn.test;

import java.util.Date;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.DateBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;

import cn.quartz.RemindJob;

public class MyQuartzTest {
    
    public static void tool() throws SchedulerException, InterruptedException{
        //第一步构建Job
         JobDetail job = JobBuilder.newJob(RemindJob.class)//
                 .withIdentity("job1", "group1")//
                 .build();
         
         //第二步创建Trigger
         //第一种方式  控制不太好
        /* Date runTime = DateBuilder.evenMinuteDate(new Date(System.currentTimeMillis()));
         Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1")//
                 .startAt(runTime).build();*/
         
         //第二种方式  不太好
         /*Trigger trigger = TriggerBuilder.newTrigger() 
                 .withIdentity(TriggerKey.triggerKey("myTrigger", "myTriggerGroup"))
                 .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                     .withIntervalInSeconds(2)
                     .repeatForever())
                 .startAt(new Date(System.currentTimeMillis()+2000))
                 .build();*/
         
                 
         
            //第三步绑定  JOb和Trigger
           // First we must get a reference to a scheduler
           //创建调度者工厂
            SchedulerFactory sf = new StdSchedulerFactory();
          //创建一个调度者
            Scheduler sched = sf.getScheduler();
          //注册并进行调度
            sched.scheduleJob(job, trigger);
          //启动调度
            sched.start();
            /*Thread.sleep(3000);
             * //关闭调度
            sched.shutdown();*/
    }

    
        
    public static void main(String[] args) throws SchedulerException, InterruptedException {
        tool();
        System.out.println("呵呵");
    }
}

 第一种方式:

第二种方式:

 

6.使用CronTrigger

CronTrigger也是Trigger的子类

CronTrigger和SimpleTrigger的对

CronTrigger允许用户更精准地控制任务的运行日期和时间,而不仅仅是定义工作的频度

CronTrigger通过Cron表达式定义准确的运行时间点。创建CronTrigger的语法如下:

7.Cron表达式

要使用CronTrigger,必须掌握Cron表达式

 

Cron表达式由6~7个由空格分隔的时间元素组成。第7个元素可选

 

Cron表达式的每个字段,都可以显式地规定一个值(如49)、一个范围(如1-6)、一个列表(如1,3,5)或者一个通配符(如*)

 

8.Cron表达式有几个特殊的字符,说明如下

“ - ”:中划线,表示一个范围

“ , ”:使用逗号间隔的数据,表示一个列表

“ * ”:表示每一个值,它可以用于所有字段。例如:在小时字段表示每小时

“ ? ”:该字符仅用于“月份中的哪一天”字段和“星期几”字段,表示不指定值

“ / ”:通常表示为x/y,x为起始值,y表示值的增量。

“ L ”:表示最后一天,仅在日期和星期字段中使用

“ # ”:只能用于“星期几”字段,表示这个月的第几个周几。例如:“6#3”指这个月第三个周五

 

9.Cron表达式案例

 

 

测试:

package cn.test;

import java.util.Date;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.DateBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;

import cn.quartz.RemindJob;

public class MyQuartzTest {
    
    public static void tool() throws SchedulerException, InterruptedException{
        //第一步构建Job
         JobDetail job = JobBuilder.newJob(RemindJob.class)//
                 .withIdentity("job1", "group1")//
                 .build();
         
         //第二步创建Trigger
        /**
         * 2016年每月的第三个星期六上午10:18触发 0 18 10 ? * 6#3 2016
         */
        CronTrigger trigger=TriggerBuilder.newTrigger()//
                .withIdentity("myTrigger", "myTriggerGroup")//
                .withSchedule(CronScheduleBuilder.//
                        cronSchedule("0 18 10 ? * 6#3 2016")).build();
         
         
            //第三步绑定  JOb和Trigger
           // First we must get a reference to a scheduler
           //创建调度者工厂
            SchedulerFactory sf = new StdSchedulerFactory();
          //创建一个调度者
            Scheduler sched = sf.getScheduler();
          //注册并进行调度
            sched.scheduleJob(job, trigger);
          //启动调度
            sched.start();
              }

    
        
    public static void main(String[] args) throws SchedulerException, InterruptedException {
        tool();
        System.out.println("呵呵");
    }
}

 

以上是关于Quartz调度系统入门和调度高可用实现方案的主要内容,如果未能解决你的问题,请参考以下文章

Elastic-Job介绍

任务调度框架 quartz 和 xxl-job - 上

Spring Quartz实现任务调度

Spring Quartz实现任务调度

Spring Quartz实现任务调度

Quartz任务调度概念例析快速入门