《Spring Boot 3实战案例锦集》PDF电子书已更新至100篇!
🎉🎉《Spring Boot实战案例合集》目前已更新133个案例,我们将持续不断的更新。文末有电子书目录。
💪💪永久更新承诺
我们郑重承诺,所有订阅合集的粉丝都将享受永久免费的后续更新服务。
💌💌如何获取
订阅我们的合集《点我订阅》,并通过私信联系我们,我们将第一时间将电子书发送给您。
环境:SpringBoot3.4.2
1. 为什么要优雅停机
数据完整性:在停机过程中,如果暴力终止进程,可能会导致事务执行中断或业务处理不完整,从而在数据库或系统中留下脏数据或残留文件。优雅停机能够确保在停机前完成所有正在处理的请求,并保存相关数据,保证数据的完整性和一致性。
用户体验:优雅停机能够在终止服务前,不再接受新的请求,但会完成已接收的请求,从而避免用户请求被中断或超时,提升用户体验。
资源释放:优雅停机能够确保在停机过程中,系统资源得到正确的释放,避免资源泄露或浪费。
2. 准备测试环境
准测试的环境,模拟耗时操作及资源销毁动作。
2.1 环境准备
public class PersonService {public void destroy() {try {TimeUnit.SECONDS.sleep(5) ;} catch (InterruptedException e) {e.printStackTrace();}System.out.println("资源释放完成...") ;}}
该Bean定义了销毁方法,容器在关闭时会执行。
public Object index() {try {System.out.println("执行任务...") ;TimeUnit.SECONDS.sleep(30) ;System.out.println("任务执行完成...") ;} catch (InterruptedException e) {e.printStackTrace();}return "demo index" ;}
该接口模拟耗时任务。主要用来观察发出停机信号后该接口是否会执行完成后再停机。
2.2 暴露停机
我们先来观察下暴露停机会是什么情况。
启动服务
请求/index接口
[]
强制终止进程
通过kill -9 强制终止进程
[]31713 Jps26037 jar[][]
此时查看服务输出情况
请求的/index接口并没有执行完成,并且PersonService的销毁方法并没有执行。
3. 优雅停机方式
3.1 方式1
通过linux命令kill,但是这里我们不要添加-9 这样的参数。而是不是使用参数或者使用-15参数,示例如下:
[]
这里测试还是按照上面的方式进行,我们只需要观察服务控制台输出结果即可。
执行任务...java.lang.InterruptedException: sleep interruptedat java.lang.Thread.sleep(Native Method)资源释放完成...
当通过上面的方式终止进程后,PersonService的销毁方法执行完成以后程序才终止。确保资源的释放。为什么SpringBoot程序能正确的关闭呢?这是因为SpringBoot程序默认为JVM注册了一个关闭钩子,也就是添加了下面这样的代码
Runtime.getRuntime().addShutdownHook(...)
有兴趣可以查看下SpringApplication源码。
当我们配置了如下参数后,SpringBoot程序就算你使用kill xxx或者kill -15 xxx也会立即终止。
spring:main:register-shutdown-hook: false
关闭注册钩子。
提示:你也可以直接通过Ctrl + C的方式来终止效果与kill - 15 是一样的。
3.2 方式2
通过如下配置,开启优雅关闭
server:shutdown: graceful---spring:main:register-shutdown-hook: true
再次通过上面的方式进行测试,服务输出结果
当发出kill xxx信号后,我们请求的/index接口并没有直接终止,程序也没有立即终止而是等到所有的请求都结束以后才终止。这种优雅停机方式要比上一种优雅的太多了。
该种停机方式首先停止接收新的请求,然后等待所有正在执行的请求完成,最后关闭应用。
3.3 方式3
通过Actuator,Actuator提供了/shutdown接口,我们可以调用该接口进行程序的关闭。
引入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency>
默认情况下并没有开启shutdown接口,需要进行如下的配置
management:endpoints:web:base-path: /acexposure:include: '*'endpoint:shutdown:enabled: true
接下来测试方式与上面相同,只不过停止服务需要通过如下接口
http://localhost:8080/ac/shutdown
当执行上面接口后
服务输出结果
服务与上面一样优雅的停机等待当前正处理的请求结束后再停机。
注意:使用了该种方式一定要做好安全防护,不要随意让人都可以去调用该接口。
推荐文章
打破限制!基于 AspectJ 的 Spring AOP 增强:final/static/private 方法全支持
非常实用!玩转 Spring Boot 接口参数类型转换,支持任意场景
SpringBoot强大的分布式锁组件Lock4j,支持多种实现
以上是本篇文章的全部内容,如对你有帮助就请作者吃个棒棒糖🍭。
完毕!!!


