Graceful Shutdown of Spring Cloud Microservices with Nacos – Practical Guide

This article explains why graceful shutdown is needed for Spring Cloud microservices using Nacos, compares several shutdown approaches—including kill command, /shutdown, /pause, and /service‑registry endpoints—provides configuration snippets, curl commands, and code examples, and highlights their limitations and best‑practice recommendations.

Senior Brother's Insights
Senior Brother's Insights
Senior Brother's Insights
Graceful Shutdown of Spring Cloud Microservices with Nacos – Practical Guide

Introduction

In distributed systems that rely on service registries such as Nacos or Eureka, client instances cache the list of available services to satisfy the CAP principle’s availability requirement. When a service is stopped normally, the registry is notified, but the cached lists on clients become stale for a few seconds, causing requests to be routed to a shutting‑down instance and potentially slowing down user responses. A graceful shutdown strategy avoids this problem by ensuring traffic is drained before the instance disappears from the registry.

Method 1: Using the kill Command

Spring Cloud registers a shutdown hook that automatically deregisters the instance from the registry when the JVM exits. The process can be stopped with a normal kill command: kill <em>JavaProcessId</em> The hook works for normal exits, System.exit(), or Ctrl+C, but not for kill -9 or sudden crashes. Although the instance is deregistered, the registry’s client cache may still retain the address for the default Nacos cache timeout (5 seconds), so this method does not fully solve the stale‑cache issue.

Method 2: Exposing the /shutdown Endpoint

Spring Boot Actuator provides a /shutdown endpoint that triggers the same shutdown hook. To enable it, add the actuator starter and configure exposure:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
management:
  endpoint:
    shutdown:
      enabled: true
  endpoints:
    web:
      exposure:
        include: shutdown

Then invoke the endpoint, for example:

curl -X POST http://<em>service-host</em>/actuator/shutdown

Because it also relies on the shutdown hook, the client‑cache delay remains, so this approach is not recommended for true graceful shutdown.

Method 3: Using the /pause Endpoint

Spring Boot Actuator also offers a /pause endpoint that changes the health status of an instance from UP to DOWN without terminating the JVM. Enable it as follows:

management:
  endpoint:
    pause:
      enabled: true
    restart:
      enabled: true
  endpoints:
    web:
      exposure:
        include: pause,restart

Send a POST request to pause the service:

curl -X POST http://<em>service-host</em>/actuator/pause

In practice this endpoint has inconsistent behavior across Spring Boot versions; it does not work reliably in 2.4.x and later because the underlying lifecycle handling changed. Therefore the article advises against using /pause for production shutdowns, though the idea of marking the instance as down before termination is still valuable.

Method 4: Using the /service‑registry Endpoint

Spring Cloud defines a generic ServiceRegistryEndpoint that can set the registration status of any supported registry. Enable the endpoint:

management:
  endpoints:
    web:
      exposure:
        include: service-registry
      base-path: /actuator
  endpoint:
    serviceregistry:
      enabled: true

After enabling, the actuator’s /actuator page lists the new endpoint. You can change the instance status with a POST request:

curl -X "POST" "http://localhost:8081/actuator/serviceregistry?status=DOWN" \
     -H "Content-Type: application/vnd.spring-boot.actuator.v2+json;charset=UTF-8"

Before the call the Nacos console shows the instance as "UP"; after the call it appears as "DOWN" (or "上线"/"下线" in the UI), confirming that the instance has been deregistered. The following images illustrate the UI before and after the operation:

The underlying implementation is a simple Spring Boot endpoint:

@Endpoint(id = "serviceregistry")
public class ServiceRegistryEndpoint {

   private final ServiceRegistry serviceRegistry;
   private Registration registration;

   public ServiceRegistryEndpoint(ServiceRegistry<?> serviceRegistry) {
      this.serviceRegistry = serviceRegistry;
   }

   public void setRegistration(Registration registration) {
      this.registration = registration;
   }

   @WriteOperation
   public ResponseEntity<?> setStatus(String status) {
      Assert.notNull(status, "status may not be null");
      if (this.registration == null) {
         return ResponseEntity.status(HttpStatus.NOT_FOUND).body("no registration found");
      }
      this.serviceRegistry.setStatus(this.registration, status);
      return ResponseEntity.ok().build();
   }

   @ReadOperation
   public ResponseEntity<?> getStatus() {
      if (this.registration == null) {
         return ResponseEntity.status(HttpStatus.NOT_FOUND).body("no registration found");
      }
      return ResponseEntity.ok().body(this.serviceRegistry.getStatus(this.registration));
   }
}

This endpoint works with any registry that implements Spring Cloud’s ServiceRegistry interface, so the same technique applies to Eureka, Consul, etc.

Conclusion

Graceful shutdown for Spring Cloud microservices requires more than simply stopping the JVM; the service must be marked down in the registry and given enough time for client caches to refresh. The /service‑registry endpoint provides the most reliable way to achieve this across different registries, while the /shutdown and /pause endpoints have notable limitations. Implementing a custom controller that first deregisters the instance and then waits (e.g., 5 seconds) before terminating the process is a practical pattern for production environments.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

MicroservicesNacosSpring CloudGraceful Shutdownservice registryActuator
Senior Brother's Insights
Written by

Senior Brother's Insights

A public account focused on workplace, career growth, team management, and self-improvement. The author is the writer of books including 'SpringBoot Technology Insider' and 'Drools 8 Rule Engine: Core Technology and Practice'.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.