SpringBootK8s启动崩溃排查方法
时间:2025-11-13 18:12:36 347浏览 收藏
在Kubernetes环境中部署Spring Boot应用时,遇到启动后立即崩溃的问题?本文深入解析了这一常见难题的根源:Kubernetes的就绪性探针(Readiness Probe)过早地判断应用为“未就绪”,导致应用被终止。通过详细分析应用日志,揭示了应用启动过程中的关键信息,并提出了有效的解决方案:为就绪性探针和存活性探针配置`initialDelaySeconds`参数,为Spring Boot应用提供充足的启动时间,确保应用在完全初始化后才接受流量。此外,文章还提供了Kubernetes配置示例和Spring Boot应用内配置建议,助您轻松解决启动问题,提升应用的稳定性和用户体验。

本文旨在解决Spring Boot应用在Kubernetes环境中启动后立即关闭的问题。核心原因在于Kubernetes的就绪性探针(Readiness Probe)在应用尚未完全初始化并准备好接受流量时,过早地判断应用为“未就绪”并触发终止。通过配置就绪性探针和存活性探针的`initialDelaySeconds`参数,为应用提供足够的启动时间,可以有效解决此问题,确保应用稳定运行。
在将Spring Boot应用部署到Kubernetes集群时,开发者可能会遇到应用在容器启动后立即终止的现象。尽管应用在本地开发环境或非Kubernetes的开发环境中运行良好,但在生产预发布(PP)等更严格的Kubernetes环境中,却出现启动后迅速关闭的问题。通过分析应用日志,我们通常会发现以下关键信息:
2022-11-30 13:11:12.110 INFO 1 --- [ main] c.a.f.MyApplication : Started MyApplication in 96.297 seconds (JVM running for 104.706) 2022-11-30 13:11:12.513 INFO 1 --- [ionShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default' ... Application availability state ReadinessState changed to REFUSING_TRAFFIC
日志显示应用似乎成功启动("Started MyApplication..."),但紧接着出现了Application availability state ReadinessState changed to REFUSING_TRAFFIC,并且触发了关闭事件("Closing JPA EntityManagerFactory...","HikariPool-1 - Shutdown initiated...")。这表明应用在启动后不久就被外部机制判定为不可用并被终止。
理解Kubernetes的探针机制
Kubernetes为了确保部署的应用的健壮性和高可用性,引入了两种核心探针:存活性探针(Liveness Probe)和就绪性探针(Readiness Probe)。
存活性探针 (Liveness Probe)
- 作用: 用于检测容器内的应用是否正在运行。如果存活性探针失败,Kubernetes会认为该容器已死亡,并根据重启策略重启容器。
- 目的: 捕获应用死锁(例如,应用进程仍在运行但无法处理请求)的情况,通过重启来恢复服务。
就绪性探针 (Readiness Probe)
- 作用: 用于检测容器内的应用是否已准备好接收流量。如果就绪性探针失败,Kubernetes会从Service的Endpoint列表中移除该Pod的IP地址,停止向其发送流量。当探针成功时,Pod会被重新加入Endpoint列表。
- 目的: 确保流量只发送给完全初始化并能够响应请求的应用实例,避免在应用启动过程中或处理复杂初始化任务时将请求发送给未准备好的实例。
问题根源:就绪性探针的过早判断
从日志中ReadinessState changed to REFUSING_TRAFFIC这一行可以看出,问题在于Kubernetes的就绪性探针过早地对应用进行了健康检查。Spring Boot应用,尤其是包含数据库初始化(如Flyway)和JPA实体管理器加载等复杂逻辑的应用,启动过程可能需要较长时间。在此期间,尽管JVM已经启动,但应用可能尚未完全完成所有依赖注入、数据库连接池初始化或业务逻辑层的准备。
如果Kubernetes的就绪性探针在应用完全准备好之前就开始检查,并且应用尚未能响应探针请求(例如/actuator/health/readiness),或者其内部状态仍处于“REFUSING_TRAFFIC”,Kubernetes就会误判应用为“未就绪”。根据Kubernetes的默认行为,如果一个Pod长时间处于非就绪状态,或者其存活性探针失败,可能会导致Pod被终止并重新创建,从而陷入无限重启的循环。
解决方案:配置探针的初始延迟
为了解决这个问题,我们需要为Kubernetes的就绪性探针和存活性探针配置一个初始延迟时间(initialDelaySeconds)。这个参数告诉Kubernetes在容器启动后,等待指定秒数后再开始执行探针检查。这为Spring Boot应用提供了足够的时间来完成其启动和初始化过程,确保在探针开始检查时,应用已经处于可接受流量的“ACCEPTING_TRAFFIC”状态。
1. Kubernetes配置示例 (Kustomization或Deployment YAML)
在Kubernetes的部署配置中,可以通过在readinessProbe和livenessProbe下添加initialDelaySeconds来设置延迟。
使用Kustomization文件进行补丁修改:
# kustomization.yml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml # 假设你的Deployment定义在这里
patches:
- target:
kind: Deployment
name: my-app-deployment # 替换为你的Deployment名称
patch: |
- op: replace
path: /spec/template/spec/containers/0/readinessProbe/initialDelaySeconds
value: 60
- op: replace
path: /spec/template/spec/containers/0/livenessProbe/initialDelaySeconds
value: 60直接在Deployment YAML中配置:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-deployment
spec:
replicas: 1
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app-container
image: com.xyz/my-app:0.0.1-SNAPSHOT
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /actuator/health/readiness # Spring Boot Actuator的就绪性端点
port: 8080
initialDelaySeconds: 60 # 容器启动后,等待60秒再开始检查就绪性
periodSeconds: 10 # 每10秒检查一次
timeoutSeconds: 5 # 探针超时时间
failureThreshold: 3 # 失败3次后认为不就绪
livenessProbe:
httpGet:
path: /actuator/health/liveness # Spring Boot Actuator的存活性端点
port: 8080
initialDelaySeconds: 60 # 容器启动后,等待60秒再开始检查存活性
periodSeconds: 10 # 每10秒检查一次
timeoutSeconds: 5 # 探针超时时间
failureThreshold: 3 # 失败3次后认为不存活2. Spring Boot应用内配置 (可选但推荐)
为了让Spring Boot应用能够正确响应Kubernetes的健康检查,需要引入spring-boot-starter-actuator依赖,并在application.yml中配置相应的健康端点。
pom.xml依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>application.yml配置:
management:
endpoint:
health:
show-details: always # 建议在非生产环境开启,方便调试
probes:
enabled: true # 启用LivenessState和ReadinessState
endpoints:
web:
exposure:
include: health # 暴露健康端点如果需要进一步细化Spring Boot应用内部的就绪性判断逻辑,例如,当所有数据库连接池都初始化完毕后才报告为“就绪”,可以自定义健康指示器。
注意事项与最佳实践
- initialDelaySeconds的设置: 这个值应该根据应用的实际启动时间来确定。可以通过本地测试、查看日志中“Started MyApplication in X seconds”的时间,并在此基础上增加一个安全裕度来估算。过短可能导致问题复现,过长则会延长应用部署上线时间。
- periodSeconds、timeoutSeconds和failureThreshold:
- periodSeconds:探针执行的频率。
- timeoutSeconds:探针请求的超时时间。
- failureThreshold:探针连续失败多少次后被判定为失败。 合理配置这些参数可以防止误判,并提高系统的响应性。
- 区分Liveness和Readiness: 存活性探针关注应用是否“活着”,就绪性探针关注应用是否“准备好接收流量”。两者目的不同,通常就绪性探针的条件会比存活性探针更严格。
- 日志监控: 部署后务必密切关注Pod的事件日志和应用容器的详细日志,以便在探针配置不当或应用本身存在其他问题时,能及时发现并进行调整。
- 平滑启动与关闭: 除了探针,还应考虑应用在接收SIGTERM信号时的平滑关闭机制,确保在Pod终止前,所有正在处理的请求都能完成,并释放资源。Spring Boot 2.3+ 默认支持优雅停机。
总结
Spring Boot应用在Kubernetes中启动后立即关闭,通常是由于Kubernetes的就绪性探针在应用尚未完全初始化时过早检查所致。通过在Kubernetes部署配置中为readinessProbe和livenessProbe设置合理的initialDelaySeconds,可以为应用提供充足的启动时间。结合Spring Boot Actuator的健康端点,确保应用能够正确响应Kubernetes的健康检查,是保障应用在云原生环境中稳定运行的关键。正确配置这些探针,不仅能解决启动问题,还能提升应用的韧性和用户体验。
到这里,我们也就讲完了《SpringBootK8s启动崩溃排查方法》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于的知识点!
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
164 收藏
-
341 收藏
-
125 收藏
-
427 收藏
-
152 收藏
-
129 收藏
-
334 收藏
-
431 收藏
-
294 收藏
-
292 收藏
-
183 收藏
-
288 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习