Operations 20 min read

How to Achieve Graceful Startup and Shutdown for Microservices with Spring Cloud, Polaris, and Docker

This article explains the principles and practical steps for implementing graceful startup and shutdown in microservices, covering service pre‑warming, registration strategies, Spring Cloud and Polaris demos, Docker container handling, and the benefits and challenges of lossless service lifecycle management.

Tencent Cloud Middleware
Tencent Cloud Middleware
Tencent Cloud Middleware
How to Achieve Graceful Startup and Shutdown for Microservices with Spring Cloud, Polaris, and Docker

Microservice graceful startup and shutdown aim to keep services stable and available during deployments by avoiding traffic interruption or errors caused by service changes.

Core Principles

Graceful startup: wait until the service is fully ready (or pre‑warmed) before exposing it.

Lossless shutdown: deregister from the registry, reject new requests, and let in‑flight requests finish before stopping.

Client resilience: use load balancing, retries, or blacklists to route only to healthy instances.

Graceful Startup Methods

Delayed release : postpone exposing the service until initialization (e.g., cache, DB pool) completes.

QoS commands : control service registration via CLI or HTTP, registering only after health checks pass.

Service registration & discovery : register with a registry (e.g., Polaris) after the service is ready and deregister on stop.

Canary release : gradually shift traffic to the new version after monitoring its behavior.

The common idea is to allow traffic only after the service is prepared.

Implementation with Spring Cloud & Polaris

First, create a Spring Cloud project and add Polaris dependencies. Configure application.properties:

spring:
  application:
    name: ${application.name}
  cloud:
    polaris:
      address: grpc://${POLARIS_ADDRESS}:8091
      namespace: default

Create a simple provider controller:

@RestController
public class ProviderController {
    @Value("${server.port}")
    private int port;

    @GetMapping("/hello")
    public String hello() {
        return "Hello, I am provider, port: " + port;
    }
}

Optionally add a health indicator using Spring Actuator:

@Component
public class DatabaseHealthIndicator implements HealthIndicator {
    @Override
    public Health health() {
        return isDatabaseConnectionOK() ? Health.up().build()
                                         : Health.down().withDetail("Error Code", "DB-001").build();
    }
    private boolean isDatabaseConnectionOK() {
        // check DB, cache, etc.
        return true;
    }
}

For the consumer, enable load‑balanced RestTemplate and call the provider by service name:

@SpringBootApplication
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }

    @Bean
    @LoadBalanced // enable client‑side load balancing
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @RestController
    public class ConsumerController {
        @Autowired
        private RestTemplate restTemplate;

        @GetMapping("/hello")
        public String hello() {
            return restTemplate.getForObject("http://provider/hello", String.class);
        }
    }
}

Graceful startup steps:

When publishing a new version, start the instance but set spring.cloud.polaris.discovery.register=false or make the health check return unhealthy, so no new traffic reaches it.

After initialization, enable registration ( spring.cloud.polaris.discovery.register=true) or mark health as healthy, allowing traffic to flow.

Service Warm‑up

Warm‑up runs the service in a ready state before full traffic, loading resources and establishing connections. Cloud‑native API gateways (e.g., Tencent Cloud API Gateway) support a “slow start” option that gradually increases instance weight.

Service warm‑up diagram
Service warm‑up diagram

Graceful Shutdown Methods

Dubbo‑go : supports graceful shutdown via its registry and load‑balancing features.

Spring Cloud : listen to ContextClosedEvent to deregister, reject new requests, wait for in‑flight requests, then stop.

Docker : use docker stop (sends SIGTERM) so the container can clean up before termination.

Spring Boot graceful shutdown can be enabled with:

# Enable graceful shutdown (default is IMMEDIATE)
server:
  shutdown: graceful
# Maximum wait time for each phase
spring:
  lifecycle:
    timeout-per-shutdown-phase: 30s

Expose the Actuator shutdown endpoint:

# Expose shutdown endpoint
management:
  endpoint:
    shutdown:
      enabled: true
  endpoints:
    web:
      exposure:
        include: shutdown

Calling http://localhost:8080/actuator/shutdown returns:

{
  "message": "Shutting down, bye..."
}

Docker Graceful Shutdown Demo

Build a simple Node.js app, containerize it, and run two versions:

# Dockerfile
FROM node:14-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD [ "node", "app.js" ]
// app.js
const express = require('express');
const app = express();
app.get('/hello', (req, res) => {
  res.send('Hello, I am app');
});
app.listen(3000, () => {
  console.log('App listening on port 3000');
});

Build and run version 1, then version 2, and stop the old container with docker stop app-1. The container must handle SIGTERM, e.g.:

// SIGTERM handler in Node.js
function termHandler() {
  console.log('Cleaning up...');
  process.exit(0);
}
process.on('SIGTERM', termHandler);

Advantages and Challenges

Benefits include minimized service interruption, data loss avoidance, improved user experience, simplified deployment, and better maintainability.

Challenges involve increased system complexity, more elaborate deployment pipelines, potential data consistency issues, and higher skill requirements for teams.

Conclusion

Graceful startup and shutdown are essential for reliable microservice operations. By leveraging service registries (Polaris, Spring Cloud), API gateways, Docker signals, and proper health‑check handling, teams can reduce downtime, protect in‑flight requests, and deliver a smoother user experience, while being aware of the added operational complexity.

Summary illustration
Summary illustration
Dockerservice discoverySpring CloudGraceful Shutdown
Tencent Cloud Middleware
Written by

Tencent Cloud Middleware

Official account of Tencent Cloud Middleware. Focuses on microservices, messaging middleware and other cloud‑native technology trends, publishing product updates, case studies, and technical insights. Regularly hosts tech salons to share effective solutions.

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.