Spring Boot 内嵌容器 Tomcat / Undertow / Jetty 优雅停机实现
前言Spring Boot 在关闭时如果有请求没有响应完在不同的容器会出现不同的结果例如在 Tomcat 和 Undertow 中会出现中断异常那么就有可能对业务造成影响。所以优雅停机非常有必要性目前官方是没有提供很好的策略来实现。Each SpringApplication registers a shutdown hook with the JVM to ensure that the ApplicationContext closes gracefully on exit. All the standard Spring lifecycle callbacks (such as the DisposableBean interface or the PreDestroy annotation) can be used.Spring Boot Application 在接收到停机信号后可以通过 DisposableBean 接口 、 PreDestroy 注解 或者 ContextClosedEvent 事件来处理优雅停机的相关逻辑。Tomcat 优雅停机SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } /** * 用于接受 shutdown 事件 */ Bean public GracefulShutdown gracefulShutdown() { return new GracefulShutdown(); } Bean public ServletWebServerFactory servletContainer() { TomcatServletWebServerFactory tomcat new TomcatServletWebServerFactory(); tomcat.addConnectorCustomizers(gracefulShutdown()); return tomcat; } /** * 优雅关闭 Spring Boot */ private class GracefulShutdown implements TomcatConnectorCustomizer, ApplicationListenerContextClosedEvent { private final Logger log LoggerFactory.getLogger(GracefulShutdown.class); private volatile Connector connector; private final int waitTime 30; Override public void customize(Connector connector) { this.connector connector; } Override public void onApplicationEvent(ContextClosedEvent contextClosedEvent) { this.connector.pause(); Executor executor this.connector.getProtocolHandler().getExecutor(); if (executor instanceof ThreadPoolExecutor) { try { ThreadPoolExecutor threadPoolExecutor (ThreadPoolExecutor) executor; threadPoolExecutor.shutdown(); if (!threadPoolExecutor.awaitTermination(waitTime, TimeUnit.SECONDS)) { log.warn(Tomcat thread pool did not shut down gracefully within waitTime seconds. Proceeding with forceful shutdown); } } catch (InterruptedException ex) { Thread.currentThread().interrupt(); } } } } }Undertow 优雅停机SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } /** * 优雅关闭 Spring Boot */ Component public class GracefulShutdown implements ApplicationListenerContextClosedEvent { Autowired private GracefulShutdownWrapper gracefulShutdownWrapper; Autowired private ServletWebServerApplicationContext context; Override public void onApplicationEvent(ContextClosedEvent contextClosedEvent){ gracefulShutdownWrapper.getGracefulShutdownHandler().shutdown(); try { UndertowServletWebServer webServer (UndertowServletWebServer)context.getWebServer(); Field field webServer.getClass().getDeclaredField(undertow); field.setAccessible(true); Undertow undertow (Undertow) field.get(webServer); ListUndertow.ListenerInfo listenerInfo undertow.getListenerInfo(); Undertow.ListenerInfo listener listenerInfo.get(0); ConnectorStatistics connectorStatistics listener.getConnectorStatistics(); while (connectorStatistics.getActiveConnections() 0){} }catch (Exception e){ // Application Shutdown } } } }Component public class GracefulShutdownWrapper implements HandlerWrapper{ private GracefulShutdownHandler gracefulShutdownHandler; Override public HttpHandler wrap(HttpHandler handler) { if(gracefulShutdownHandler null) { this.gracefulShutdownHandler new GracefulShutdownHandler(handler); } return gracefulShutdownHandler; } public GracefulShutdownHandler getGracefulShutdownHandler() { return gracefulShutdownHandler; } }Component AllArgsConstructor public class UndertowExtraConfiguration { private final GracefulShutdownWrapper gracefulShutdownWrapper; Bean public UndertowServletWebServerFactory servletWebServerFactory() { UndertowServletWebServerFactory factory new UndertowServletWebServerFactory(); factory.addDeploymentInfoCustomizers(deploymentInfo - deploymentInfo.addOuterHandlerChainWrapper(gracefulShutdownWrapper)); factory.addBuilderCustomizers(builder - builder.setServerOption(UndertowOptions.ENABLE_STATISTICS, true)); return factory; } }Jetty 优雅停机默认支持所有请求完毕后再关闭缺点客户端接收不到响应有待改进 福利时间如果你正在备战面试或者想要学习其他知识给大家推荐一个宝藏知识库作者整理了一些列 Java 程序员需要掌握的核心知识有需要的自取不谢。知识库地址https://farerboy.com/

相关新闻

OpenSSL genrsa 命令详解:从生成RSA私钥到理解SSL/TLS安全基石

OpenSSL genrsa 命令详解:从生成RSA私钥到理解SSL/TLS安全基石

1. 项目概述:为什么SSL证书生成是每个开发者的必修课 如果你在开发一个网站、一个API接口,或者任何需要通过网络传输数据的应用,那么“SSL/TLS”这个词你一定不陌生。它不再是大型电商或银行的专属,而是所有在线服务的标配。简单…

2026/7/26 22:50:55 阅读更多 →
SpringBoot 3 启用 spring.factories 后如何升级替换原有的 spring.factories ?

SpringBoot 3 启用 spring.factories 后如何升级替换原有的 spring.factories ?

前言 Spring Boot 3 弃用 spring.factories 不是简单的“喜新厌旧”,而是一次为了解决历史包袱、拥抱云原生和原生编译的“外科手术式”切割。这背后是旧机制在新时代下的全面溃败。 为何要弃用 spring.factories 根本原因在于,spring.factories 基于运行…

2026/7/26 22:50:55 阅读更多 →
半价逼近旗舰、开源追平闭源:当模型能力走向“够用“,AI竞争的下一道墙在哪里?

半价逼近旗舰、开源追平闭源:当模型能力走向“够用“,AI竞争的下一道墙在哪里?

半价逼近旗舰、开源追平闭源:当模型能力走向"够用",AI竞争的下一道墙在哪里? 引言:45天,旗舰能力就被下放了一半价格 2026年7月25日,Anthropic正式上线Claude Opus 5。这个时间点距离其旗舰模型F…

2026/7/26 22:50:55 阅读更多 →

最新新闻

AI代理约束工程:构建安全可靠的智能系统

AI代理约束工程:构建安全可靠的智能系统

1. 什么是AI Agent Harness Engineering?AI Agent Harness Engineering(AI代理约束工程)是近年来兴起的一个交叉学科领域,它专注于设计、开发和优化AI代理(Agent)的行为约束机制。简单来说,就是…

2026/7/26 23:11:06 阅读更多 →
四通道数字隔离器:ISO7241A

四通道数字隔离器:ISO7241A

简 介&#xff1a; 本文测试了德州仪器ISO7241A四通道数字隔离芯片的基本功能。该芯片采用SOIC-16封装&#xff0c;支持1Mbps传输速率&#xff0c;提供2500Vrms隔离耐压。测试显示&#xff1a;静态工作电流约20mA&#xff1b;在输入方波频率<1MHz时&#xff0c;输入输出保持…

2026/7/26 23:11:06 阅读更多 →
OMAP4470移动SoC架构解析:异构计算与双通道内存的设计哲学

OMAP4470移动SoC架构解析:异构计算与双通道内存的设计哲学

1. 项目概述&#xff1a;一颗被低估的移动计算心脏 在智能手机和平板电脑的早期黄金时代&#xff0c;处理器平台的竞争远比今天激烈。大家可能还记得那个百花齐放的时代&#xff0c;除了高通和苹果&#xff0c;德州仪器&#xff08;TI&#xff09;的OMAP系列处理器也曾是高端安…

2026/7/26 23:11:06 阅读更多 →
卡丁快跑组别建议国赛名额多放点名额

卡丁快跑组别建议国赛名额多放点名额

卡丁快跑国赛名额01 【卡丁快跑国赛名额】 卓老师&#xff0c;我看了评论区&#xff0c; 还是有很多感悟的&#xff0c;就好比如卡丁快跑组别&#xff0c; 这个组别为全新组别&#xff0c; 第一次引进大车来进行比赛&#xff0c; 大家在选择中也考虑到其难度性&#xff0c; 无论…

2026/7/26 23:11:06 阅读更多 →
四通道单刀单掷模拟开关:DG442DY

四通道单刀单掷模拟开关:DG442DY

**AD\Test\2026\July\TestDG442.PcbDoc *** DG442模拟开关01 【DG442DY模拟开关】 一、测试背景 这是手边的一个功能坏掉的电路板&#xff0c; 现在准备把它抛弃了。 不过上面有很多很有趣的芯片&#xff0c;我们来查看一下。 其中有一个DG442DY芯片&#xff0c; 这是一个SOP1…

2026/7/26 23:11:06 阅读更多 →
[C++ 核心机制] 别被 bool 的“简单”骗了!从寻址粒度、未定义行为到 std::vector<bool> 引用陷阱全景解构

[C++ 核心机制] 别被 bool 的“简单”骗了!从寻址粒度、未定义行为到 std::vector<bool> 引用陷阱全景解构

导读摘要&#xff1a;在 C 开发中&#xff0c;bool 常被视为最基础的数据类型&#xff0c;但其底层却隐藏着诸多反直觉的物理特性与工程陷阱。为什么表示 1 bit 逻辑值的 bool 在内存中偏偏要占用 1 字节&#xff1f;非法内存写入 0x05 为什么会引发诡异的未定义行为&#xff0…

2026/7/26 23:10:03 阅读更多 →

日新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档&#xff0c;可以直接使用&#xff01;系统支持图片、视频、摄像头等多种方式检测裂缝&#xff0c;功能强大实用。 1数据集6000张 8各类别

2026/7/26 0:00:31 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像&#xff01; pubg绝地求生目标检测数据集 1分类&#xff1a;e_body&#xff0c;14905个标签&#xff0c;txt格式 共计14244张图&#xff0c;99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/26 0:00:31 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别&#xff1a; allies enemy tag图片总量&#xff1a;7247张训练集&#xff1a;5139张验证集&#xff1a;1425张测试集&#xff1a;683张标注状态&#xff1a;全部已标注&#xff0c;即拿即用数据格式&#xff1a;支持YOLO格式及其他格式&#…

2026/7/26 0:00:31 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档&#xff0c;可以直接使用&#xff01;系统支持图片、视频、摄像头等多种方式检测裂缝&#xff0c;功能强大实用。 1数据集6000张 8各类别

2026/7/26 0:00:31 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像&#xff01; pubg绝地求生目标检测数据集 1分类&#xff1a;e_body&#xff0c;14905个标签&#xff0c;txt格式 共计14244张图&#xff0c;99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/26 0:00:31 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别&#xff1a; allies enemy tag图片总量&#xff1a;7247张训练集&#xff1a;5139张验证集&#xff1a;1425张测试集&#xff1a;683张标注状态&#xff1a;全部已标注&#xff0c;即拿即用数据格式&#xff1a;支持YOLO格式及其他格式&#…

2026/7/26 0:00:31 阅读更多 →

月新闻