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…
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- Spring Schedule Task動態改寫Cron配置方式
- 使用spring-task定時任務動態配置修改執行時間
- spring schedule實現動態配置執行時間
- SpringBoot項目中使用@Scheduled讀取動態參數
- Springboot自帶定時任務實現動態配置Cron參數方式