Skip to content

Actuator & Graceful Shutdown#

What Is The Graceful Shutdown?#

  • Graceful shutdown refers to the process of terminating an application in a controlled manner, allowing it to complete any ongoing tasks, release resources, and ensure data integrity. Instead of abruptly terminating the application, graceful shutdown ensures that all processes are gracefully stopped, preventing any potential data corruption or loss.

 #zoom

  • For example: Usually when we see that when we develop a spring boot project on our local machine and we did some api tests by postman then we can easily see that when the spring boot application is processing our request from postman then we stop the application from our IDE then the request will be shutdown immediately. Then if we configure the graceful shutdown on our Spring Boot application then when we shutdown our project, our project will stop receiving incoming requests and the processing requests will be not shutdown immediately, our application will wait those requests finished then if there are no processing requests our application will be shutdown.
  • More information

What Is The Spring Boot Actuator?#

  • Spring Boot Actuator is a set of production-ready features and tools provided by the Spring Boot framework for monitoring and managing your application in a production environment. It allows you to gather operational information about your application, such as health, metrics, environment properties, and more. These features are useful for monitoring, diagnosing issues, and gaining insights into the runtime behavior of your Spring Boot application.
  • Moreover, the Spring Boot Actuator is also exporting Liveness and Readiness Probes which will help Spring Boot integrates better with Kubernetes deployment environment.
  • In Kubernetes, the Liveness and Readiness Kubernetes concepts represent facets of the application state.

    • The Liveness state of an application tells whether the internal state is valid. If Liveness is broken, this means that the application itself is in a failed state and cannot recover from it. In this case, the best course of action is to restart the application instance. For example, an application relying on a local cache should fail its Liveness state if the local cache is corrupted and cannot be repaired.
    • The Readiness state tells whether the application is ready to accept client requests. If the Readiness state is unready, Kubernetes should not route traffic to this instance. If an application is too busy processing a task queue, then it could declare itself as busy until its load is manageable again.
  • More information

Example#

  • So let's start an example for integrating Spring Boot application with Actuator and Graceful Shutdown.
  • Firstly, let's crate a simple Spring boot project with spring boot actuator dependency as below.
pom.xml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<dependencies>
    <!-- spring boot 3 web -->
    <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>3.1.4</version>
    </dependency>

    <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
            <version>3.1.4</version>
    </dependency>
</dependencies>
  • Then let's create a simple controller as below.
SampleController.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
package com.springboot.project.controller;

import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;
import java.util.List;

@RestController
public class SampleController {

    @RequestMapping(method = RequestMethod.GET, path = "/v1/messages", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<List<String>> getMessages() throws InterruptedException {
        Thread.sleep(25000);
        return ResponseEntity.ok(Arrays.asList("Message 1", "Message 2"));
    }

}
  • As you can see, we will assume that this api will take 25 seconds to handle an request.

Configure Graceful Shutdown#

  • Now, to configure the Graceful shutdown for our Spring Boot application, we just simply add the configuration below into our application.yaml file.
application.yaml
1
2
3
4
5
6
server:
  shutdown: graceful

spring:
  lifecycle:
    timeout-per-shutdown-phase: 35s
Configuration Key Default Value Value Description
server.shutdown immediate graceful Specifies the shutdown type for the Spring Boot application. In this case, it's set to "graceful," indicating that the application should perform a graceful shutdown. A graceful shutdown allows the application to complete any ongoing tasks before shutting down, ensuring a smoother termination process.
spring.lifecycle.timeout-per-shutdown-phase 30s 35s Sets the timeout duration for each phase of the shutdown process in the Spring application. In this case, it's configured to 35 seconds. During application shutdown, this property defines the maximum time allowed for each phase to complete. If any phase exceeds this timeout, the application may forcefully terminate the remaining tasks. A longer timeout value allows more time for cleanup tasks during shutdown.

Configure Spring Boot Actuator#

  • Then for configuring the Spring Boot Actuator, we also just add configurations below into our application.yaml file.
application.yaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
management:
  endpoints:
    jackson:
      isolated-object-mapper: false
  health:
    probes:
      enabled: true
    livenessstate:
      enabled: true
    readinessState:
      enabled: true
Configuration Key Default Value Value Description
management.endpoints.jackson.isolated-object-mapper true false This configuration is used to determine whether to use a separate, isolated ObjectMapper for endpoints. When set to false, the same ObjectMapper used for HTTP message conversion is also used for endpoints.
management.health.probes.enabled false true This configuration enables Kubernetes readiness and liveness probes. When set to true, the application will expose readiness and liveness state information that can be used by Kubernetes probes.
management.health.livenessstate.enabled false true This configuration enables liveness state information. When set to true, the application will expose liveness state information that can be used by Kubernetes liveness probes.
management.health.readinessState.enabled false true This configuration enables readiness state information. When set to true, the application will expose readiness state information that can be used by Kubernetes readiness probes.

Testing#

Graceful Shutdown#

  • Now, let's start our Spring Boot application, then use postman to make a request and also shutdown our Spring Boot application by IDE. Then we can see that the Spring Boot application will wait for the processing request handled successfully and the postman will receive the response.

 #zoom

 #zoom

  • Then now, let's start our application again, then make an api call first and stop the application. During the graceful shutdown is waiting for handling requests then from postman, let's try to make some other calls, we can see that new incoming requests will be denied by our Spring Boot server with error code ERR_CONNECTION_REFUSED.

 #zoom

  • Now, let's configure timeout-per-shutdown-phase to 10 seconds, then test again, as we can see the Graceful shutdown will wait for 10 seconds if the processing request taking more time than that then the processing request will be shutdown immediately together with the application.

 #zoom

 #zoom

Spring Boot Actuator#

  • For testing Spring Boot Actuator, we just simply start our application then we can open browser to access supported endpoints.
  • Firstly, to check the Spring Boot Actuator worked correctly, we can access /actuator endpoint. Then we can see the result is a json with some information for the health endpoints.

 #zoom

  • Now, if we continue to access the health endpoint /actuator/health then we can see the info about health which included readiness and liveness also.

 #zoom

  • Then if we continue to access the readiness at /actuator/health/readiness and liveness endpoints then we can see those status there.

 #zoom

 #zoom

  • These endpoints are very useful when we deploy Spring Boot application on Kubernetes which can help us achieve the Zero Downtime Deployment.

See Also#

References#