当前位置: 首页 > 知识库问答 >
问题:

如何暂停计划的任务开始使用springboot的@计划注释?

仉联
2023-03-14

我有一个简单的计划任务,它是使用@计划注释创建的。类似这样的东西-

public void doSomething() {
    // My code

}

我还有一个蓝绿色升级场景,在这个场景中,这个计划任务可能会在蓝色和绿色集群中运行。鉴于这个计划任务修改了数据库,其中一个节点可能会覆盖来自另一个节点的数据——或者最坏情况下的竞争条件。

我想暂停绿色集群上所有计划的任务,直到它准备好接受流量。我已经有了代码来监听应用程序状态的变化。

我探索了几个选择-

  1. 只需在任务开始时添加一个布尔值
  2. 向ThreadPoolTaskScheduler添加装饰程序

这些方法的问题在于,它们会跳过特定日程的任务,而不是暂停它。因此,如果任务被跳过,比如在T,并且应用程序立即变为,应用程序将不得不等待T 30分钟来刷新数据。

有没有办法在springboot暂停调度程序和立即恢复?

共有2个答案

杨赞
2023-03-14

自定义任务调度程序,直到它完成工作,并允许Spring引导执行优雅关闭

@Bean
TaskSchedulerCustomizer taskSchedulerCustomizer() {
    return taskScheduler -> {
        taskScheduler.setAwaitTerminationSeconds(60);
        taskScheduler.setWaitForTasksToCompleteOnShutdown(true);
    };
}

另一种意见

使用Shedlock锁定给定时间(可升级时间)的调度程序。它还解决了运行在所有/多个实例而不是一个实例上的调度程序。

滕学义
2023-03-14

看起来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);
  }
}

石英调度在调度任务时提供了很大的灵活性

http://www.quartz-scheduler.org/overview/

 类似资料:
  • 我使用Spring Framework的注释创建了一个简单的计划任务。 我知道可以有一个选择在这个方法开始时检查一个条件标志,但这不会停止这个方法的执行。 Spring提供了什么来停止任务吗?

  • 问题内容: 我已经使用Spring Framework的注释创建了一个简单的计划任务。 现在,当不再需要时,我想停止此任务。 我知道在此方法开始时可能有一种方法可以检查一个条件标志,但这不会停止执行此方法。 Spring提供了什么来停止任务? 问题答案: 选项1:使用后处理器 为应停止调度的bean 提供并显式调用。 选项2:维护目标豆与其未来的映射 当必须停止对bean的调度时,可以查找该映射以

  • 我认为Azure的优点之一是,我可以根据我希望服务何时可用来打开和关闭服务。 然而,我看不到如何暂停我的应用程序服务计划。有可能吗? 我想使用S1层,这样我就可以使用它提供的东西。然而,当我不使用它时,我希望能够暂停成本积累。 我从应用程序服务定价帮助中看到,即使某个应用程序处于停止状态,仍将为其计费。 然而,这种联系也清楚地表明,我只为我使用的东西付费。那么这是如何运作的呢?

  • 问题内容: 我正在使用类,并且正在使用其schedule方法执行某些任务,但是在执行了6次之后,我必须停止其任务。 我该怎么办? 问题答案: 在某个地方保留对计时器的引用,并使用: 停止所做的一切。您可以将此代码放在正在执行的任务中,以计算您经过的次数,例如

  • 计划任务系统使用说明 新版计划任务为用户提供了以下功能 创建一个计划任务 修改一个计划任务 删除计划任务 查看一个namespace的所有计划任务 查看一个namespcae的某个计划任务详细内容 查看一个计划任务的执行状况 查看任务的日志 查看创建的计划任务列表和某个计划任务的详细信息。 点击计划任务v2,进入计划任务列表,在这里可以看到用户名下的所有计划任务,点击一个计划任务,可以看到该计划任

  • 在此之前我问了一个问题。我的服务conifg是: 我编写了一个扩展mediator交易文件。该类返回文件名并向服务发送请求。服务没有输入消息。我要每天13:30的服务。我尝试添加新的计划任务。但是它不能工作?谁能告诉我如何设置这个计划任务? 我也不知道如何设置“固定服务器”。