Java 如何暂停使用springboot启动的计划任务';s@Scheduled注解?
我有一个简单的计划任务,它是使用@scheduled注释创建的。像这样的-Java 如何暂停使用springboot启动的计划任务';s@Scheduled注解?,java,spring-boot,scheduled-tasks,Java,Spring Boot,Scheduled Tasks,我有一个简单的计划任务,它是使用@scheduled注释创建的。像这样的- public void doSomething() { // My code } 我还有一个蓝绿色的升级场景,其中此计划任务可能同时在蓝绿色集群中运行。如果此计划任务修改了数据库,则其中一个节点可能会覆盖来自另一个节点的数据-或最坏情况下的竞争条件 我想暂停绿色集群上的所有计划任务,直到它准备好接受流量。我已经将代码连接到侦听应用程序状态的更改 我探索了一些选择- 只需在任务开始时添加布尔值 向ThreadP
public void doSomething() {
// My code
}
我还有一个蓝绿色的升级场景,其中此计划任务可能同时在蓝绿色集群中运行。如果此计划任务修改了数据库,则其中一个节点可能会覆盖来自另一个节点的数据-或最坏情况下的竞争条件
我想暂停绿色集群上的所有计划任务,直到它准备好接受流量。我已经将代码连接到侦听应用程序状态的更改
我探索了一些选择-
springboot中是否有方法暂停调度程序并立即恢复?自定义任务调度程序,使其等待作业完成,并允许spring boot正常关闭
@Bean
TaskSchedulerCustomizer taskSchedulerCustomizer() {
return taskScheduler -> {
taskScheduler.setAwaitTerminationSeconds(60);
taskScheduler.setWaitForTasksToCompleteOnShutdown(true);
};
}
另一种观点
用于在给定的时间量(可升级时间)内锁定计划程序。它还解决了在所有/多个实例(而不是一个实例)上运行的调度程序。看起来spring本机没有暂停计划任务的能力。在使用spring运行调度任务时,我倾向于使用Quartz调度器 为了做到这一点,我们必须进行一些配置 首先,我们必须设置上下文感知组件:
@Component
public final class ApplicationContextHolder extends SpringBeanJobFactory implements ApplicationContextAware {
private static ApplicationContext context;
private transient AutowireCapableBeanFactory beanFactory;
@Override
public void setApplicationContext(ApplicationContext ctx) throws BeansException {
if (context == null) {
beanFactory = ctx.getAutowireCapableBeanFactory();
context = ctx;
}
}
@Override
protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
final Object job = super.createJobInstance(bundle);
beanFactory.autowireBean(job);
return job;
}
/**
* Get the current application context
* @return the current context
*/
public static ApplicationContext getContext() {
return context;
}
}
然后我们的配置:
@Configuration
public class QuartzSchedulerConfig {
@Autowired
private ApplicationContext applicationContext;
/**
* Create the job factory bean
* @return Job factory bean
*/
@Bean
public JobFactory jobFactory() {
ApplicationContextHolder jobFactory = new ApplicationContextHolder();
jobFactory.setApplicationContext(applicationContext);
return jobFactory;
}
/**
* Create the Scheduler Factory bean
* @return scheduler factory object
*/
@Bean
public SchedulerFactoryBean schedulerFactory() {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setAutoStartup(true);
factory.setSchedulerName("Scheduler");
factory.setOverwriteExistingJobs(true);
factory.setJobFactory(jobFactory());
return factory;
}
}
然后我们的实际服务:
@Service
public class SchedulerService {
@Autowired
private SchedulerFactoryBean schedulerFactory;
private Scheduler scheduler;
private ScheduledExecutorService executor;
/**
* Initialize the scheduler service
*/
@PostConstruct
private void init() {
scheduler = schedulerFactory.getScheduler();
executor = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors());
}
...//Other Scheduling tasks can go here
public void pauseJob(String triggerName, String groupName) {
TriggerKey tk = new TriggerKey(triggerName, groupName);
scheduler.pauseJob(tk);
}
}
Quartz调度在调度任务时提供了很大的灵活性
这是一个不错的选择,但Shedlock中的锁定时间也是静态的。而且升级时间在多个环境中是可变的。如果我错了,请纠正我。