springboot+quartz优雅关闭

新手上路,请多包涵

求助大佬,如果springboot还整合了quartz,那如何进行优雅关闭?quartz也需要进行优雅关闭。我之前使用actuator进行优雅关闭,在ContextClosedEvent中使用scheduler.shutdown(true)来优雅关闭quartz,不过这样做偶尔会关闭失败。尤其是当我程序运行几天后再执行优雅关闭就会大概率停不了程序,只能被迫暴力关闭

阅读 4.3k
1 个回答

在关闭Springboot应用时,想要保证执行中的定时任务不被中断而导致程序数据错误,需要在Springboot关闭的时候,先停止定时任务的执行。
如:

package com.azhuzhu.job.config;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.stereotype.Component;

/**
 * 系统关闭时,关闭定时任务的执行(等待运行中的任务执行完成)
 * <p>监听ContextClosedEvent事件 会在SpringBoot应用关闭,准备销毁Context以及里面的Bean时调用</p>
 * <p>因为Bean被销毁之后程序肯定无法执行了,所以需要在这之前触发关闭Quartz</p>
 *
 * @author azhuzhu
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class QuartzShutdownListener implements ApplicationListener<ContextClosedEvent> {

    private final Scheduler quartzScheduler;

    @Override
    public void onApplicationEvent(ContextClosedEvent contextClosedEvent) {
        try {
            log.info("-------------------等待运行中的定时任务执行完成-------------------");
            // Quartz框架提供的方法,等待所有任务执行完成之后关闭调度器Scheduler,等待期间不再触发新的任务
            quartzScheduler.shutdown(true);
            log.info("-------------------执行完成,Quartz关闭-------------------");
        } catch (SchedulerException e) {
            log.info("-------------------Quartz关闭失败-------------------");
        }
    }

}
注意:如果要安全的退出应用,服务器上终止应用时,不能使用 kill -9 直接杀死进程,而是使用 kill -15 通知应用自身去结束并释放资源。

已参与 「极客观点」 ,欢迎正在阅读的你也加入。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进