当前位置: 首页 > news >正文

SpringBoot帮你优雅的关闭WEB应用程序

Graceful shutdown 应用

在这里插入图片描述

Graceful shutdown说明

Graceful shutdown is supported with all four embedded web servers (Jetty, Reactor Netty, Tomcat, and Undertow) and with both reactive and servlet-based web applications. It occurs as part of closing the application context and is performed in the earliest phase of stopping SmartLifecycle beans. This stop processing uses a timeout which provides a grace period during which existing requests will be allowed to complete but no new requests will be permitted. The exact way in which new requests are not permitted varies depending on the web server that is being used. Jetty, Reactor Netty, and Tomcat will stop accepting requests at the network layer. Undertow will accept requests but respond immediately with a service unavailable (503) response.

版本要求

对Tomcat有版本要求,不能低于9.0.33

 Graceful shutdown with Tomcat requires Tomcat 9.0.33 or later. 

配置方式

# 配置启用graceful
server.shutdown=graceful
# 配置超时等待活跃请求的时间,默认30s
spring.lifecycle.timeout-per-shutdown-phase=30s 

特别说明

监控的是SIGTERM信号,SIGTERM是Linux提供的一种优雅关闭服务的方式,通过发出一个软件终止的信号来给应用程序一个缓冲的时间,相对于SIGKILL这种,就会直接杀掉进程。

Using graceful shutdown with your IDE may not work properly if it does not send a proper SIGTERM signal. See the documentation of your IDE for more details.

验证

只需简单配置后,即可使用,启动服务,发起请求。

@Slf4j
@RestController
public class TestController {@RequestMapping("/activeRequest")public void activeRequest() throws InterruptedException {log.info("【请求执行中】");/*** spring.lifecycle.timeout-per-shutdown-phase=30s* 配置为等待30秒,因此在执行改方法后的10秒内,如果停止了web服务,依然会等待改方法执行完毕*/Thread.sleep(10000);log.info("【请求执行结束】");}}

输出日志中,可以看到,当发起停止服务时,打印了Commencing graceful shutdown. Waiting for active requests to complete,表示开始等待活跃的请求执行结束。

当执行结束后,打印Graceful shutdown complete,开始关闭其他相关资源。


2023-03-18 10:31:41.582  INFO 18056 --- [nio-8080-exec-1] c.w.controller.安全关闭WEB服务.TestController  : 【请求执行中】
Disconnected from the target VM, address: '127.0.0.1:51695', transport: 'socket'
2023-03-18 10:31:45.158  INFO 18056 --- [extShutdownHook] o.s.b.w.e.tomcat.GracefulShutdown        : Commencing graceful shutdown. Waiting for active requests to complete
2023-03-18 10:31:51.593  INFO 18056 --- [nio-8080-exec-1] c.w.controller.安全关闭WEB服务.TestController  : 【请求执行结束】耗时:10007毫秒
2023-03-18 10:31:51.656  INFO 18056 --- [tomcat-shutdown] o.s.b.w.e.tomcat.GracefulShutdown        : Graceful shutdown complete
2023-03-18 10:31:51.664  INFO 18056 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'
2023-03-18 10:31:51.665  INFO 18056 --- [extShutdownHook] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} closing ...
2023-03-18 10:31:51.677  INFO 18056 --- [extShutdownHook] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} closed

如果把spring.lifecycle.timeout-per-shutdown-phase=10s 配置改为10秒,而activeRequest方法要执行20秒

@RequestMapping("/activeRequest")
public void activeRequest() throws InterruptedException {log.info("【请求执行中】");Stopwatch started = Stopwatch.createStarted();/*** spring.lifecycle.timeout-per-shutdown-phase=10s* 配置为等待10秒,因此改方法最终不会执行完成。*/Thread.sleep(20000);log.info("【请求执行结束】耗时:" + started.elapsed(TimeUnit.MILLISECONDS) + "毫秒");
}

从日志输出Graceful shutdown aborted with one or more requests still active可以看出,最终直接终止了一个或多个依然活动的请求,【请求执行结束】也没有得到输出。


2023-03-18 10:57:16.020  INFO 22520 --- [nio-8080-exec-1] c.w.controller.安全关闭WEB服务.TestController  : 【请求执行中】
Disconnected from the target VM, address: '127.0.0.1:52322', transport: 'socket'
2023-03-18 10:57:17.471  INFO 22520 --- [extShutdownHook] o.s.b.w.e.tomcat.GracefulShutdown        : Commencing graceful shutdown. Waiting for active requests to complete
2023-03-18 10:57:27.478  INFO 22520 --- [extShutdownHook] o.s.c.support.DefaultLifecycleProcessor  : Failed to shut down 1 bean with phase value 2147483647 within timeout of 10000ms: [webServerGracefulShutdown]
2023-03-18 10:57:27.510  INFO 22520 --- [tomcat-shutdown] o.s.b.w.e.tomcat.GracefulShutdown        : Graceful shutdown aborted with one or more requests still active
2023-03-18 10:57:29.790  INFO 22520 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'
2023-03-18 10:57:29.791  INFO 22520 --- [extShutdownHook] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} closing ...

