• quartz的持久化任务调度使用应用的dataSource


    Quartz提供两种基本作业存储类型
    --->第一种类型叫做RAMJobStore:
         最佳的性能,因为内存中数据访问最快
         不足之处是缺乏数据的持久性,当程序路途停止或系统崩溃时,所有运行的信息都会丢失
    --->第二种类型叫做JDBC作业存储:
         通过调整其quartz.properties属性文件,持久化任务调度信息
         使用数据库保存任务调度信息后,即使系统崩溃后重新启动,任务的调度信息将得到恢复

    如果部署应用多台服务器,定时任务在同一时刻只能有一个节点执行,那就必须使用第二种方案:持久化任务调度,通过Quartz默认的集群方案,保证同一时刻相同触发器定时任务,只有一个节点去执行此任务!!!如果该节点执行失败,则此任务则会被分派到另一节点执行,中途也会自动检查失效的定时调度,发现不成功的,其他节点立马接过来继续完成定时任务。

    默认的配置文件如下:

    复制代码
    # Default Properties file for use by StdSchedulerFactory
    # to create a Quartz Scheduler Instance, if a different
    # properties file is not explicitly specified.
    #
    # StdSchedulerFactory使用quartz.properties 创建一个Quartz Scheduler实例
    # 参数请参考:http://www.quartz-scheduler.org/documentation/quartz-2.x/configuration/
    #
    # Quartz提供两种基本作业存储类型
    # --->第一种类型叫做RAMJobStore:
    #     最佳的性能,因为内存中数据访问最快
    #     不足之处是缺乏数据的持久性,当程序路途停止或系统崩溃时,所有运行的信息都会丢失
    # --->第二种类型叫做JDBC作业存储:
    #     通过调整其quartz.properties属性文件,持久化任务调度信息
    #     使用数据库保存任务调度信息后,即使系统崩溃后重新启动,任务的调度信息将得到恢复
    #
    
    
    #============================================================================
    # 基础配置
    #============================================================================
    
    # 设置调度器的实例名(instanceName) 和实例ID (instanceId)
    # 注意:如果使用JobStoreTX,实例名严禁使用:DefaultQuartzScheduler
    # 原因:内存方式的instanceid为默认的DefaultQuartzScheduler,如果不修改系统会同时存在内存型和DB型,默认会走内存
    org.quartz.scheduler.instanceName: MyQuartzScheduler
    #如果使用集群,instanceId必须唯一,设置成AUTO
    org.quartz.scheduler.instanceId = AUTO
    
    org.quartz.scheduler.rmi.export: false
    org.quartz.scheduler.rmi.proxy: false
    org.quartz.scheduler.wrapJobExecutionInUserTransaction: false
    
    #============================================================================
    # 调度器线程池配置
    #============================================================================
    
    org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
    # 指定多少个工作者线程被创建用来处理 Job
    org.quartz.threadPool.threadCount: 10
    # 设置工作者线程的优先级(最大值10,最小值1,常用值5)
    org.quartz.threadPool.threadPriority: 5
    # 加载任务代码的ClassLoader是否从外部继承
    org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true
    
    org.quartz.jobStore.misfireThreshold: 60000
    
    #============================================================================
    # Configure JobStore 作业存储配置
    #============================================================================
    
    # 默认配置,数据保存到内存(调度程序信息是存储在被分配给JVM的内存里面,运行速度快)
    #org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore
    
    # 持久化配置(存储方式使用JobStoreTX,也就是数据库)
    org.quartz.jobStore.class:org.quartz.impl.jdbcjobstore.JobStoreTX
    # 驱动器方言
    org.quartz.jobStore.driverDelegateClass:org.quartz.impl.jdbcjobstore.StdJDBCDelegate
    # 使用自己的配置文件
    org.quartz.jobStore.useProperties:true
    
    #数据库中quartz表的表名前缀
    org.quartz.jobStore.tablePrefix:qrtz_
    org.quartz.jobStore.dataSource:myQuartzDB
    
    #是否使用集群(如果项目只部署到 一台服务器,就不用了)
    org.quartz.jobStore.isClustered = true
    
    #============================================================================
    # Configure Datasources配置数据源(可被覆盖,如果在schedulerFactoryBean指定数据源)
    #============================================================================
    
    org.quartz.dataSource.myQuartzDB.driver:oracle.jdbc.OracleDriver
    org.quartz.dataSource.myQuartzDB.URL:jdbc:oracle:thin:@10.132.81.134:1521:dsdb1
    org.quartz.dataSource.myQuartzDB.user:masmf
    org.quartz.dataSource.myQuartzDB.password:masmf
    org.quartz.dataSource.myQuartzDB.maxConnections:10
    复制代码

    其中,定义了Quartz的数据源。

    如果Quartz的表结构和应用的表结构部署在同一个DB的schema下,则可以使用应用的datasource。我这里使用的SpringBoot,代码如下:

    复制代码
    /**
         * 配置SchedulerFactoryBean
         *
         * @return
         * @throws IOException
         */
        @Bean //将一个方法产生为Bean并交给Spring容器管理(@Bean只能用在方法上)
        public SchedulerFactoryBean schedulerFactoryBean(@Qualifier("primaryDataSource") DataSource dataSource)
                throws IOException {
            //Spring提供SchedulerFactoryBean为Scheduler提供配置信息,并被Spring容器管理其生命周期
            SchedulerFactoryBean factory = new SchedulerFactoryBean();
            //启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
            //factory.setOverwriteExistingJobs(true);
            // 延时启动(秒)
            //factory.setStartupDelay(20);
            //设置quartz的配置文件
            Properties QuartzPropertie = quartzProperties();
            factory.setQuartzProperties(QuartzPropertie);
    
            //设置数据源(使用系统的主数据源,覆盖propertis文件的dataSource配置)
            factory.setDataSource(dataSource);
    
            //设置自定义Job Factory,用于Spring管理Job bean
            factory.setJobFactory(myJobFactory);
            return factory;
        }
    复制代码

    关键代码就2行:

    1、注入应用的datasource:@Qualifier("primaryDataSource") DataSource dataSource

    2、设置datatasource:factory.setDataSource(dataSource)

    这里会自动覆盖quartz.properties配置的数据源

    如果使用xml配置,如下:

    <bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
        <property name="dataSource" ref="dataSource"/>  
        <property name="overwriteExistingJobs" value="true"/>  
        <property name="configLocation" value="classpath:quartz.properties"/>  
    </bean> 

    具体SpringBoot下如何继承Quartz,请参考前一片文章:SpringBoot集成Quartz

    参考文章

    SchedulerFactoryBean的初始化分析

    https://www.cnblogs.com/huahua035/p/7977092.html

  • 相关阅读:
    java.lang.NoClassDefFoundError: Lorg/slf4j/Logger;
    jetty9内嵌到应用,并在启动后加载WebApplicationInitializer,可运行jsp
    Gradle Maven 依赖管理
    gradle多模块开发
    Github .gitignore详解
    Could not find or load main class org.gradle.wrapper.GradleWrapperMain解决办法
    SOC 与 ARM
    Codis集群的搭建与使用
    TIDB VS COCKROACHEB
    mysql故障
  • 原文地址:https://www.cnblogs.com/0xcafedaddy/p/8999254.html
Copyright © 2020-2023  润新知