欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring Task 动态修改任务执行计划cron方式

程序员文章站 2022-09-02 10:36:04
目录spring task 动态修改任务执行计划cron原理demo如下spring @scheduled定时任务动态修改cron参数spring task 动态修改任务执行计划cronspring...

spring task 动态修改任务执行计划cron

spring task 能够在不重启服务的情况下,动态修改批量任务执行时间。

原理

spring task目前仅支持triggercontext上修改下次执行时间(批量任务执行后回调schedulingconfigurer.configuretasks,让用户可以重新设置trigger,从而动态修改下次执行时间)),这种方法的弊端就是“执行时间不能实时生效”。

为此,看了下task文档,感觉若要实现实时生效功能,必须代码里手工启动/停止spring task任务。

demo如下

首先,xml里不需要配置springtask相关的executor和scheduler。其次,在代码里自定义scheduler和taskregistrar(springtask启动的类)。最后,开个线程,模拟动态修改cron表达式的接口。

Spring Task 动态修改任务执行计划cron方式

输出如下:(35min没有执行原task)

info 27-11 14:34:10,476 - initializing executorservice
info 27-11 14:34:10,484 - nextexecutiontime: 0 35 14 * * ?
修改cron为: 0 36 14 * * ?
info 27-11 14:34:20,487 - initializing executorservice
info 27-11 14:34:20,488 - nextexecutiontime: 0 36 14 * * ?
info 27-11 14:36:00,001 - dynamiccrontask is running...
info 27-11 14:36:00,001 - nextexecutiontime: 0 36 14 * * ?

spring @scheduled定时任务动态修改cron参数

  • 在定时任务类上增加@enablescheduling注解,并实现schedulingconfigurer接口。(注意低版本无效)
  • 设置一个静态变量cron,用于存放任务执行周期参数。
  • 另辟一线程,用于模拟实际业务中外部原因修改了任务执行周期。
  • 设置任务触发器,触发任务执行,其中就可以修改任务的执行周期。

class : springdynamiccorntask

package com.xindatai.ibs.lime.dycschedul;
import java.util.date;
import org.slf4j.logger;
import org.slf4j.loggerfactory;
import org.springframework.context.annotation.lazy;
import org.springframework.scheduling.trigger;
import org.springframework.scheduling.triggercontext;
import org.springframework.scheduling.annotation.enablescheduling;
import org.springframework.scheduling.annotation.schedulingconfigurer;
import org.springframework.scheduling.config.scheduledtaskregistrar;
import org.springframework.scheduling.support.crontrigger;
import org.springframework.stereotype.component;

/**
 * spring动态周期定时任务 在不停应用的情况下更改任务执行周期
 * 
 * @author liang
 *
 *         2017年6月1日
 */
@lazy(false)
@component
@enablescheduling
public class springdynamiccorntask implements schedulingconfigurer {
    private static final logger logger = loggerfactory.getlogger(springdynamiccorntask.class);
    private static string cron;
    private springdynamiccorntask() {
        cron = "0/5 * * * * ?";
        // 开启新线程模拟外部更改了任务执行周期
        new thread(new runnable() {

            @override
            public void run() {
                try {
                    thread.sleep(15 * 1000);
                } catch (interruptedexception e) {
                    e.printstacktrace();
                }
                cron = "0/10 * * * * ?";
                system.out.println("cron change to : " + cron);
            }
        }).start();
    }

    @override
    public void configuretasks(scheduledtaskregistrar taskregistrar) {
        taskregistrar.addtriggertask(new runnable() {

            @override
            public void run() {
                // 任务逻辑
                logger.info("dynamiccrontask is running...");
            }
        }, new trigger() {

            @override
            public date nextexecutiontime(triggercontext triggercontext) {
                // 任务触发,可修改任务的执行周期
                crontrigger trigger = new crontrigger(cron);
                date nextexecutiontime = trigger.nextexecutiontime(triggercontext);
                return nextexecutiontime;
            }
        });
    } 
}

console :

[info 2017-06-01 12:26:25 springdynamiccorntask] - dynamiccrontask is running...
[info 2017-06-01 12:26:30 springdynamiccorntask] - dynamiccrontask is running...
[info 2017-06-01 12:26:35 springdynamiccorntask] - dynamiccrontask is running...
cron change to : 0/10 * * * * ?
[info 2017-06-01 12:26:40 springdynamiccorntask] - dynamiccrontask is running...
[info 2017-06-01 12:26:50 springdynamiccorntask] - dynamiccrontask is running...
[info 2017-06-01 12:27:00 springdynamiccorntask] - dynamiccrontask is running...

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

相关标签: Spring Task cron