【实践】SpringSchedule实现动态配置
背景
在分布式环境下实现调度功能,我们一般会使用一些第三方的分布式定时调度任务平台或引擎,例如XXL-JOB、Elastic-Job、Quartz等。
而在单体项目中,我们大多直接使用Spring框架提供的@Scheduled注解实现定时任务。但是@Scheduled注解的用法只能硬编码,无法动态配置,存在局限性。
这时我们需要改为使用org.springframework.scheduling.annotation.SchedulingConfigurer
SchedulingConfigurer
SchedulingConfigurer是@Scheduled的全局配置入口/高级用法,允许我们定制@Scheduled的底层调度行为,可以自定义Spring定时任务使用的调度器(线程池、触发器、动态 cron 等)
动态调度
在使用@Scheduled时,我配置了项目启动60s后,每60s秒执行一次
java
@Scheduled(fixedRate = 1000 * 60, initialDelay = 1000 * 60)
public void exec() {
}改为使用SchedulingConfigurer
java
@Configuration
@EnableScheduling
public class DynamicScheduleConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.addTriggerTask(
// 要执行的任务
DynamicScheduleConfig::exec,
// 动态触发器
triggerContext -> {
// 动态获取执行间隔(单位:毫秒)
long interval = getInterval() * 1000;
Date lastActualExecutionTime = triggerContext.lastActualExecutionTime();
if (lastActualExecutionTime == null) {
return new Date(System.currentTimeMillis() + interval);
}
return new Date(lastActualExecutionTime.getTime() + interval);
}
);
}
public void exec() {
}
public long getInterval() {
// 此处可以从数据库或配置中心获取
return 60;
}
}动态Cron
如果相实现动态的Cron表达式,则可以将上面的addTriggerTask替换成addCronTask即可。除了传入执行的任务外再传入表达式,表达式可以选择从数据库或配置中心进行获取