Graceful Shutdown and Startup for Microservices with Spring Boot and Docker
This article explains how to implement graceful shutdown and startup for microservices using JVM shutdown hooks, Spring Boot listeners, Docker stop signals, and external container scripts, providing code examples and best‑practice recommendations for both built‑in and external containers.
For microservices, graceful service up‑ and down‑scaling is essential: a service should not be exposed before it is ready, and it should be removed from traffic before the host stops.
Graceful Shutdown
Basic JVM Shutdown Hook
The JVM supports graceful termination via Runtime.getRuntime().addShutdownHook(...), which works for normal exits, System.exit(), Ctrl+C, and kill signals except SIGKILL.
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
close();
}
});Spring Boot Integration
Spring Boot registers its own shutdown hook that reacts to Ctrl+C or SIGTERM (kill -15). The implementation resides in AnnotationConfigEmbeddedWebApplicationContext and its parent AbstractApplicationContext.
public void registerShutdownHook() {
if (this.shutdownHook == null) {
this.shutdownHook = new Thread() {
public void run() {
synchronized (AbstractApplicationContext.this.startupShutdownMonitor) {
AbstractApplicationContext.this.doClose();
}
}
};
Runtime.getRuntime().addShutdownHook(this.shutdownHook);
}
}When the context closes, a ContextClosedEvent is published, which can be used to deregister the service from a registry.
@Component
public class GracefulShutdownListener implements ApplicationListener<ContextClosedEvent> {
@Override
public void onApplicationEvent(ContextClosedEvent event) {
// deregister logic
zookeeperRegistry.unregister(mCurrentServiceURL);
...
}
}Docker Stop
Docker stop sends SIGTERM to PID 1, waits 10 seconds, then sends SIGKILL. Applications should handle SIGTERM to perform graceful shutdown; the timeout can be adjusted with docker stop -t.
External Container (Jetty) Shutdown Script
When using an external container, a shutdown script can invoke a custom RPC shutdown API before killing the process, e.g.,
initiate shutdown → close ports → verify shutdown → stop container.
Graceful Startup
Graceful startup ensures a service is only exposed after its listening port is ready.
Spring Boot Built‑in Container
Spring Boot publishes ContextRefreshedEvent after the container starts, but it may fire multiple times. A more reliable event is ApplicationReadyEvent, which guarantees the port is bound.
@Component
public class GracefulStartupListener implements ApplicationListener<ApplicationReadyEvent> {
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
// registration logic – graceful startup
apiRegister.register(urls);
...
}
}External Container (Jetty) Startup
For external containers, the startup script should invoke a custom RPC “startup” API after the container is running and health checks pass, following the sequence: start container → health check → register service → mark service as healthy.
Overall, by leveraging JVM shutdown hooks, Spring Boot lifecycle events, Docker signal handling, and custom scripts for external containers, developers can achieve reliable graceful up‑ and down‑scaling for microservices.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
