您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# SpringBoot如何进行优雅停服
## 引言
在微服务架构中,服务的启停是常态操作。相比于粗暴地直接终止进程(`kill -9`),**优雅停服(Graceful Shutdown)**能确保正在处理的请求正常完成、资源有序释放、注册中心及时下线服务,避免数据不一致和客户端请求失败。本文将深入探讨SpringBoot实现优雅停服的完整方案。
---
## 一、什么是优雅停服?
优雅停服包含三个核心要素:
1. **拒绝新请求**:停止接收新流量
2. **处理存量请求**:等待正在执行的请求完成
3. **释放资源**:关闭数据库连接、线程池等资源
对比强制停服:
| 方式 | 新请求处理 | 进行中请求 | 资源释放 |
|--------------|------------|------------|----------|
| 强制停服 | 立即中断 | 强制终止 | 可能泄漏 |
| 优雅停服 | 拒绝接收 | 等待完成 | 有序释放 |
---
## 二、SpringBoot原生支持方案
### 2.1 启用优雅停服配置
```yaml
# application.yml
server:
shutdown: graceful # 2.3+版本支持
spring:
lifecycle:
timeout-per-shutdown-phase: 30s # 超时时间
SIGTERM
)@PreDestroy
等生命周期回调# 发送停止信号
kill -2 <PID> # 等同于Ctrl+C
# 观察日志输出
...[ThreadPoolTaskExecutor] Shutting down ExecutorService
...[TomcatWebServer] Graceful shutdown complete
@RestController
@RequiredArgsConstructor
public class GracefulShutdownEndpoint {
private final ConfigurableApplicationContext context;
@PostMapping("/graceful-shutdown")
public String shutdown() {
new Thread(() -> {
try {
Thread.sleep(1000); // 等待端点响应
context.close(); // 触发优雅停机
} catch (Exception e) {
Thread.currentThread().interrupt();
}
}).start();
return "Shutdown initiated";
}
}
@EventListener(ContextClosedEvent.class)
public void onShutdown(ContextClosedEvent event) {
// 1. 先标记服务为OUT_OF_SERVICE
discoveryClient.setStatus(InstanceStatus.OUT_OF_SERVICE);
// 2. 等待负载均衡刷新
Thread.sleep(30000);
// 3. 正式注销(通过preStop钩子实现更佳)
discoveryClient.shutdown();
}
@Bean(destroyMethod = "shutdown")
public ExecutorService taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setAwaitTerminationSeconds(60);
return executor.getThreadPoolExecutor();
}
# deployment.yaml
spec:
template:
spec:
containers:
- name: app
lifecycle:
preStop:
exec:
command:
- "curl"
- "-XPOST"
- "http://localhost:8080/graceful-shutdown"
terminationGracePeriodSeconds: 60 # 等待时间
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 20
periodSeconds: 5
Thread interrupted
异常现象:超过配置的timeout仍未停止
解决方案:
- 使用jstack
检查线程阻塞情况
- 检查是否有非守护线程未结束
现象:服务实例仍可被调用
解决方案:
- 确认preStop钩子执行成功
- 检查服务心跳超时配置
实现真正的优雅停服需要: 1. 合理配置超时时间 2. 全链路状态管理 3. 完善的测试验证
SpringBoot提供的机制结合Kubernetes等平台能力,可以构建出生产级可用的优雅停服方案。建议将此纳入服务健康度的基础评估指标。
参考文档:
- Spring Boot Graceful Shutdown
- Kubernetes Termination Process “`
这篇文章包含: 1. 理论说明 + 实践代码 2. 多种环境方案(普通部署/K8s) 3. 表格对比和流程图(需补充) 4. 完整的实施链路 5. 问题排查指引
可根据需要补充具体案例或性能数据。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。