Spring Task 动态修改任务执行计划cron方式
spring task 动态修改任务执行计划cron
spring task 能够在不重启服务的情况下,动态修改批量任务执行时间。
原理
spring task目前仅支持triggercontext上修改下次执行时间(批量任务执行后回调schedulingconfigurer.configuretasks,让用户可以重新设置trigger,从而动态修改下次执行时间)),这种方法的弊端就是“执行时间不能实时生效”。
为此,看了下task文档,感觉若要实现实时生效功能,必须代码里手工启动/停止spring task任务。
demo如下
首先,xml里不需要配置springtask相关的executor和scheduler。其次,在代码里自定义scheduler和taskregistrar(springtask启动的类)。最后,开个线程,模拟动态修改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...
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。