zoukankan      html  css  js  c++  java
  • Quartz 入门

    简介

    可以用来创建执行数十,数百乃至数万个作业的简单或复杂的计划;开源的完全使用JAVA开发的一种时间调度框架,可多线程同步执行。支持集群、JTA事务(听着好高大上,说白了就是定时器~,与以往不同的是,他支持大量的定时任务同步执行,还可以将定时信息保存到数据库中在需要的时候在开启执行,可以防止数据丢失,也可以随时查看定时任务的信息)

    使用

    quartz 下载地址: http://www.quartz-scheduler.org/downloads/ 

    quartz有两种使用方式:RAM、JDBC。任务的调度也有两种方式:SimpleSchedule、CronSchedule

    RAM方式:

    程序直接运行在内存中

    1、导入 Quartz 的jar包,官网有zip文件可供下载,maven 项目则需要导入依赖

        <!-- quartz begin -->
          <dependency>
           <groupId>org.quartz-scheduler</groupId>
           <artifactId>quartz</artifactId>
           <version>2.2.1</version>
         </dependency>
         <dependency>
           <groupId>org.quartz-scheduler</groupId>
           <artifactId>quartz-jobs</artifactId>
           <version>2.2.1</version>
         </dependency> 
         <!-- quartz end -->
         
         <!-- log -->
         <dependency>  
            <groupId>org.slf4j</groupId>  
            <artifactId>slf4j-simple</artifactId>  
            <version>1.7.25</version>  
        </dependency>

    2、创建 quartz.properties  文件放到 classpath 中

    #JDBC驱动
    #org.quartz.dataSource.qzDS.driver:com.mysql.jdbc.Driver
    #org.quartz.dataSource.qzDS.URL:jdbc:mysql://localhost:3306/test
    #org.quartz.dataSource.qzDS.user:root
    #org.quartz.dataSource.qzDS.password:
    #org.quartz.dataSource.qzDS.maxConnection:10

    org.quartz.scheduler.instanceName=MyScheduler
    org.quartz.threadPool.threadCount=3
    org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore

    3、创建具体的任务

    package com.quartz.first;
    
    import org.quartz.Job;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    
    public class MyJob implements Job {
    
        private static final String NAME = "name";
        
        @Override
        public void execute(JobExecutionContext arg0) throws JobExecutionException {
            
            System.out.println(" execute job() ...  ");
        }
    
    }

    调用

    package com.quartz.first;
    
    import java.util.Date;
    
    import org.quartz.JobBuilder;
    import org.quartz.JobDetail;
    import org.quartz.Scheduler;
    import org.quartz.SchedulerException;
    import org.quartz.SchedulerFactory;
    import org.quartz.Trigger;
    import org.quartz.TriggerBuilder;
    import org.quartz.impl.StdSchedulerFactory;
    
    /**
     * 
     * 使用 RAM 方式定时
     * 
     * @author 丰志
     *
     */
    public class RAMQuartz {
    
        public static void main(String[] args) throws SchedulerException {
            //1.创建Scheduler的工厂
            SchedulerFactory schedulerFactory = new StdSchedulerFactory();
            //2.从工厂中获取调度器实例
            Scheduler scheduler = schedulerFactory.getScheduler();
            //3.创建JobDetail
            JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
                    .withDescription("this is a ram job") //job的描述
                    .withIdentity("ramJob", "ramGroup") //job 的name和group
                    .build();
    
    //        jobDetail.getJobDataMap().put("name", "zhangsan"); //传参用与MyJob中获取参数    jobDataMap.get("name")
            
            //任务运行的时间,SimpleSchedle类型触发器有效
            long time=  System.currentTimeMillis() + 3*1000L; //3秒后启动任务
            Date statTime = new Date(time);
    
            //4.创建Trigger
            //使用SimpleScheduleBuilder或者CronScheduleBuilder
            Trigger trigger = TriggerBuilder.newTrigger()
                        .withDescription("")
                        .withIdentity("ramTrigger", "ramTriggerGroup")
                        .startAt(statTime)  //默认当前时间启动
    //                    .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2).withRepeatCount(10)) // 每个2秒钟执行一次,一共执行10次
    //                    .withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?")) //两秒执行一次,cron 秒、分、时、日、月、年、
                        .build();
    
            //5.注册任务和定时器
            scheduler.scheduleJob(jobDetail, trigger);
            //6.启动 调度器
            scheduler.start();
        }
    }

     结果:

    到此就实现了基本的调度任务,但是在实际项目中往往需要用到quartz跟一些开发框架的集成

    spring集成quartz

       使用spring框架来管理quartz可以使开发变得简单,只需要书写具体的任务即可,因为不在需要写JAVA代码来开启任务,spring会根据配置文件中的配置自动开启省去了手写的调度过程。具体实现:

    1、添加 spring 支持(添加之前的依赖):

    <dependency>                                
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>${spring.version}</version>
    </dependency>

    2、创建具体的任务

    Simple方式:

    package org.quartz.demo;
    
    import java.util.Date;
    
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    import org.springframework.scheduling.quartz.QuartzJobBean;
    
    public class SimpleJob extends QuartzJobBean {
    
        @Override
        protected void executeInternal(JobExecutionContext arg0) throws JobExecutionException {
            System.out.println("------   执行ExampleJob     -------"  + new Date());
        }
    }

    Cron方式:

    package org.quartz.demo;
    
    import java.util.Date;
    
    public class CronJob {
    
        public void doIt() {
            System.out.println("======    执行 ExampleBusinessObject.doIt...       ======" + new Date());
        }
    }

    3、配置 spring-quartz.xml 文件:

    spring 的applicationContext.xml文件中添加quartz:

    <import resource="classpath:conf/spring-quartz.xml" />

    配置 spring-quartz.xml

    Simple方式:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
        
        <!-- 具体执行的任务 --> 
        <bean name="simpleJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
            <property name="jobClass" value="org.quartz.demo.SimpleJob"/>
        </bean>
        
        <!-- Simple触发器 -->    
        <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
            <property name="jobDetail" ref="simpleJob"/>
            <property name="startDelay" value="50000"/>
            <property name="repeatInterval" value="5000"/>
        </bean>  
         
        <!-- 调度工厂 --> 
        <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
            <property name="triggers">
                <list>
                    <ref bean="simpleTrigger"/>
                </list>
            </property>
        </bean>
        
    </beans>

    Cron方式:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
        
        <!-- 具体的任务 -->
        <bean id="cronJob" class="org.quartz.demo.CronJob"/>
        
        <!-- JobDetail -->
        <bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
            <property name="targetObject" ref="cronJob"/>
            <property name="targetMethod" value="doIt"/>
        </bean>
        
        <!-- Cron触发器 -->
        <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
            <property name="jobDetail" ref="jobDetail"/>
            <property name="cronExpression" value="10 * * * * ?"/> 
        </bean>  
         
        <!-- 调度工厂 --> 
        <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
            <property name="triggers">
                <list>
                    <ref bean="cronTrigger"/>
                </list>
            </property>
        </bean>
        
    </beans>

    启动 tomcat 测试结果

    Cron.doIt 每分钟的第 10 秒执行一次, SimpleJob 每 5 秒钟执行一次。两个任务可以同时调度。测试通过~

    JDBC方式:

    如果需要使用 JDBC模式需要下载官方的资料,进入 quartz-2.2.3 / docs / dbTables 里面有所有的 sql 文件,可以执行具体的 sql 生成需要的数据表,数据表只有在使用 JDBC 模式的情况下才有效,这里只是初步的记录下quartz的使用。

    1、根据官方文档提供的 sql 生成相应的数据表

    在下载文件夹下进入 quartz-2.2.3 / docs / dbTables 执行相应的 sql 生成对应的数据表

    其中常用的

      qrtz_cron_tiggers:  记录使用 CRON 表达式定义的触发器

      qrtz_fired_triggers:  记录触发器的执行时间

      qrtz_job_details:  记录具体任务的名称,组,类名等信息

      qrtz_simple_triggers:  记录使用 Simple 方式定义的触发器

      qrtz_triggers:  记录触发器执行的详细信息,包括任务的名称、组,触发器的名称、组以及触发器的开始执行时间、上次执行的时间和下一次执行的时间等信息

    2、配置 quartz.properties 放到 classpath 目录下

    org.quartz.threadPool.threadCount=3
    org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
    org.quartz.jobStore.dataSource = myDS
    
    org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver
    org.quartz.dataSource.myDS.URL = jdbc:mysql://localhost:3306/test
    org.quartz.dataSource.myDS.user = root
    org.quartz.dataSource.myDS.password =
    org.quartz.dataSource.myDS.maxConnections = 30

    在这儿只列举基本的配置,详细的参考:  http://www.quartz-scheduler.org/documentation/quartz-2.1.x/configuration/ 

    3、配置具体的任务

    package com.quartz.first;
    
    import org.quartz.Job;
    import org.quartz.JobDataMap;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    
    public class MyJob implements Job {
    
        private static final String NAME = "name";
        
        @Override
        public void execute(JobExecutionContext arg0) throws JobExecutionException {
            
            System.out.println(" execute jdbcJob() ...  ");
        }
    
    }

    4、调用测试

    package com.quartz.first;
    
    import java.util.List;
    
    import org.quartz.CronScheduleBuilder;
    import org.quartz.CronTrigger;
    import org.quartz.JobBuilder;
    import org.quartz.JobDetail;
    import org.quartz.JobKey;
    import org.quartz.Scheduler;
    import org.quartz.SchedulerException;
    import org.quartz.SchedulerFactory;
    import org.quartz.SimpleScheduleBuilder;
    import org.quartz.SimpleTrigger;
    import org.quartz.Trigger;
    import org.quartz.TriggerBuilder;
    import org.quartz.impl.StdSchedulerFactory;
    
    public class JDBCQuartz {
    
        public static void main(String[] args) throws SchedulerException {
            
            startSchedule(); //开始执行定时任务,同时会向数据库写入任务、触发器、调度等数据
            //resumeJob(); // 重新执行
        }
    
        private static void startSchedule() {
            try {
                // 1、创建JobDetail实例
                JobDetail jobDetail = JobBuilder.newJob(MyJob.class).withIdentity("job1", "group1").build();
    
                // 2、设置触发器类型 、执行次数
    //            SimpleScheduleBuilder simpleScheduleBuilder = SimpleScheduleBuilder.repeatSecondlyForTotalCount(5);
                CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/2 * * * * ?");
    
                // 3、创建Trigger
                Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startNow()
                        .withSchedule(cronScheduleBuilder).build();
    
                // 4、创建Scheduler
                Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
                scheduler.start();
    
                // 5、调度执行
                scheduler.scheduleJob(jobDetail, trigger);
                try {
                    Thread.sleep(60000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
    
                // 关闭调度器
                // scheduler.shutdown();
    
            } catch (SchedulerException e) {
                e.printStackTrace();
            }
        }
    
        /** 从数据库中找到已经存在的job,并重新开户调度 */
        private static void resumeJob() {
            try {
    
                SchedulerFactory schedulerFactory = new StdSchedulerFactory();
                Scheduler scheduler = schedulerFactory.getScheduler();
                JobKey jobKey = new JobKey("job1", "group1");
                List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
                if (triggers.size() > 0) {
                    for (Trigger tg : triggers) {
                        // 根据类型判断
                        if ((tg instanceof CronTrigger) || (tg instanceof SimpleTrigger)) {
                            // 恢复job运行
                            scheduler.resumeJob(jobKey);
                        }
                    }
                    scheduler.start();
                }
    
            } catch (Exception e) {
                e.printStackTrace();
    
            }
        }
    }

    运行结果:

    数据库:

     

    关闭服务,执行修改代码执行resumeJob():  

    一秒钟执行了这么多次,调用成功。

    到此基本的使用应该没什么问题了   (~ ̄▽ ̄ ~)

    源码: https://files.cnblogs.com/files/guofz/myFirstQuartz.rar

    Quartz官方介绍:  http://www.quartz-scheduler.org/documentation/quartz-2.2.x/quick-start.html

    Spring官方文档介绍集成 Quartz 地址:https://docs.spring.io/spring/docs/4.3.17.BUILD-SNAPSHOT/spring-framework-reference/htmlsingle/

    最后:欢迎吐槽指正~ 

  • 相关阅读:
    std thread
    windows更新包发布地址
    How to set up logging level for Spark application in IntelliJ IDEA?
    spark 错误 How to set heap size in spark within the Eclipse environment?
    hadoop 常用命令
    windows 安装hadoop 3.2.1
    windows JAVA_HOME 路径有空格,执行软连接
    day01MyBatisPlus条件构造器(04)
    day01MyBatisPlus的CRUD 接口(03)
    day01MyBatisPlus入门(02)
  • 原文地址:https://www.cnblogs.com/guofz/p/8963367.html
Copyright © 2011-2022 走看看