如何关闭 Spring Boot 应用程序

x33g5p2x  于2022-09-25 转载在 Spring  
字(5.1k)|赞(0)|评价(0)|浏览(935)

1 概述

管理 Spring Boot 应用程序的生命周期对于生产就绪系统非常重要。 Spring 容器在 ApplicationContext. 的帮助下处理所有 Bean 的创建、初始化和销毁

这篇文章的重点是生命周期的破坏阶段。更具体地说,我们将了解关闭 Spring Boot 应用程序的不同方法。

2. 使用 Actuator EndPoint 关机

Spring Boot Actuator 带有许多生产就绪功能,包括 /shutdown 端点。默认情况下,所有 /shutdown 端点都未在执行器中启用。要在我们的应用程序中使用此端点,我们应该包含 spring-boot-starter-actuator 启动器并在我们的应用程序中启用此端点。

要包含并启用它,我们需要在我们的应用程序 pom.xml 中添加 spring-boot-starter-actuator 启动器,并要求使用 application.propertiesapplication.yml 文件启用 /shutdown 端点。这是我们设置它的 Maven 依赖项。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.0.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.dailycodebuffer.example</groupId>
	<artifactId>Spring-Boot-Shutdown</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>Spring-Boot-Shutdown</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>11</java.version>
	</properties>

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

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

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

要配置端点的启用,请使用其 management.endpoint..enabled 属性。这就是我们的 application.properties 添加更改后的样子。

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

2.1 安全端点

在此示例中,我们在没有任何安全措施的情况下公开了 /endpoint。不建议在您的生产应用程序上执行此操作。这可能会给您的应用程序带来很大的安全风险。要保护您的关闭端点,请使用 spring-boot-starter-security 启动器。

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

要关闭 Spring Boot 应用程序,我们只需像这样调用 POST 方法

curl -X POST localhost:port/actuator/shutdown

在此调用中,port 代表执行器端口。

3. 关闭 ApplicationContext

关闭 Spring Boot 应用程序* 的另一个选项是使用 SpringApplication 关闭 Spring ApplicationContext。 SpringApplication.run(String…) 方法返回 ApplicationContext 作为 ConfigurableApplicationContext 我们可以使用 close() 方法以编程方式关闭 ApplicationContext。

@SpringBootApplication
public class SpringBootShutdownApplication {

 public static void main(String[] args) {

  ConfigurableApplicationContext ctx = SpringApplication.run(SpringBootShutdownApplication.class, args);
  ctx.close();
 }
}

为了处理 ApplicationContext 关闭事件,让我们使用 @PreDestroy 注释创建一个关闭句柄方法。

@Configuration
public class ApplicationConfig {

 @PreDestroy
 public void onShutDown() {
  System.out.println("closing application context..let's do the final resource cleanup");
 }
}

4. 退出 SpringApplication

我们还可以选择使用 SpringApplication 类提供的静态退出辅助方法。

@SpringBootApplication
public class SpringBootShutdownApplication {

 public static void main(String[] args) {

  ConfigurableApplicationContext ctx = SpringApplication.run(SpringBootShutdownApplication.class, args);
  exitApplication(ctx);
  //ctx.close();
 }

 public static void exitApplication(ConfigurableApplicationContext ctx) {
  int exitCode = SpringApplication.exit(ctx, new ExitCodeGenerator() {
   @Override
   public int getExitCode() {
    // no errors
    return 0;
   }
  });
  System.exit(exitCode);
 }
}

5. 终止应用程序进程

使用Spring Boot 应用程序将 PID 写入文件。我们可以使用 PID 文件来停止或重新启动,或者使用 bash 脚本获取状态。我们使用 ApplicationPidFileWriter 将 PID 写入文件。

SpringApplication application = new SpringApplication(SpringBootShutdownApplication.class);
application.addListeners(new ApplicationPidFileWriter("./bin/app.pid"));
application.run();

接下来,创建一个包含以下内容的 shutdown.bat 文件:

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

shutdown.bat 的执行从 app.pid 文件中提取进程 ID,并使用 kill 命令终止启动应用程序。

6 总结

在这篇快速文章中,我们介绍了一些可用于关闭正在运行的 Spring Boot 应用程序的简单方法。

虽然由开发人员选择合适的方法;所有这些方法都应该被设计和有目的地使用。

例如,当我们需要将错误代码传递到另一个环境(例如 JVM 以进行进一步操作)时,首选 .exit()。使用** ApplicationPID 提供了更大的灵活性,因为我们还可以使用 bash 脚本启动或重新启动应用程序**。

最后,/shutdown ** 在这里可以 通过 HTTP** 在外部终止应用程序。对于所有其他情况,.close() 将完美运行。
Github 代码

Click here to pull the code

相关文章