关闭TaskScheduler不会停止运行@Scheduled方法

时间:2018-08-14 08:40:39

标签: spring spring-boot taskscheduler spring-scheduled

我有一个带有方法@Scheduled的类

list

和taskScheduler的配置:

table

我正在尝试通过使用等待# calculate mean and sum for each column in the list of tables myfun <- function(x){ return(mean(x) * sum(x)) #mean of a column * sum of the same column } es <- lapply(LIST.OF.TABLES, function(x){apply(x,2,myfun)}) es <- sapply((es), sum)/sapply(LIST.OF.TABLES, sum) 的类来使用正常关机:

SELECT *
FROM yourtable
ORDER BY (CASE
  WHEN `date`>"2018-07-06" THEN 'date'
  ELSE DATE("2018-07-06")
) ASC,
`date` DESC;

即使我正在关闭taskScheduler和底层taskExecutor,新任务仍然由@Scheduled运行。发送SIGTERM时运行@Component @Slf4j public class MyScheduler { @Scheduled(cron = "${polling-job-cron}") //each minute public void pollingJob() { log.info("starting polling job..."); //some work log.info("polling job finished."); } } 的代码,而其他关闭taskScheduler的代码运行正常。

 @Bean
    public ThreadPoolTaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(5);
        scheduler.setThreadNamePrefix("mynameofscheduler");
        scheduler.setWaitForTasksToCompleteOnShutdown(true);
        scheduler.setAwaitTerminationSeconds(30);
        scheduler.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
        return scheduler;
    }

threadPoolPrefix记录在这些行的前面(由于行太长而无法读取,因此我已在上面进行了剪裁):

ContextClosedEvent

我认为也许使用了其他taskScheduler,但我关闭了错误的一个,但是所有@Component @Slf4j public class GracefulShutdown implements ApplicationListener<ContextClosedEvent> { private final ApplicationContext context; private final ThreadPoolTaskScheduler taskScheduler; public GracefulShutdown(ApplicationContext context, ThreadPoolTaskScheduler taskScheduler) { this.context = context; this.taskScheduler = taskScheduler; } @Override public void onApplicationEvent(ContextClosedEvent event) { log.info("Graceful shutdown - start"); log.info("Closing task scheduler"); taskScheduler.shutdown(); //1 taskScheduler.getScheduledThreadPoolExecutor().shutdown(); //2 log.error("Closed task scheduler"); //give k8s a chance to hit in readinessProbe and stop sending requests to this pod try { Thread.sleep(80000); //3 } catch (InterruptedException error) { log.info("error while trying to sleep"); error.printStackTrace(); } log.info("Closing spring context with startup date, {}, parent: {}, id: {}, name: {}", context.getStartupDate(), context.getParent(), context.getId(), context.getDisplayName()); ((ConfigurableApplicationContext) context).close(); log.info("Graceful shutdown - end"); } 都在GracefulShutdown中配置了

2 个答案:

答案 0 :(得分:0)

thx到M. Deinum。我搞砸了弹簧关闭流量。我已经通过注册关闭钩子来解决了这个问题:

 public static void main(String[] args) {
    ConfigurableApplicationContext context = SpringApplication.run(AgileStreamApplication.class, args);
    Runtime.getRuntime().addShutdownHook(new Thread(new GracefulShutdownHook(context)));
}

,现在我不必显式关闭taskSchedulers了。春天来了。

答案 1 :(得分:0)

由于默认情况下,ScheduledThreadPoolExecutor将等待所有延迟的计划任务完成执行,即使当时未运行计划任务。

尝试以下操作:

@Bean
public ThreadPoolTaskScheduler taskScheduler() {
    ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler() {
        private static final long serialVersionUID = -1L;
        @Override
        public void destroy() {
            this.getScheduledThreadPoolExecutor().setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
            super.destroy();
        }
    };
    scheduler.setPoolSize(5);
    scheduler.setThreadNamePrefix("mynameofscheduler");
    scheduler.setWaitForTasksToCompleteOnShutdown(true);
    scheduler.setAwaitTerminationSeconds(30);
    scheduler.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
    return scheduler;
}

然后ScheduledThreadPoolExecutor将仅等待当前正在运行的计划任务完成执行。