Springboot + Quartz安全的结束应用

在关闭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关闭失败-------------------");
        }
    }

}

新建一个测试用的Job:

package com.azhuzhu.job.demo;

import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.springframework.stereotype.Component;

/**
 * 测试任务-执行时间60s
 *
 * @author azhuzhu
 */
@Slf4j
@Component
public class ShutdownWaitJob implements Job {

    @Override
    public void execute(JobExecutionContext context) {
        int i = 60;
        while (--i > 0) {
            log.info("距离完成还有" + i + "秒");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
}

本地测试,将任务开启执行之后,在IDEA停止任务

2020-10-23 14:11:45.943  INFO 4852 --- [eduler_Worker-5] com.azhuzhu.job.demo.ShutdownWaitJob     : 距离完成还有9秒
2020-10-23 14:11:46.944  INFO 4852 --- [eduler_Worker-5] com.azhuzhu.job.demo.ShutdownWaitJob     : 距离完成还有8秒
Disconnected from the target VM, address: '127.0.0.1:61759', transport: 'socket'
2020-10-23 14:11:47.492  INFO 4852 --- [extShutdownHook] c.n.c.job.config.QuartzShutdownListener  : -------------------等待运行中的定时任务执行完成-------------------
2020-10-23 14:11:47.492  INFO 4852 --- [extShutdownHook] org.quartz.core.QuartzScheduler          : Scheduler clusteredScheduler_$_HIH-L-62831603432025356 shutting down.
2020-10-23 14:11:47.493  INFO 4852 --- [extShutdownHook] org.quartz.core.QuartzScheduler          : Scheduler clusteredScheduler_$_HIH-L-62831603432025356 paused.
2020-10-23 14:11:47.944  INFO 4852 --- [eduler_Worker-5] com.azhuzhu.job.demo.ShutdownWaitJob     : 距离完成还有7秒
2020-10-23 14:11:48.945  INFO 4852 --- [eduler_Worker-5] com.azhuzhu.job.demo.ShutdownWaitJob     : 距离完成还有6秒
2020-10-23 14:11:49.945  INFO 4852 --- [eduler_Worker-5] com.azhuzhu.job.demo.ShutdownWaitJob     : 距离完成还有5秒
2020-10-23 14:11:50.946  INFO 4852 --- [eduler_Worker-5] com.azhuzhu.job.demo.ShutdownWaitJob     : 距离完成还有4秒
2020-10-23 14:11:51.947  INFO 4852 --- [eduler_Worker-5] com.azhuzhu.job.demo.ShutdownWaitJob     : 距离完成还有3秒
2020-10-23 14:11:52.947  INFO 4852 --- [eduler_Worker-5] com.azhuzhu.job.demo.ShutdownWaitJob     : 距离完成还有2秒
2020-10-23 14:11:53.948  INFO 4852 --- [eduler_Worker-5] com.azhuzhu.job.demo.ShutdownWaitJob     : 距离完成还有1秒
2020-10-23 14:11:55.003  INFO 4852 --- [extShutdownHook] org.quartz.core.QuartzScheduler          : Scheduler clusteredScheduler_$_HIH-L-62831603432025356 shutdown complete.
2020-10-23 14:11:55.003  INFO 4852 --- [extShutdownHook] c.n.c.job.config.QuartzShutdownListener  : -------------------执行完成,Quartz关闭-------------------
2020-10-23 14:11:55.248  INFO 4852 --- [extShutdownHook] o.s.s.quartz.SchedulerFactoryBean        : Shutting down Quartz Scheduler
2020-10-23 14:11:55.252  INFO 4852 --- [extShutdownHook] o.f.j.s.i.a.AbstractAsyncExecutor        : Shutting down the async job executor [org.flowable.spring.job.service.SpringAsyncExecutor].
2020-10-23 14:11:55.252  INFO 4852 --- [uire-timer-jobs] o.f.j.s.i.a.AcquireTimerJobsRunnable     : stopped async job due acquisition
2020-10-23 14:11:55.252  INFO 4852 --- [uire-async-jobs] o.f.j.s.i.a.AcquireAsyncJobsDueRunnable  : stopped async job due acquisition
2020-10-23 14:11:55.252  INFO 4852 --- [et-expired-jobs] o.f.j.s.i.a.ResetExpiredJobsRunnable     : stopped resetting expired jobs
2020-10-23 14:11:55.261  INFO 4852 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'
2020-10-23 14:11:55.265  INFO 4852 --- [extShutdownHook] a.s.s.m.AbstractValidatingSessionManager : Disabled session validation scheduler.
2020-10-23 14:11:55.276  INFO 4852 --- [extShutdownHook] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} closing ...
2020-10-23 14:11:55.377  INFO 4852 --- [extShutdownHook] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} closed

Process finished with exit code 130

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

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值