一,什么是优雅下线
当我们需要部署新版本代码的时候,需要重启服务,这个时候可能会出现一些问题,比如之前服务正在处理的请求还在处理,这个时候如果强制的停止服务,会造成数据丢失或者请求失败的情况。那么就需要有一种功能,当我们发出停止指令的时候,停止接收所有外部的请求,然后处理完已经接收的正在处理的请求,之后,再停止服务。这就是优雅下线。
优雅下线,也叫优雅关闭,包含以下操作:
- 停止接受新的请求
- 等待所有正在处理的请求完成
- 关闭所有连接和资源
- 释放所有内存和 CPU 资源
二,配置
server: shutdown: gracefulspring: lifecycle: timeout-per-shutdown-phase: 60000
1,server.shutdown
: 控制关闭行为,可选值包括 immediate
和 graceful
。
immediate
: 立即关闭应用,不等待正在处理的请求完成。
graceful
: 优雅关闭应用,等待正在处理的请求完成。
2, spring.lifecycle.timeout-per-shutdown-phase 超时时间,就是到了这个时间不管正在处理的请求是否完成都会关闭(如果有hook配置,可以超过这个时间的配置), 单位是毫秒。
三,案例
1,没有配置hook,系统在到了超时时间的时候就强制关闭。
模拟一个接口执行100秒,调用后立马停止项目,配置的超时时间是5000毫秒。
Waiting for workers to finish.
Successfully waited for workers to finish.
Commencing graceful shutdown. Waiting for active requests to complete
到了5000毫秒后,强制关闭
Shutdown phase 2147482623 ends with 1 bean still running after timeout of 5000ms: [webServerGracefulShutdown]
Exception java.lang.RuntimeException: java.lang.InterruptedException: sleep interrupted
Graceful shutdown aborted with one or more requests still active
2,如果需要延时,让代码执行完,系统再停止。可以添加一个hook。
先触发这个测试接口,把hook加到Spring容器,在去关闭项目,这个时候项目不会在超时时间后立马关闭,而是等到这个hook里面的逻辑执行完才关闭。
四,额外的说明
在Linux服务器上部署服务时,脚本里也需要注意一下kill命令的参数
kill -9 pid 是立即关闭服务
kill -15 pid 是发送关闭服务信号,服务接收到信号后,不再接收新的请求,并会在处理完已接收的请求之后再停止服务。