Spring Boot优雅停机
一、为什么需要优雅停机?
在更新后端服务时,肯定是希望旧版本服务切新版本服务的时候服务不间断。
首先肯定是需要让新版本服务和旧版本服务同时运行,然后将请求都转移到新版本服务上。
此时旧版本服务就不会接收到任何请求了,那么此时是要立刻关闭旧版本服务呢,还是等一会在关闭呢?
显然是等一会在关闭,因为旧版本服务中可能还存在部分用户的请求没有处理完,此时如果关闭,用户那边就会报错,因此不能立刻关闭。
那就只能让旧服务等一会再关闭了,这就是优雅停机
二、Spring Boot提供的优雅停机
依赖:
implementation 'org.springframework.boot:spring-boot-starter-actuator'
配置文件:
spring:
# 停机过程超时时长设置了20s,超过20s,直接停机
lifecycle:
timeout-per-shutdown-phase: 20s
server:
port: 8080
# GRACEFUL表示优雅关机
shutdown: graceful
management:
server:
address: 127.0.0.1
port: 8081
endpoint:
shutdown:
enabled: true
endpoints:
web:
base-path: /endpoint
exposure:
include: health,shutdown
在服务切换时调用127.0.0.1:8081/endpoint/shutdown,系统会给JVM发送SIGTERM信号,服务就会进入优雅停机状态,等待做多 timeout-per-shutdown-phase配置的秒数后,发送SIGKILL终止进程。
二、k8s环境下的优雅停机
k8s给pod也提供了一样的等待、超时、kill掉的策略。
可以和Spring Boot的优雅停机策略搭配只用,因为k8s的策略是给容器进程发送的SIGTERM信号,而不是JVM进程,要想给JVM优雅停机就需要使用Spring Boot的策略。这里是通过在k8s preStop时调用Spring Boot的shutdown接口来实现的。
需要注意的一点是terminationGracePeriodSeconds要比timeout-per-shutdown-phase
apiVersion: apps/v1
kind: Deployment
metadata:
name: A-Server
spec:
template:
spec:
# 等待60s
terminationGracePeriodSeconds: 60
containers:
lifecycle:
preStop:
exec:
command: [ "curl", "-X", "POST", "127.0.0.1:8081/endpoint/shutdown" ]
Loading...