Why kill -9 Can Crash Your Spring Boot Service and How to Shut It Down Gracefully
This article explains the dangers of using the Linux kill -9 command on Java services, especially Spring Boot applications, and demonstrates several graceful shutdown techniques—including using SIGTERM, Tomcat's shutdown hooks, Spring Actuator, and custom shutdown configurations—to avoid data loss and ensure clean termination.
kill -9 pid ???
The kill command sends a signal to a process; by default it sends SIGTERM (15) to terminate the process. If the process does not stop, SIGKILL (9) can be used to force termination. Process IDs can be obtained with ps or jobs.
Although kill -9 pid reliably kills a Linux process, using it in a production project can cause serious problems.
Problems Caused by kill -9 pid
Because kill -9 is a violent termination, it can lead to data inconsistency. For example, in a money transfer scenario using MyISAM tables, a sudden termination may deduct money from account A without crediting account B, resulting in unrecoverable loss. Even with InnoDB, abrupt termination can break distributed transactions.
Therefore, kill -9 should not be used to stop services; instead, use graceful shutdown methods.
Graceful Service Shutdown
kill -15 pid
Sending SIGTERM (15) allows the application to shut down gracefully. The article demonstrates a Spring Boot controller that sleeps for 100 seconds and shows that after sending kill -15, the InterruptedException is caught, the thread is interrupted, and the method can still complete.
@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";
}Running the application, obtaining its PID, and sending kill -15 <pid> results in the following log:
2020-04-24 10:53:14.939 INFO 14086 --- [nio-9988-exec-1] com.ymy.controller.TestController : test --- start
2020-04-24 10:54:02.450 INFO 14086 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
...
2020-04-24 10:54:04.574 INFO 14086 --- [nio-9988-exec-1] com.ymy.controller.TestController : test --- endThe interruption triggers an exception but the method still finishes, illustrating a graceful shutdown.
ConfigurableApplicationContext close
package com.ymy.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
public class TestController implements ApplicationContextAware {
private ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.context = applicationContext;
}
@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";
}
@PostMapping(value = "shutdown")
public void shutdown() {
ConfigurableApplicationContext ctx = (ConfigurableApplicationContext) context;
ctx.close();
}
}Calling ctx.close() removes the JVM shutdown hook and stops the Spring Boot application.
Spring Boot Actuator
Adding the Actuator dependency provides a /shutdown endpoint that can be exposed securely.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency> server:
port: 9988
management:
endpoints:
web:
exposure:
include: shutdown
endpoint:
shutdown:
enabled: trueInvoking the shutdown endpoint stops the service, similar to the previous methods, and the thread’s interrupt causes a sleep exception.
ElegantShutdownConfig (Custom Tomcat Graceful Shutdown)
package com.ymy.config;
import org.apache.catalina.connector.Connector;
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextClosedEvent;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ElegantShutdownConfig implements TomcatConnectorCustomizer, ApplicationListener<ContextClosedEvent> {
private volatile Connector connector;
private final int waitTime = 10; // seconds
@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) {
try {
ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executor;
threadPoolExecutor.shutdown();
if (!threadPoolExecutor.awaitTermination(waitTime, TimeUnit.SECONDS)) {
System.out.println("Please try force shutdown");
}
} catch (InterruptedException ex) {
System.out.println("Exception occurred");
Thread.currentThread().interrupt();
}
}
}
}The configuration pauses Tomcat, waits for active requests to finish, and then shuts down.
Data Backup on Shutdown
To perform backup or other cleanup before the container stops, add a method annotated with @PreDestroy:
package com.ymy.config;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PreDestroy;
@Configuration
public class DataBackupConfig {
@PreDestroy
public void backData() {
System.out.println("Backing up data…");
}
}This method runs automatically during graceful shutdown.
Overall, the article demonstrates why kill -9 is unsafe for Java services and provides multiple graceful shutdown strategies for Spring Boot applications, including signal handling, Actuator, custom Tomcat shutdown, and pre‑destroy hooks for data backup.
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.
MaGe Linux Operations
Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.
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.
