借助 spring-boot
开启优雅关闭终端:endpoints.shutdown.enabled: true
调用接口: POST /shutdown
用docker实现
-
docker stop/restart [-t seconds] [container_id]
发送中断信号,不会接收新的请求,之前的请求会继续运行
-
新请求无法创建连接:因为服务不再接收新的请求,所以会报503:Service Unavailable,
建议Client设置一个合适的 连接超时时间 -
超时时间[-t]:到达超时时间后,服务仍会立即中断,所以最好 设置一个合适的超时时间
-
日志:接收到中断信号后,log不会再打印,但
log.isXXXEnabled()
仍返回true
!
所以不要用log作为判断请求中断的标记,而是用System.out.print
-
代码解决
该方法只是手动关闭服务线程,前几种方法已经可以做到,不建议使用
-
实现
自定义
GracefulShutdownConfiguration
通过
@ImportAutoConfiguration(GracefulShutdownConfiguration.class)
启用配置 -
问题:停止后服务仍未关闭,用
jstack
看到仍然有线程在执行(基于我当前的服务):-
org.springframework.cloud.consul.config.ConfigWatch
解决:
spring.cloud.consul.config.watch.enabled: false
但是有些服务是需要开启的
查看源码,该线程默认要等待55s来判断结束状态,时间较长
-
ch.qos.logback.classic.AsyncAppender
解决:logback-spring 里加上
<shutdownHook class="ch.qos.logback.core.hook.DelayingShutdownHook"/>
ShutdownHookBase#close
里会调用Context.stop()
进行关闭
-
参考
-
spring boot issue: Shut down embedded servlet container gracefully
-
A graceful shutdown starter for Spring-Boot: spring-boot-graceful-shutdown
-
graceful shutdown by impl
TomcatConnectorCustomizer
: Graceful Shutdown Spring Boot Applications
GracefulShutdownConfiguration
1 |
|