▶ Spring Boot 依赖与配置
Maven 依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>com.github.timpeeters</groupId>
<artifactId>spring-boot-graceful-shutdown</artifactId>
<version>2.1.1</version>
</dependency>
▶ Graceful Shutdown 配置说明
配置项 | 默认值 | 描述 |
---|---|---|
graceful.shutdown.enabled | false | 是否启用优雅停机 |
graceful.shutdown.timeout | 60 | 在关闭 Tomcat Connector 之前等待活跃线程完成的秒数 |
graceful.shutdown.wait | 30 | 优雅停机前,服务处于 OUT_OF_SERVICE 的时间 |
▶ Graceful Shutdown 流程
- JVM 接受 SIGTERM 信号,开始关闭 Spring Container
- Spring EventListener 监听 ContextClosedEvent 事件,关闭开始后回调
- EventListener 更新 Spring Boot HealthIndicator 为 "OUT_OF_SERVICE"
- 使用 Thread.sleep 延迟 Context 关闭,以便负载均衡器查看更新的 HealthIndicator 状态,并停止向此实例转发请求
- 当 Thread.sleep 结束, Tomcat container 正常关闭。首先通过暂停 Connector,不再接受新的请求,然后通过配置的时间让 Tomcat 线程池处理活跃的线程
- 最后, Spring Context 关闭
▶ Github Demo URL
示例中,Spring Boot 配置如下:
graceful.shutdown.enabled=true
graceful.shutdown.timeout=60s
graceful.shutdown.wait=30s
正常运行时,执行 curl http://127.0.0.1:8080/actuator/health
,结果如下:
{
"status": "UP"
}
关闭服务后,30 秒内,执行 curl http://127.0.0.1:8080/actuator/health
,结果如下:
{
"status": "OUT_OF_SERVICE"
}
30 秒内,服务能正常接收新的请求。30 秒后,服务不再接受新的请求,会有如下几种情况:
- Tomcat 无请求待处理,服务立即关闭
- Tomcat 有请求待处理,处理时间在 60 秒内,服务会在所有请求处理完后立即关闭
- Tomcat 有请求待处理,处理时间超过 60 秒,服务会在 60 秒后强制关闭,异常退出