springcloud配置中心实现多定时任务配置功能

    前提概述:springboot部分讲解了动态定时器的简单实用,本篇介绍一下怎样结合springcloud配置中心实现多任务配置功能。

一、配置中心模块

    初始化配置内容,分为两部分,初始化springbeanJobFactory和定时器配置类

import org.quartz.spi.TriggerFiredBundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;

public final class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {

    private static final Logger LOG = LoggerFactory.getLogger(AutowiringSpringBeanJobFactory.class);

    private transient AutowireCapableBeanFactory beanFactory;

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

    @Override
    protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
        final Object job = super.createJobInstance(bundle);
        LOG.info("create job instance");
        beanFactory.autowireBean(job);
        return job;
    }
}
import com.fusion.servicetaskscheduling.util.AppUtil;
import org.quartz.JobDetail;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.spi.JobFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.quartz.*;

import java.io.IOException;
import java.util.List;
import java.util.Properties;

@Configuration
@ConditionalOnProperty(name = "quartz.enabled")
public class QuartzConfigrations {

    @Autowired
    List listOfTrigger;

    @Bean
    public JobFactory jobFactory(ApplicationContext applicationContext) {
        AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
        jobFactory.setApplicationContext(applicationContext);
        return jobFactory;
    }

    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory) throws IOException {
        SchedulerFactoryBean factory = new SchedulerFactoryBean();
        factory.setOverwriteExistingJobs(true);
        factory.setAutoStartup(true);
        factory.setJobFactory(jobFactory);
        factory.setQuartzProperties(quartzProperties());

        // Here we will set all the trigger beans we have defined.
        if (!AppUtil.isObjectEmpty(listOfTrigger)) {
            factory.setTriggers(listOfTrigger.toArray(new Trigger[listOfTrigger.size()]));
        }

        return factory;
    }

    @Bean
    public Properties quartzProperties() throws IOException {
        PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
        propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
        propertiesFactoryBean.afterPropertiesSet();
        return propertiesFactoryBean.getObject();
    }

    public static SimpleTriggerFactoryBean createTrigger(JobDetail jobDetail, long pollFrequencyMs) {
        SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
        factoryBean.setJobDetail(jobDetail);
        factoryBean.setStartDelay(0L);
        factoryBean.setRepeatInterval(pollFrequencyMs);
        factoryBean.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
        // in case of misfire, ignore all missed triggers and continue :
        factoryBean.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT);
        return factoryBean;
    }

    // Use this method for creating cron triggers instead of simple triggers:
    public static CronTriggerFactoryBean createCronTrigger(JobDetail jobDetail, String cronExpression) {
        CronTriggerFactoryBean factoryBean = new CronTriggerFactoryBean();
        factoryBean.setJobDetail(jobDetail);
        factoryBean.setCronExpression(cronExpression);
        factoryBean.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_FIRE_NOW);
        return factoryBean;
    }

    public static JobDetailFactoryBean createJobDetail(Class jobClass) {
        JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
        factoryBean.setJobClass(jobClass);
        // job has to be durable to be stored in DB:
        factoryBean.setDurability(true);
        return factoryBean;
    }

}

    我的项目是添加了两个定时任务,如下为每天定时任务内容

import com.fusion.servicetaskscheduling.configs.QuartzConfigrations;
import com.fusion.servicetaskscheduling.quartz.ResetCron;
import com.fusion.servicetaskscheduling.service.DailyTaskSchedulingService;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.stereotype.Component;

@Component
@RefreshScope
@DisallowConcurrentExecution
public class EveryDayJobWithCronTrigger implements Job {

    private final static Logger logger = LoggerFactory.getLogger(EveryDayJobWithCronTrigger.class) ;

    @Value("${cron.frequency.everydayjobwithcrontrigger}")
    private String frequency ;

    @Lazy
    @Autowired
    DailyTaskSchedulingService taskSchedulingService ;

    @Override
    public void execute(JobExecutionContext jobExecutionContext) {
        logger.info("Running everydayjob | frequency --> " + frequency);
        ResetCron.reset(jobExecutionContext,frequency) ;
        boolean flag = taskSchedulingService.runTask();
        if(flag){
            logger.info("----------everydaytask has been successfully execution.----------");
        } else {
            logger.info("----------everydaytask appear problem, program terminating.----------");
        }
    }

    @Bean(name = "everyDayJobWithCronTriggerBean")
    public JobDetailFactoryBean sampleJob() {
        return QuartzConfigrations.createJobDetail(this.getClass());
    }

    @Bean(name = "everyDayJobWithCronTriggerBeanTrigger")
    public CronTriggerFactoryBean sampleJobTrigger(@Qualifier("everyDayJobWithCronTriggerBean") JobDetail jobDetail) {
        return QuartzConfigrations.createCronTrigger(jobDetail, frequency);
    }

}

    定时器每次执行任务的时候都判断定时器是否有变化

import org.quartz.*;

public class ResetCron {

    public static void reset(JobExecutionContext jobExecutionContext , String frequency){
//        JobDetail jobDetail = jobExecutionContext.getJobDetail() ;
        Trigger trigger = jobExecutionContext.getTrigger();
        Scheduler scheduler = jobExecutionContext.getScheduler() ;

        CronTrigger cronTrigger = null;
        try {
            cronTrigger = (CronTrigger) scheduler.getTrigger(trigger.getKey());
            String currentCron = cronTrigger.getCronExpression();// 当前Trigger使用的
            if (currentCron.equals(frequency)) {
                System.out.println(currentCron+"--------->>>>>>>>>"+frequency);
                // 如果当前使用的cron表达式和从数据库中查询出来的cron表达式一致,则不刷新任务
            } else {
                System.out.println(currentCron+"--------->>>>>>>>>"+frequency);
                // 表达式调度构建器
                CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(frequency);
                // 按新的cronExpression表达式重新构建trigger
                cronTrigger = (CronTrigger) scheduler.getTrigger(trigger.getKey());
                cronTrigger = cronTrigger.getTriggerBuilder().withIdentity(trigger.getKey())
                        .withSchedule(scheduleBuilder).build();
                // 按新的trigger重新设置job执行
                scheduler.rescheduleJob(trigger.getKey(), cronTrigger);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

    配置中心相关配置内容,taskurl为执行定时任务时调用其他模块的相关内容

cron.frequency.everydayjobwithcrontrigger  = 0 0 1 * * ?
cron.frequency.everyweekjobwithcrontrigger  = 0 0 3 ? * MON
schedule.dailytaskurl=http://SERVICE-SPARKTASK/getESToHDFSTask,http://SERVICE-SPARKTASK/getData2SqliteNotLogoutTask
schedule.weeklytaskurl=http://SERVICE-SPARKTASK/getUserLabelTask

写的仓促,未完待续

你可能感兴趣的:(springboot,springcloud,java)