This starter expose endpoints on a spring-boot project to perform graceful shutdown. At this time, the actuator starter expose a shutdown endpoint, this shutdown is ok to destroy graceful the spring-context, but not for currents HTTP connections.
An issue is open on github : spring-projects/spring-boot#4657 To gain time, I have written a new Spring-Boot starter based on Spring-Boot actuator. When we hit a shutdown, the starter denied new http connections and wait end of currents connections.
Endpoints exposed :
- HTTP : REST API /gracefulshutdown (with spring-boot-starter-actuator)
- JMX (with spring-boot-starter-actuator)
- SSH (with spring-boot-starter-remote-shell)
Note: Support only Undertow and Tomcat For security see actuator
We support currently : Undertow and Tomcat
3 properties in application.properties (or application.yml)
Property | Default | Description |
---|---|---|
endpoints.shutdown.graceful.enabled | false | Activate the starter and expose endpoints |
endpoints.shutdown.graceful.timeout | 30 | Wait "30" seconds before make a force shutdown |
endpoints.shutdown.graceful.wait | 30 | The time before launch graceful shutdown, the health checker return OUT_OF_SERVICE |
Call /shutdowngraceful (in GET), the endpoint return the HTTP Response code 200 with a message.
Must be documented
If the spring-boot-starter-remote-shell is in dependencies, you can type the following command
endpoint invoke gracefulShutdownEndpoint
Please refer to remote shell manual for setup and security.
Level | Sample | Description |
---|---|---|
INFO | Mapped "{[/shutdowngraceful..." | If graceful shutdown starter is enabled |
INFO | Shutdown performed in ?? second(s) | When the shutdown is performed |
INFO | Graceful shutdown in progress.. We don't accept new connection... Wait after latest connections (max : ?? seconds) | When we start a graceful shutdown |
INFO | Thread pool is empty, we stop now | No active HTTP connection, we can kill |
INFO | We are now in OUT_OF_SERVICE mode, please wait ?? second(s) | App is always alive, but the health checker return OUT_OF_SERVICE |
WARN | Thread pool did not shut down gracefully within ?? second(s). Proceeding with force shutdown | Few HTTP connections are actives, but the timeout is exceeded, we perform a force shutdown |
ERROR | The await termination has been interrupted | A force shutdown has been received before graceful shutdown |
An health checker endpoint is available to see the state of the app. The endpoint can be prefixed, see actuator doc. If the app is out of service, the response will be :
{
"status": "OUT_OF_SERVICE",
"gracefulHealth" : {
"status" : "OUT_OF_SERVICE"
}
}
The HTTP code is 503 : Service unavailable. If all is good, you must be have a 200.
The security is maintened by two points :
- Isolate Path : /management
- Isolate management opération on a specific port : please use management.port setting
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>fr.azelart</groupId>
<artifactId>spring-boot-starter-graceful-shutdown</artifactId>
<version>X.X.X</version>
</dependency>
Check the latest version on repository.
It's optionnal
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-remote-shell</artifactId>
</dependency>
In application.properties
# Enable the endpoint (mandatory)
endpoints.shutdown.graceful.enabled=true
# Specify the timeout before perform a force shutdown (optional)
endpoints.shutdown.graceful.timeout=15
# The timer before launch graceful shutdown, the health checker return OUT_OF_SERVICE (optional)
endpoints.shutdown.graceful.wait=15
Or application.yml
endpoints:
shutdown:
graceful:
enabled: true
timeout: 15
wait: 15