SpringBoot优雅停机
说明
在生产环境中,当我们需要升级或者停止服务的时候,应该希望当前服务能够服务完所有请求后再停止,从而达成优雅停机
SpringBoot如何实现优雅停机
默认SpringBoot的优雅停机功能是关闭的,需要通过配置项打开
1 | #server.shutdown=immediate |
该配置项默认为immediate,即收到停止信号时,直接关闭服务,没有服务完的请求也直接放弃,这样会导致客户端出现报错
当将此配置改为graceful后,应用在收到停止信号时,会先服务完当前的请求后再关闭服务
实验
编写一个测试Controller
1 |
|
通过curl命令模拟请求应用,正常会睡眠20秒
1 | curl http://127.0.0.1:9090/test |
在20秒内,给应用发送SEGTERM信号,应用不会立马结束,会等本次请求服务完再停止,客户端curl也收到响应体test字符串,优雅停机成功
原理
这里主要是spring框架利用的jvm的ShutdownHook功能,注册一个ShutdownHook的方法如下
1 | Runtime.getRuntime().addShutdownHook(new Thread(()->{ |
当注册上述关闭钩子后,jvm在收到停止信号时,就会调用一段自定义处理逻辑
spring框架内有一个是否注册关闭钩子的配置项
1 | spring.main.register-shutdown-hook=true |
此配置项默认打开,如关闭此配置项,则上述所说的优雅关闭功能也会失效
此外,注解@PreDestroy的实现,也是基于上述原理
补充
当应用接收到SEGTERM信号后,则不再提供服务,新的请求将会直接被拒绝,所以真正实现优雅,最好可以配合注册中心的线下功能,让新的流量在执行优雅停机之前就不再打到该应用上了
另外,当应用收到的是强杀指令kill -9,即SEGKILL信号时,操作系统会直接干掉jvm,不给jvm任何狡辩的机会,即使开启上述配置也无法做到优雅停机
- Title: SpringBoot优雅停机
- Author: liminjun
- Created at: 2023-05-15 10:35:39
- Updated at: 2023-05-15 15:23:58
- Link: https://olldbg.github.io/2023/05/15/Springboot优雅停机/
- License: This work is licensed under CC BY-NC-SA 4.0.