微服务和云原生时代,应用的平滑启停是保障系统高可用的关键环节。 Spring Boot 在 2.3 版本引入了对内嵌 Web 容器优雅停机的原生支持,改变了此前需要手动编码实现的局面。
什么是优雅停机?
优雅停机(Graceful Shutdown) 是指在应用停止过程中完成以下动作:
- 立即停止接收新请求;
- 允许已进入的请求继续处理完成;
- 安全释放资源(数据库连接、线程池、缓存等);
- 避免客户端收到 5xx 错误或连接中断。
若未实现优雅停机,在滚动更新、缩容或重启时,极易出现如下典型异常:
ERROR ... - Error creating bean with name 'orderController': Singleton bean creation not allowed while singletons of this factory are in destruction org.springframework.beans.factory.BeanCreationNotAllowedException: ...
异常表明:Spring 容器正在销毁,但仍有请求试图获取 Controller Bean。这正是停机流程设计不当的直接体现。
核心组件与层级关系
要理解停机流程,需先厘清以下组件的包含关系:
JVM └── 内嵌 Web 容器(如 Tomcat) └── Servlet 容器(StandardContext) └── DispatcherServlet(Spring MVC 入口) └── Spring ApplicationContext(IoC 容器) └── 所有 Spring Bean(@Controller, @Service 等)
- Web 容器(Tomcat/Jetty/Undertow):负责网络连接与线程调度。
- Servlet 容器:管理 Servlet、Filter 生命周期。
- Spring 容器:即
ApplicationContext,管理 Bean 的创建与销毁。 - Spring Boot:不是容器,而是自动集成 Web 容器 + Spring 容器的启动框架。
⚠️ 关键点:Spring 容器运行在 Web 容器内部。停机时,必须协调二者关闭顺序,否则就会出现'Web 容器还在处理请求,但 Spring 容器已拒绝服务'的竞态条件。
Spring Boot < 2.3:手动实现的'伪优雅'
在 2.3 之前,Spring Boot 没有内置优雅停机能力。默认行为是:
- 收到
SIGTERM(如kill -15); - 立即关闭 Spring 容器 → 设置
singletonsCurrentlyInDestruction = true; - Web 容器仍在运行,继续 accept 新连接并分配线程;
- 若此时有请求进入,
DispatcherServlet尝试通过getBean("orderController")获取 Controller; - 因 Spring 容器已标记为'销毁中',抛出
BeanCreationNotAllowedException。


