Spring Boot 2.3版本新特性
1. 正常(优雅)停机
什么是正常(优雅)停机?
官网翻译:
所有四个嵌入式Web服务器(Jetty,Reactor Netty,Tomcat和Undertow)以及响应式和基于Servlet的Web应用程序均支持正常关机。它作为关闭应用程序上下文的一部分发生,并在停止
SmartLifecycle
bean 的最早阶段执行。此停止处理使用一个超时,该超时提供一个宽限期,在此宽限期内,现有请求将被允许完成,但新请求将不被允许。不允许新请求的确切方式因所使用的Web服务器而异。Jetty,Reactor Netty和Tomcat将停止在网络层接受请求。Undertow将接受请求,但会立即以服务不可用(503)响应进行响应。当我们流量请求到此接口执行业务逻辑的时候,若服务端此时执行关机 (kill),spring boot 默认情况会直接关闭容器(tomcat 等),导致此业务逻辑执行失败。在一些业务场景下:会出现数据不一致的情况,事务逻辑不会回滚。
使用Tomcat正常关机需要Tomcat 9.0.33或更高版本。
在最新的 spring boot 2.3 版本,内置此功能,不需要再自行扩展容器线程池来处理, 目前 spring boot 嵌入式支持的 web 服务器(Jetty、Reactor Netty、Tomcat 和 Undertow)以及反应式和基于 Servlet 的 web 应用程序都支持优雅停机功能。 我们来看下如何使用:
1.1使用方式
要启用正常关机,请配置
server.shutdown=graceful
启用时(默认是immediate
),在 web 容器关闭时,web 服务器将不再接收新请求,并将等待活动请求完成的缓冲期。如以下示例所示:
配置applicationyml
文件中开启
server.shutdown=graceful
要配置超时时间,请配置
spring.lifecycle.timeout-per-shutdown-phase
属性,默认值,等待30秒,无论线程业务是否执行完毕都会停机!
如以下示例所示:
spring.lifecycle.timeout-per-shutdown-phase=20s
2. 分层jar
包 (主要配合docker)
官网翻译:
重新打包的jar 分别在
BOOT-INF/classes
和中包含应用程序的类和依赖项BOOT-INF/lib
。对于需要从jar的内容中构建docker映像的情况,能够进一步分隔这些目录,以便可以将它们写入不同的层是很有用的。
分层其实只是逻辑上的抽象而已。打出的 jar 包结构如下(jar包其实就是个压缩包,可以解压缩查看目录结构)
Buildpacks 打镜像包会使用缓存的,如果这一层没变那就不用重新打这一层,只需要重新打包修改过的层,这样一来,如果你只修改了 application 中的内容,比如新加了 Controller 或者配置文件等,那么只需要重新打包这一层,也就是几 K,几十K 不会很大,这样一来打包速度就很快了,要不然一个上百兆的镜像包也得需要一段时间。
分层的jar使用与常规重新打包的jar相同的布局,但是包括一个描述每个图层的附加元数据文件。要使用此功能,必须启用分层功能:
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.1.RELEASE</version>
<configuration>
<layers>
<enabled>true</enabled>
</layers>
</configuration>
</plugin>
</plugins>
</build>
</project>
默认情况下,定义了以下层:
dependencies
对于版本不包含的任何依赖项SNAPSHOT
。spring-boot-loader
用于jar加载程序类。snapshot-dependencies
对于其版本包含的任何依赖项SNAPSHOT
。application
应用程序类和资源。
层顺序很重要,因为它确定了部分应用程序更改时可以缓存先前的层的可能性。默认顺序为dependencies
,spring-boot-loader
,snapshot-dependencies
,application
。应该首先添加最不可能更改的内容,然后添加更可能更改的层。
作者:古时的风筝
参考来源链接:https://juejin.im/post/5ef956d06fb9a07e5c182f21
来源:掘金
1