目录

服务优雅关闭 与 暴力关闭

Actuator shutdown 优雅关闭服务

ConfigurableApplicationContext 关闭服务

Spring Boot 服务打包排除指定文件


服务优雅关闭 与 暴力关闭

1、使用 Spring Boot 服务时,都要涉及到服务的停止和启动,停止服务很多时候大家都是 kill -9 暴力杀掉进程,而很多时候都需要安全的将服务停止,把没有处理完的工作继续处理完成,比如停止一些依赖的服务,输出一些日志,发一些信号给其他的应用系统等等,这在保证系统的高可用是非常有必要的。

2、优雅关闭服务:

第一步:停止接收请求和内部线程。
第二步:判断是否有线程正在执行。
第三步:等待正在执行的线程执行完毕。
第四步:停止容器。

3、为了能明显看到服务关闭,在启动类中加上  @PreDestroy 标识的方法(可以在任意 bean 中添加 @PreDestroy),服务关闭的时候会销毁 Bean,销毁时就会调用 bean 中 PreDestroy 标识的方法。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import javax.annotation.PreDestroy;
/**
 * @author wangmaoxiong
 */
@SpringBootApplication
public class MybatisStudyApplication {

    private static final Logger logger = LoggerFactory.getLogger(MybatisStudyApplication.class);

    public static void main(String[] args) {
        SpringApplication.run(MybatisStudyApplication.class, args);
    }
    /**
     * 服务关闭的时候会销毁 Bean,此时就会调用 bean 中 PreDestroy 标识的方法
     */
    @PreDestroy
    public void shutdownApp() {
        logger.info("应用关闭!");
    }
}

Actuator shutdown 优雅关闭服务

1、Spring Boot Actuator 提供的 shutdown  端点允许应用以优雅的方式关闭。

一:导入 Actuator  依赖

        <!--监控和管理应用程序-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

二:启用 shutdown 端点并公开

management:
  endpoint:
    shutdown:
      enabled: true #启用 shutdown 端点,默认是未启用的
  endpoints:
    web:
      exposure:
        include: health,info,shutdown #对外公开 health,info,shutdown 端点,默认只会公开前两个

三:post 访问 shutdown 端点即可优雅关闭服务:http://127.0.0.1:8080/actuator/shutdown

更多 Actuator 可参考:Spring Boot Actuator 监控和管理应用程序

ConfigurableApplicationContext 关闭服务

1、获取 Spring boot 服务启动时候的 ConfigurableApplicationContext,其中提供了关闭应用的方法。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import javax.annotation.PreDestroy;
/**
 * @author wangmaoxiong
 */
@SpringBootApplication
public class MybatisStudyApplication {
    /**
     * 获取启动类中 SpringApplication.run 方法返回的配置应用上下文
     * 为了操作方便,这里直接作为静态成员变量存储,需要使用的时候,直接 类名.变量名
     */
    public static ConfigurableApplicationContext configurableApplicationContext;

    public static void main(String[] args) {
        configurableApplicationContext = SpringApplication.run(MybatisStudyApplication.class, args);
    }
}

2、对外提供一个关闭服务的接口:

import com.wmx.mybatisstudy.MybatisStudyApplication;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * @author wangMaoXiong
 * @version 1.0
 * @date 2020/10/19 19:36
 */
@RestController
public class AppController {
    private static Logger logger = LoggerFactory.getLogger(AppController.class);
    /**
     * http://127.0.0.1:8080/app/shutdown
     *
     * @return
     */
    @GetMapping("app/shutdown")
    public void shutdown() {
        logger.info("用户手动请求关闭服务.");
        MybatisStudyApplication.configurableApplicationContext.close();
    }
}

Spring Boot 服务打包排除指定文件或目录

1、Spring boot 应用打包时忽略某些文件或者目录,本文环境 Java JDK 1.8 + Spring Boot 2.1.3。

2、亲测在 pom.xml 中使用 <resources> <excludes> 无法排除,需要借助 maven-jar-plugin 插件才行。

    <build>
        <plugins>
            <!--Spring Boot 应用 Maven 打包插件(如果下面 maven-jar-plugin 需要排除启动类,则自己必须注释掉,否则可以不用注释) -->
            <!--<plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>-->

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <excludes>
                        <!-- 排除启动类(此时必须将 spring-boot-maven-plugin 注释掉,否则打包报错,因为它需要启动类) -->
                        <!-- 不排除启动类时,spring-boot-maven-plugin 可以不用注释掉 -->
                        <exclude>com/wmx/wmxredis/WmxRedisApplication.class</exclude>
                        <!-- 排除com.wmx包下所有以Controller结尾的控制层(两个星号表示任意级次,一个星表示任意字符) -->
                        <exclude>com/wmx/**/*Controller.class</exclude>
                        <!-- 排除com.wmx包下所有controller目录下的文件 -->
                        <exclude>com/wmx/**/controller/**</exclude>
                        <!-- 排除com.wmx包下的RedisConfig配置类 -->
                        <exclude>com/wmx/**/RedisConfig.class</exclude>
                        <!-- 排除 /resources 路径下的资源文件 -->
                        <exclude>*.yml</exclude>
                        <exclude>*.properties</exclude>
                        <exclude>*.txt</exclude>
                        <exclude>*.sh</exclude>
                        <exclude>static/**</exclude>
                        <exclude>public/**</exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

 源码:pom-exlude.xml · 汪少棠/wmx-redis - Gitee.com

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