如果不配置server.shutdown=graceful,则不会有任何提示以及等待活跃请求执行完成的行为,而是直接关闭服务。

2023-03-18 11:00:15.719  INFO 3376 --- [nio-8080-exec-1] c.w.controller.安全关闭WEB服务.TestController  : 【请求执行中】
Disconnected from the target VM, address: '127.0.0.1:58704', transport: 'socket'
2023-03-18 11:00:21.086  INFO 3376 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'
2023-03-18 11:00:21.086  INFO 3376 --- [extShutdownHook] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} closing ...
2023-03-18 11:00:21.099  INFO 3376 --- [extShutdownHook] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} closed

换成Undertow服务也支持


2023-03-18 13:53:53.435  INFO 10804 --- [  XNIO-1 task-1] c.w.controller.安全关闭WEB服务.TestController  : 【请求执行中】
Disconnected from the target VM, address: '127.0.0.1:63225', transport: 'socket'
2023-03-18 13:53:54.546  INFO 10804 --- [extShutdownHook] o.s.b.w.e.undertow.UndertowWebServer     : Commencing graceful shutdown. Waiting for active requests to complete
2023-03-18 13:54:03.451  INFO 10804 --- [  XNIO-1 task-1] c.w.controller.安全关闭WEB服务.TestController  : 【请求执行结束】耗时:10009毫秒
2023-03-18 13:54:03.478  INFO 10804 --- [  XNIO-1 task-1] o.s.b.w.e.undertow.UndertowWebServer     : Graceful shutdown complete
2023-03-18 13:54:03.478  INFO 10804 --- [extShutdownHook] io.undertow                              : stopping server: Undertow - 2.2.3.Final
2023-03-18 13:54:03.487  INFO 10804 --- [extShutdownHook] io.undertow.servlet                      : Destroying Spring FrameworkServlet 'dispatcherServlet'
2023-03-18 13:54:03.489  INFO 10804 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'
2023-03-18 13:54:03.489  INFO 10804 --- [extShutdownHook] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} closing ...
2023-03-18 13:54:03.506  INFO 10804 --- [extShutdownHook] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} closed

与Tomcat不同之处,正如官方文档中说明那样,Undertow在关闭期间对于请求会直接返回503,而Tomcat则不会。

Undertow
在这里插入图片描述

Tomcat
在这里插入图片描述

相关文章:

SpringBoot帮你优雅的关闭WEB应用程序

Graceful shutdown 应用 Graceful shutdown说明 Graceful shutdown is supported with all four embedded web servers (Jetty, Reactor Netty, Tomcat, and Undertow) and with both reactive and servlet-based web applications. It occurs as part of closing the applica…...

递归与递推

递归 直白理解:函数在其内部调用自身(自己调用自己)所有递归都可以采用递归搜索树来理解递归的特点: 一般来说代码较为简短,但是理解难度大一般时间和空间消耗较大,容易产生重复计算,可能爆栈 …...

使用<style scoped>导致的样式问题

问题描述: 今天使用开源组件库TDesign的自动补全组件时,遇到了一个样式失效问题,一开始怎么也找不到问题出在哪,后面一个偶然去掉了scoped,竟然发现样式竟然正常了,具体原因不知道在哪,有大佬知…...

Elasticsearch深入理解(十八)-集群关键指标及调优指南

1、CPU使用率 CPU使用率是指在一段时间内CPU执行程序的百分比,它是衡量系统资源利用率的一种指标。 1.1 详细说明: 在Elasticsearch中,高的CPU使用率通常意味着节点正在执行大量的计算任务,这可能是因为索引和搜索操作的负载较大…...

Transformer到底为何这么牛

从注意力机制(attention)开始,近两年提及最多的就是Transformer了,那么Transformer到底是什么机制,凭啥这么牛?各个领域都能用?一文带你揭开Transformer的神秘面纱。 目录 1.深度学习&#xff0…...

【Spring事务】声明式事务 使用详解

个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~ 个人主页:.29.的博客 学习社区:进去逛一逛~ 声明式事务一、编程式事务二、声明式事务&…...

学习28个案例总结

学习前 对于之前遇到的问题没有及时总结,导致做什么事情都是新的一样。没有把之前学习到接触到的内容应用上。通过这次对28个案例的学习。把之前遇到的问题总结成自己的经验,在以后的开发过程中避免踩重复性的坑。多看帮助少走弯路。 学习中 对28个案例…...

刷题Java常用方法总结

刷题Java常用方法总结 文章目录刷题Java常用方法总结快速查看:静态数组 Static Array初始化instance属性length技巧Arrays.sort从小到大排序Arrays.fill填满一个数组Arrays.copyOf / arr.clone()复制一个数组(二维数组也可以)动态数组 List & Dynamic Array初始化常规 - Ar…...

大数据技术之Hive

