Backend Development 19 min read

Graceful Shutdown of Spring Boot Services and the Risks of Using kill -9

The article explains how the Linux kill command, especially kill -9, can abruptly terminate processes causing data inconsistency, and demonstrates safer alternatives for stopping Spring Boot applications—including kill -15, the built‑in shutdown script, Actuator endpoints, custom Tomcat connector shutdown, and @PreDestroy backup hooks—providing complete code examples.

Architecture Digest
Architecture Digest
Architecture Digest
Graceful Shutdown of Spring Boot Services and the Risks of Using kill -9

kill sends signals to processes; the default SIGTERM (15) terminates gracefully, while SIGKILL (9) forces immediate termination. Using kill -9 on services such as a Spring Boot application can cause data loss similar to a sudden power outage, especially with non‑transactional storage engines.

Examples illustrate how a transaction on MyISAM can become inconsistent when a process is killed, and why distributed systems must avoid abrupt termination.

For a more graceful stop, kill -15 can be used. The article provides a simple controller that sleeps for 100 seconds and shows that sending kill -15 to the process interrupts the thread, causing an InterruptedException but still allowing cleanup.

@GetMapping(value = "/test")
public String test() {
    log.info("test --- start");
    try {
        Thread.sleep(100000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    log.info("test --- end");
    return "test";
}

Spring Boot also offers built‑in shutdown scripts (shutdown.sh/shutdown.bat) and the Actuator shutdown endpoint, which can be enabled in application.yml and invoked via HTTP.

server:
  port: 9988
management:
  endpoints:
    web:
      exposure:
        include: shutdown
  endpoint:
    shutdown:
      enabled: true

For advanced control, the article introduces an ElegantShutdownConfig that customizes the Tomcat connector, pauses new requests, and waits up to a configurable timeout before forcing termination.

public class ElegantShutdownConfig implements TomcatConnectorCustomizer, ApplicationListener
{
    private volatile Connector connector;
    private final int waitTime = 10;
    @Override
    public void customize(Connector connector) { this.connector = connector; }
    @Override
    public void onApplicationEvent(ContextClosedEvent event) {
        connector.pause();
        Executor executor = connector.getProtocolHandler().getExecutor();
        if (executor instanceof ThreadPoolExecutor) {
            ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executor;
            threadPoolExecutor.shutdown();
            if (!threadPoolExecutor.awaitTermination(waitTime, TimeUnit.SECONDS)) {
                System.out.println("Please try forceful shutdown");
            }
        }
    }
}

Finally, the article shows how to execute backup logic during shutdown using the @PreDestroy annotation in a Spring bean.

@Configuration
public class DataBackupConfig {
    @PreDestroy
    public void backData() {
        System.out.println("Backing up data...");
    }
}

These techniques together provide a safe, graceful way to stop Spring Boot services without risking data corruption.

Javabackend developmentSpring BootGraceful ShutdownLinux Signals
Architecture Digest
Written by

Architecture Digest

Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.

0 followers
Reader feedback

How this landed with the community

login 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.