a65ecfcc2754f882568e2f84bffdcf07.png

前言

在生产环境下管理Spring Boot应用的生命周期非常重要。Spring容器通过ApplicationContext处理应用服务的所有的beans的创建、初始化、销毁。
本文着重于生命周期中的销毁阶段的处理,我将使用多种方式来实现关闭Spring Boot应用服务。如果你需要了解关于Spring Boot更多内容,请看我之前写过的文章和精品合辑!

一、通过Actuator Shutdown 端点服务

Spring Boot Actuator是一个主要用于应用指标监控和健康检查的服务。可以通过Http访问对应的Endpoint来获取应用的健康及指标信息。另外,它还提供了一个远程通过http实现应用shutdown的端点。
首先,我们要在Spring Boot中引入Actuator。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

生产环境通常出于安全考虑,不能将应用关闭的访问完全公开,我们还要引入spring-boot-starter-security。具体的安全配置,请参考学习Spring security,在此不多做叙述!

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

默认情况下,出于安全考虑shutdown端点服务是处于关闭状态的,我们需要通过配置开启:

management.endpoints.web.exposure.include=*
management.endpoint.shutdown.enabled=true
endpoints.shutdown.enabled=true

至此,我们就可以通过发送一个Post请求,来停掉Spring Boot应用服务。

curl -X POST localhost:port/actuator/shutdown

这种方法的缺陷在于:当你引入Actuator的shutdown服务的时候,其他的监控服务也自动被引入了。

二、 关闭Application Context

我们也可以自己实现一个Controller开放访问端点,调用Application Context的close方法实现应用服务的关闭。

@RestController
public class ShutdownController implements ApplicationContextAware {

    private ApplicationContext context;

    @PostMapping("/shutdownContext")
    public void shutdownContext() {
        ((ConfigurableApplicationContext) context).close();
    }

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

    }
}

我们添加了一个Controller继承自ApplicationContextAware接口,并且重写了setApplicationContext方法获取当前的应用上下文。然后在Post请求方法中调用close方法关闭当前应用。这种实现的方法更加轻量级,不会像Actuator一样引入更多的内容。我们同样可以通过发送Post请求,实现应用的关闭。

curl -X POST localhost:port/shutdownContext

同样,当你对外开放一个关闭服务的端点,你要考虑它的权限与安全性

四、退出 SpringApplication

还可以通过SpringApplication 向JVM注册一个 shutdown 钩子来确保应用服务正确的关闭。

ConfigurableApplicationContext ctx = new SpringApplicationBuilder(Application.class)
  .web(WebApplicationType.NONE).run();

int exitCode = SpringApplication.exit(ctx, new ExitCodeGenerator() {
@Override
public int getExitCode() {
        // return the error code
        return 0;
    }
});

System.exit(exitCode);

同样的效果,使用Java 8 lambda可以这样实现,代码简单很多:

SpringApplication.exit(ctx, () -> 0);

五、kill杀掉应用进程

我们还可以使用bat或者shell脚本来停止应用的进程。所以,我们首先在应用启动的时候,要把进程ID写到一个文件里面。如下所示:

SpringApplicationBuilder app = new SpringApplicationBuilder(Application.class)
  .web(WebApplicationType.NONE);
app.build().addListeners(new ApplicationPidFileWriter("./bin/shutdown.pid"));
app.run();

创建一个shutdown.bat脚本,内容如下:

kill $(cat ./bin/shutdown.pid)

然后调用这个脚本就可以把应用服务进程杀死。
欢迎大家关注,转发,此外给大家整理了一些详细SpringBoot的方面的资料,点击链接https://shimo.im/docs/k6xtWVdqw3tyh36p/《Java学习、面试;文档、视频资源免费获取》即可获得文档领取方式

3b5504d2bad8e7bf5b73a566f976de80.png


本书以丰富的实例,介绍了如何使用Spring Boot开发框架进行基础应用和分布式应用等方面的开发,并且介绍了如何使用Spring Boot开发的应用搭建一个高性能的服务平台,同时还对Spring Boot的一些核心功能的源代码进行了分析,从而加深对Spring Boot的理解。
书中对从最基本的入门知识,到数据库的使用,以及界面设计、安全设计等领域都做了详细的介绍和探讨,并在分布式应用系统领域,以平台级应用系统的实例,介绍了如何创建和使用SSO管理系统、分布式文件系统,如何使用SpringCloud进行云应用方面的开发,以及如何使用Docker发布和构建高可用的分布式系统服务平台。同时,对Spring Boot的程序加载、自动配置、数据管理,和Spring Cloud的配置管理、发现服务和负载均衡服务等核心功能的源代码做了深入剖析,这样在认识其实现原理的基础上,能更好地使用其相应的功能。
全书分为三个部分:第一部分(第1 ~ 5章)
介绍基础应用方面的开发,包含简单人门知识、数据库使用、界面设计和安全设计等内容;
第二部分(第6 ~ 9章)
介绍了Spring Boot在分布式系统开发和云应用开发等方面的应用以及使用微服务构建高可用的服务平台;
第三部分(第10 ~】2章)
对Spring Boot的程序加载、自动配置和数据管理的实现原理,以及Spring Cloud的配置管理、发现服务和负载均衡服务等实现原理进行了深入的剖析。

da601ded5e9db3081fcbfe3022351b6f.png

d6aa003c1c7760a63955e20aa7b8bef8.png

a01fe25c1a6119e2ffbe85477b3611ef.png

54f148f7f1f3d6a5d76f5040993e2a9a.png

7f1b013923ee23682cefdd8a32524169.png

点击链接https://shimo.im/docs/k6xtWVdqw3tyh36p/《Java学习、面试;文档、视频资源免费获取》即可获得文档领取方式

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