
本文旨在解决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为了确保部署的应用的健壮性和高可用性,引入了两种核心探针:存活性探针(Liveness Probe)和就绪性探针(Readiness Probe)。
存活性探针 (Liveness Probe)
就绪性探针 (Readiness Probe)
从日志中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”状态。
在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次后认为不存活为了让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应用内部的就绪性判断逻辑,例如,当所有数据库连接池都初始化完毕后才报告为“就绪”,可以自定义健康指示器。
Spring Boot应用在Kubernetes中启动后立即关闭,通常是由于Kubernetes的就绪性探针在应用尚未完全初始化时过早检查所致。通过在Kubernetes部署配置中为readinessProbe和livenessProbe设置合理的initialDelaySeconds,可以为应用提供充足的启动时间。结合Spring Boot Actuator的健康端点,确保应用能够正确响应Kubernetes的健康检查,是保障应用在云原生环境中稳定运行的关键。正确配置这些探针,不仅能解决启动问题,还能提升应用的韧性和用户体验。
以上就是Spring Boot应用在Kubernetes环境中启动后立即关闭的诊断与解决的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号