优雅关闭SpringBoot项目-接口方式

前言

一般在服务器重新部署SpringBoot项目,无非就是用kill -9暴力停止进程,但会造成很多数据问题,如果遇到一些耗时或者正在处理交易类的业务时,直接导致数据异常,严重会导致一些预想不到的后果。针对这种情况也有很多解决办法,我这里只列举接口的方式,感觉这是比较方便的做法,就算是把接口暴露到了外网,只需要在接口里面做好权限校验,也能防止被外部调用,保证接口的安全性。

实现

SpringBoot 官方文档上,已经告诉开发者只需要实现特定接口即可监听到项目启动成功与关闭时的事件,相关接口如下:

CommandLineRunner接口:当应用启动成功后但在开始接受流量之前,会回调此接口的实现类,也可以实现ApplicationRunner接口,工作的方式与CommandLineRunner与之类似。
DisposableBean接口:当应用正要被销毁前,会回调此接口的实现类,也可以使用@PreDestroy注解,被标记的方法也会被调用。
基于此流程,我们可以创建一个服务监听类,用于监听到项目启动成功与关闭时的回调服务,示例代码如下:

import org.springframework.beans.factory.DisposableBean;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class AppListener implements CommandLineRunner, DisposableBean {

    @Override
    public void run(String... args) throws Exception {
        System.out.println("应用启动成功,预加载相关数据....");
        for (int i = 0; i < 30; i++){
            Thread.sleep(1000);
            System.out.println("业务---" + i);
        }
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("应用正在关闭,清理相关数据....");
    }

}

每一个SpringApplication在启用的时候,都会向JVM注册一个关闭钩子shutdownhook,以确保ApplicationContext在退出的时候,通过这个勾子通知JVM,实现服务正常的关闭。

新建一个controller用于关闭服务

@RestController
public class ShutdownController implements ApplicationContextAware {

    private ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;
    }

    /**
     * 关闭服务
     */
    @GetMapping("/shutdown")
    public void shutdownContext() {
        ((ConfigurableApplicationContext) context).close();
    }
}

调用接口:http://localhost:8080/shutdown

此时会发现会等待项目的所有在运行的逻辑全部关闭后,再自动关闭整个服务。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西瓜不甜柠檬不酸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值