Today I added graceful-shutdown capabilities to our Spring Boot Application.
The Springboot-Graceful-Shutdown enables your spring boot application to do a rolling deployment without any downtime on Openshift. We (SBB) use this in a dockerized Cloud environment on Openshift – it should also work on Kubernetes. We use here the terminology of Openshift/Kubernetes: Pods (roughly containers) and Services (logical load balancers that combine N containers). Openshift needs to know when a Pod is ready to respond to requests. That is done via the readyness probe. As soon as the readyness probe of a Pod fails, Openshift takes the Pod off the service, so user requests are no longer sent to this Pod.
Example Workflow:
- Openshift sends the Pod the SIGTERM signal which tells the Docker instance to shutdown all its processes. This can happen when scaling down a Pod by hand or automatically during a rolling deployment of Openshift.
- The JVM receives the SIGTERM signal and the graceful shutdown hook sets the readyness probe to false
- The process waits for a defined time to initiate the shutdown of the spring context, e.g. for 20 seconds. This time is needed for Openshift to detect that the Pod is no longer ready and to remove the pod from the service. The readyness probe check interval must in this case be configured to be less than 20 seconds.
- Openshift removes the Pod from the Service.
- After the configured wait time, for example 20 seconds, the spring context will be shut down. Open transactions will be properly finished.
- After the Spring Boot application is shutdown, the liveness probe will automatically be set to false.
- Pod is shutdown and removed.
You can find the SpringBoot Graceful Shutdown Hook on GitHub.
Adding the project to you existing Spring Boot Application is done in three simple steps.
First add the neccesarry dependencies. Use Version 1.1 of the springboot-graceful-shutdown artifact for Spring Boot 1.x applications and 2.0 for experimental Spring Boot 2 Support.
org.springframework.boot
spring-boot-starter-actuator
ch.sbb
springboot-graceful-shutdown
1.1 <!-- Spring Boot 1.x -->
2.0 <!-- Spring Boot 2 -->
Then start your application with the alternative method GracefulshutdownSpringApplication.run
instead of SpringApplication.run
.
@SpringBootApplication
public class EstaGracefullshutdownTesterApp {
public static void main(String[] args) {
GracefulshutdownSpringApplication.run(EstaGracefullshutdownTesterApp.class, args);
}
}
As a last step assure that your Readiness Probe is configured to check the /health actuator every 10 seconds. Example:
readinessProbe:
httpGet:
path: /health
port: 8080
scheme: HTTP
initialDelaySeconds: 90
timeoutSeconds: 30
timeoutSeconds: 10
failureThreshold: 3