第1章Hive基本概念1.1 Hive1.1.1 Hive的产生背景在那一年的大数据开源社区,我们有了HDFS来存储海量数据、MapReduce来对海量数据进行分布式并行计算、Yarn来实现资源管理和作业调度。但是面对海量数据和负责的业务逻辑,开发人员要编写MR来对数据进行统计…...

第33篇:Java集合类框架总结

目录 1、集合概念 2、集合与数组的区别 3、集合框架的特性 1)高性能 2)可操作...

数据结构 | 栈的中缀表达式求值

目录 什么是栈? 栈的基本操作 入栈操作 出栈操作 取栈顶元素 中缀表达式求值 实现思路 具体代码 什么是栈? 栈是一种线性数据结构,具有“先进后出”(Last In First Out, LIFO)的特点。它可以看作是一种受限的…...

vue2前端实现html导出pdf功能

1. 功能实现方案 1.html转换成canvas后生成图片导出pdf(本文选用) html转canvas插件:html2canvas是一款将HTML代码转换成Canvas的插件;canvas生成pdf:jsPDF是一个使用Javascript语言生成PDF的开源库 2.HTML代码转出…...

用 ChatGPT 辅助学好机器学习

文章目录一、前言二、主要内容🍉 CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 一、前言 探索更高效的学习方法可能是有志者共同的追求,用好 ChatGPT,先行于未来。 作为一个人工智能大语言模型,ChatGPT 可以在帮助初…...

【动态规划】最长上升子序列(单调队列、贪心优化)

Halo,这里是Ppeua。平时主要更新C语言,C,数据结构算法......感兴趣就关注我吧!你定不会失望。 🌈个人主页:主页链接 🌈算法专栏:专栏链接 我会一直往里填充内容哒! &…...

海思SD3403/SS928V100开发(7)mcp2515-SPI转CAN驱动开发

1. 前言 需求: 需要一路can进行收发 分析: 根据目前使用较多的方案是使用主控端SPI接口 接入MCP2515芯片进行CAN协议转换 硬件: MCP2515->SPI2->SS928 2. Uboot开发 2.1 pinmux复用配置 2.1.1 修改uboot参数表 路径: osdrv/tools/pc/uboot_tools/ SS928V100…...

【安卓源码】SurfaceFlinger 启动及其与应用通信

1. surfaceFlinger 初始化和消息队列处理机制 surfaceflinger 的makefile 文件 /frameworks/native/services/surfaceflinger/Android.bp 235 cc_binary { 236 name: "surfaceflinger", 237 defaults: ["libsurfaceflinger_binary"], 238 i…...

springboot车辆充电桩

sprinboot车辆充电桩演示录像2022开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7(一定要5.7版本) 数据库工具:Navicat11 开发软件:ecli…...

linux进程和进程通信编程(1)

What makes the desert beautiful is that somewhere it hides a well. 沙漠之所以美丽,是因为在它的某个角落隐藏着一口井. linux进程和进程通信编程(1)1.什么是进程2.进程id(pid)3.进程间通信的方法管道信号IPCSocket4.创建进程forkfork有三个返回值父…...

操作系统(1.3)--习题

一、课堂习题 1、一个作业第一 次执行时用了5min ,而第二次执行时用了6min,这说明了操作系统的( )特点。 A、并发性 B、共享性 C、虚拟性 D、不确定性 D 2、在计算机系统中,操作系统是( )。 A、处于裸机之上的第一层软件 B、处于硬件之下的低层软件 C、处于应用软件之上的系统软…...

刷题笔记之十三(有假币、最难的问题、因子个数)

目录 1. 求正数数组的最小不可组成和 2. 有假币 3. 继承时先调用父类的构造方法;类中的成员变量的初始化操作都在构造方法时进行 4. 学会并理解装箱拆箱,注意new出来的也可以拆!! 5. getDeclaredMethods()是标识类或接口的声明成员(这个表示public private 包访问权限 pro…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...

React---day11

14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...

深入浅出Diffusion模型:从原理到实践的全方位教程

I. 引言:生成式AI的黎明 – Diffusion模型是什么? 近年来,生成式人工智能(Generative AI)领域取得了爆炸性的进展,模型能够根据简单的文本提示创作出逼真的图像、连贯的文本,乃至更多令人惊叹的…...

Leetcode33( 搜索旋转排序数组)

题目表述 整数数组 nums 按升序排列&#xff0c;数组中的值 互不相同 。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 < k < nums.length&#xff09;上进行了 旋转&#xff0c;使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...

基于鸿蒙(HarmonyOS5)的打车小程序

1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...

快速排序算法改进:随机快排-荷兰国旗划分详解

随机快速排序-荷兰国旗划分算法详解 一、基础知识回顾1.1 快速排序简介1.2 荷兰国旗问题 二、随机快排 - 荷兰国旗划分原理2.1 随机化枢轴选择2.2 荷兰国旗划分过程2.3 结合随机快排与荷兰国旗划分 三、代码实现3.1 Python实现3.2 Java实现3.3 C实现 四、性能分析4.1 时间复杂度…...