GracefulStop 是 Tomcat 的优雅停机机制,收到指令后拒绝新连接、允许活跃请求完成,超时或连接归零后才退出;需合理配置 connectionTimeout、asyncTimeout,Spring Boot 可设 server.shutdown=graceful。

GracefulStop 是 Apache Tomcat(注意:不是 Apache HTTP Server)中用于实现服务优雅停机的机制,它本身并非 Apache Commons 或 Apache HttpClient 的标准组件。Java 生态中常被提及的“GracefulStop”实际多指 Tomcat 的 stop 或 shutdown 过程中对已有连接的平滑处理能力。
Tomcat 的 graceful shutdown 是如何工作的
Tomcat 8.5+ 默认启用优雅关闭(通过 server.xml 中的 Connector 配置项 connectionTimeout 和 shutdown 命令配合实现),其核心逻辑是:
- 收到 shutdown 指令(如发送
SHUTDOWN命令到指定端口,或调用StandardServer.stop())后,不再接受新连接; - 已建立的连接(包括正在处理的 HTTP 请求、Keep-Alive 连接、异步 Servlet、WebSocket 等)会继续完成处理;
- Connector 进入“暂停”状态,拒绝新请求,但允许活跃请求超时或自然结束;
- 当所有活跃连接归零(或达到最大等待时间),JVM 才真正退出。
关键配置与控制方式
要确保 GracefulStop 生效,需关注以下配置:
-
Connector 的
connectionTimeout应合理设置(如 20000ms),避免长连接无限阻塞关闭流程; -
启用
asyncTimeout(Tomcat 9+)以限制异步 Servlet 的最大等待时间; - 在
server.xml中确认Server元素的port和shutdown属性可用(如port="8005" shutdown="SHUTDOWN"); - Java 应用自身若使用线程池(如
Executors.newFixedThreadPool),需在ServletContextListener.contextDestroyed()中显式调用shutdownNow()并 awaitTermination; - Spring Boot 用户可启用
server.shutdown=graceful(2.3+),并配置spring.lifecycle.timeout-per-shutdown-phase=30s控制等待上限。
常见误区与注意事项
很多开发者误以为“发个 shutdown 命令就等于平滑停止”,实际上:
- HTTP Keep-Alive 连接可能持续数秒甚至分钟,若未设
keepAliveTimeout,它们会拖慢整个关闭过程; - 阻塞 I/O(如未超时的数据库查询、外部 HTTP 调用)会导致请求无法及时返回,GracefulStop 失效;
- WebSocket 或 SSE 连接若未在应用层监听
onClose并释放资源,也会阻碍关闭; - Tomcat 默认 shutdown 端口(8005)若被防火墙拦截或未监听,远程触发将失败;
- 直接
kill -9 pid绕过 JVM 关闭钩子,必然中断所有连接——务必使用kill -15或 Tomcat 自带脚本。
验证是否真正平滑
可通过以下方式确认 GracefulStop 是否生效:
- 启动时添加 JVM 参数
-Dorg.apache.catalina.STRICT_SERVLET_COMPLIANCE=true(可选,增强日志); - 观察 catalina.out 日志:出现
Waiting for [X] connector(s) to stop→Connector stopped→Server shutdown completed表明流程完整; - 压测期间发起 shutdown,用
netstat -an | grep :8080观察 ESTABLISHED 连接是否逐步归零而非瞬间消失; - 客户端侧检查是否有 502/503 或连接拒绝(Connection refused),正常应只收到已完成响应,无新请求失败。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










