penpenrou
2019-12-17 17:37 阅读 683

quartz 集群环境下,停掉一个点,该点下的定时任务不被其他点承接,定时任务不再执行

集群环境下 springboot + quartz,停掉一个点,该点下的定时任务不被其他点承接,定时任务不再执行
两个job类20秒执行一次
0/20 * * * * ?
启动两个,能看到控制台的两个项目分别打印两个定时任务的日志,停掉其中一个项目,日志不变,停掉项目中的任务没有被运行的项目执行,运行的项目还执行原任务

    配置文件
#quartz集群配置  
# ===========================================================================    
# Configure Main Scheduler Properties 调度器属性    
# ===========================================================================  
#调度标识名 集群中每一个实例都必须使用相同的名称    
org.quartz.scheduler.instanceName=DefaultQuartzScheduler  
#ID设置为自动获取 每一个必须不同  
org.quartz.scheduler.instanceid=AUTO    
#============================================================================  
# Configure ThreadPool    
#============================================================================  
#线程池的实现类(一般使用SimpleThreadPool即可满足几乎所有用户的需求)  
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool  
#指定线程数,至少为1(无默认值)(一般设置为1-100直接的整数合适)  
org.quartz.threadPool.threadCount=10  
#设置线程的优先级(最大为java.lang.Thread.MAX_PRIORITY 10,最小为Thread.MIN_PRIORITY 1,默认为5)   
org.quartz.threadPool.threadPriority=5  
#============================================================================  
# Configure JobStore    
#============================================================================  
# 信息保存时间 默认值60秒   
org.quartz.jobStore.misfireThreshold=60000  
#数据保存方式为数据库持久化  
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX  
#数据库代理类,一般org.quartz.impl.jdbcjobstore.StdJDBCDelegate可以满足大部分数据库  
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate  
#JobDataMaps是否都为String类型  
org.quartz.jobStore.useProperties=false  
#数据库别名 随便取  
org.quartz.jobStore.dataSource=myDS  
#表的前缀,默认QRTZ_  
org.quartz.jobStore.tablePrefix=QRTZ_  
#是否加入集群  
org.quartz.jobStore.isClustered=true  
#调度实例失效的检查时间间隔  
org.quartz.jobStore.clusterCheckinInterval=15000


@Configuration
public class QuartzConfiguration {

    @Autowired
    DataSource dataSource;

    /**
     * 继承org.springframework.scheduling.quartz.SpringBeanJobFactory 实现任务实例化方式
     */
    public static class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {

        private transient AutowireCapableBeanFactory beanFactory;

        @Override
        public void setApplicationContext(final ApplicationContext context) {
            beanFactory = context.getAutowireCapableBeanFactory();
        }

        /**
         * 将job实例交给spring ioc托管 我们在job实例实现类内可以直接使用spring注入的调用被spring ioc管理的实例
         * 
         * @param bundle
         * @return
         * @throws Exception
         */
        @Override
        protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
            final Object job = super.createJobInstance(bundle);
            /**
             * 将job实例交付给spring ioc
             */
            beanFactory.autowireBean(job);
            return job;
        }
    }

    /**
     * 配置任务工厂实例
     * 
     * @param applicationContext spring上下文实例
     * @return
     */
    @Bean
    public JobFactory jobFactory(ApplicationContext applicationContext) {
        /**
         * 采用自定义任务工厂 整合spring实例来完成构建任务 see {@link AutowiringSpringBeanJobFactory}
         */
        AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
        jobFactory.setApplicationContext(applicationContext);
        return jobFactory;
    }

    /**
     * 配置任务调度器 使用项目数据源作为quartz数据源
     * 
     * @param jobFactory 自定义配置任务工厂
     * @return
     * @throws Exception
     */
    @Bean(destroyMethod = "destroy", autowire = Autowire.NO)
    public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory) throws Exception {
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        // 将spring管理job自定义工厂交由调度器维护
        schedulerFactoryBean.setJobFactory(jobFactory);
        // 设置覆盖已存在的任务
        schedulerFactoryBean.setOverwriteExistingJobs(true);
        // 项目启动完成后,等待10秒后开始执行调度器初始化
        schedulerFactoryBean.setStartupDelay(10);
        // 设置调度器自动运行
        schedulerFactoryBean.setAutoStartup(true);
        // 设置数据源,使用与项目统一数据源
        schedulerFactoryBean.setDataSource(dataSource);
        // 设置上下文spring bean name
        schedulerFactoryBean.setApplicationContextSchedulerContextKey("applicationContext");
        // 设置配置文件位置
        schedulerFactoryBean.setConfigLocation(new ClassPathResource("/application-quartz.properties"));
        return schedulerFactoryBean;
    }
}

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

1条回答 默认 最新

  • wojiushiwo945you 毕小宝 2019-12-17 18:12

    查一下 Quartz 定时任务表中的数据变化的规则是什么?
    此外,你的任务是怎么配置的呢?
    Quartz 集群任务是针对一个应用集群部署的情况下,保证 Quartz 任务只会被一个节点执行,但道理是不会出这种情况的。同一台机器上,没有时间同步的问题,那么有可能是定时任务的用法问题。

    点赞 2 评论 复制链接分享

相关推荐