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/

    最后:欢迎吐槽指正~ 

  • 相关阅读:
    DeepFM
    Wide & Deep Learning Model
    机器学习优化方法总结比较(SGD,Adagrad,Adadelta,Adam,Adamax,Nadam)
    svm、logistic regression对比
    梯度下降和EM算法,kmeans的em推导
    牛顿法、拟牛顿法以及与梯度下降法的对比
    【effective c++】构造/析构/赋值运算
    Tips/Tricks in Deep Neural Networks
    GoogLeNet系列解读
    电脑组装的配件及其功能
  • 原文地址:https://www.cnblogs.com/guofz/p/8963367.html
Copyright © 2011-2022 走看看