【动态定时任务】从apollo配置中心获取定时任务的执行时间,能够实时修改定时任务执行时间

基本原理:设置两次定时任务,一次定时任务专门用来查看apollo的配置是否修改。另一次则是项目需要执行的定时任务

【这样写的好处】

  1. 同一时间执行多个定时任务,一个定时任务失败,不会导致其他定时任务阻塞
  2. 动态从apollo获取定时任务执行时间,不需要每次更改定时时间都重新部署服务
  3. 定时任务比较少时,免去维护数据库的过程

废话不多说,直接上代码,走着

一、引入依赖

 <!--        引入quartz依赖-->
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
        </dependency>

        <!-- 该依赖必加,里面有sping对schedule的支持 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>

二、需要执行的定时任务

其中,reset()方法动态从apollo获取;method2()的定时时间代码写死,不是动态的;

@Configuration
@Component
@EnableScheduling
public class TaskConfig {

    public void reset(){  //需要执行的定时任务
        //定时任务的业务代码XXXXXXXXXXXXXXXXXXXXXX
    }

   //当有第二个需要执行的定时任务
    public void method2(){  
    }
}

三、Quartz配置类

@Configuration
public class QuartzConfigration {

    @Bean(name = "jobDetail")
    public MethodInvokingJobDetailFactoryBean detailFactoryBean(TaskConfig taskConfig){  //需要定时执行的任务

        MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
        /*
         *  是否并发执行
         *  例如每5s执行一次任务,但是当前任务还没有执行完,就已经过了5s了,
         *  如果此处为true,则下一个任务会执行,如果此处为false,则下一个任务会等待上一个任务执行完后,再开始执行
         */
        jobDetail.setConcurrent(false);  //等待上一个任务执行完,再开始执行
        jobDetail.setName("resetTask"); //设置任务的名字
        jobDetail.setTargetObject(taskConfig); //为需要执行的实体类对应的对象(定时方法所在类的对象)
        jobDetail.setTargetMethod("reset"); // 为需要执行的方法(需要执行的定时任务方法)
        return jobDetail;
    }

    /**
     * attention:
     * Details:配置定时任务的触发器,也就是什么时候触发执行定时任务
     * 注意!!!!入参JobDetail 对象 jobDetail需要和 上面注入的名称一致!!!!!
     */
    @Bean(name = "jobTrigger")
    public CronTriggerFactoryBean cronJobTrigger(JobDetail jobDetail){
        CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
        trigger.setJobDetail(jobDetail);
        trigger.setCronExpression("0 0 0 * * ?"); //初始时的cron表达式
        return trigger;
    }
    
	// 第二个定时任务的配置
 	@Bean(name = "jobDetail2")
    public MethodInvokingJobDetailFactoryBean detailFactoryBean(TaskConfig taskConfig){  //需要定时执行的任务

        MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
        jobDetail.setConcurrent(false);
        jobDetail.setName("task2"); 
        jobDetail.setTargetObject(taskConfig); 
        jobDetail.setTargetMethod("method2");
        return jobDetail;
    }

    /**
     * attention:
     * Details:配置定时任务的触发器,也就是什么时候触发执行定时任务
     */
    @Bean(name = "jobTrigger2")
    public CronTriggerFactoryBean cronJobTrigger(JobDetail jobDetail2){
        CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
        trigger.setJobDetail(jobDetail2);
        trigger.setCronExpression("0 0 0 * * ?"); 
        return trigger;
    }

    /**
     *
     * @param cronJobTrigger
     * @return 定义quartz调度工厂
     * 注意!!!!入参Trigger 对象 jobTrigger、jobTrigger2 要和 上面注入的触发器名称一致!!!!!
     * 有几个任务,配置几个触发器,将需要执行的触发器注入
     */
    @Bean(name = "scheduler")
    public SchedulerFactoryBean schedulerFactory(Trigger jobTrigger,Trigger jobTrigger2){
        SchedulerFactoryBean bean = new SchedulerFactoryBean();
        // 用于quartz集群,QuartzScheduler 启动时更新己存在的Job
        bean.setOverwriteExistingJobs(true);
        // 延时启动,应用启动1秒后
        bean.setStartupDelay(1);
        // 注册触发器
        bean.setTriggers(jobTrigger,jobTrigger2);
        return bean;
    }
}

四、获取定时任务动态执行时间

@Configuration
@EnableScheduling
@Component
public class ScheduleRefreshApollo {

    @Resource(name = "jobDetail")
    private JobDetail jobDetail;

    @Resource(name = "jobTrigger")
    private CronTrigger cronTrigger;

    @Resource(name = "scheduler")
    private Scheduler scheduler;

    @Scheduled(fixedDelay = 60000) //每隔1分钟,获取apollo数据,决定是否重置定时任务
    public void scheduleUpdateCronTrigger() throws SchedulerException {
        CronTrigger trigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey());
        String currentCron = trigger.getCronExpression();//当前trigger使用的
        String searchCron = SystemConfigValues.get("job.cron");//获取apollo配置的时间,这里是公司封装的方法,需要修改为自己的动态时间 
        System.out.println(">>>>>>>>>>currentCron>>>>>>>>>>>" + currentCron + ",searchCron>>>>>>>>>>>" + searchCron);
        if (null != searchCron && null!=currentCron && !searchCron.equals(currentCron)){
            // 表达式调度构建器
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(searchCron);
            // 按新的cronExpression表达式重新构建trigger
            trigger = (CronTrigger)scheduler.getTrigger(cronTrigger.getKey());
            trigger = trigger.getTriggerBuilder().withIdentity(cronTrigger.getKey()).withSchedule(scheduleBuilder).build();
            // 按新的trigger重新设置job执行
            scheduler.rescheduleJob(cronTrigger.getKey(),trigger);
            currentCron = searchCron;
        }
    }
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值