Spring Boot与K8s集成的核心机制
🌟 一、核心目标:让 Spring Boot 应用“懂”Kubernetes
Kubernetes(K8s)是一个容器编排系统。它需要知道:
- 这个应用是否还活着? → 用 Liveness Probe
- 这个应用是否准备好接收流量? → 用 Readiness Probe
- (可选)这个应用启动是否完成? → 用 Startup Probe
Spring Boot Actuator 现在 原生支持这些探针,无需你手动写 /health/liveness 接口。
🔌 二、Spring Boot 是怎么做的?(自动集成)
✅ Spring Boot 自动做了三件事:
| 功能 | 实现方式 |
|---|---|
| 1. 管理应用的“可用性状态” | 内置 ApplicationAvailability 接口 |
| 2. 提供 Liveness 检查 | LivenessStateHealthIndicator |
| 3. 提供 Readiness 检查 | ReadinessStateHealthIndicator |
这两个健康检查会自动出现在:
/actuator/health
同时,还会单独暴露为两个独立端点:
| 探针 | 对应端点 |
|---|---|
| Liveness Probe | /actuator/health/liveness |
| Readiness Probe | `/actuator/health/readiness`` |
✅ 这两个端点其实是 Health Group(健康分组),我们在上一节讲过。
📡 三、K8s 配置示例:如何使用这些探针?
你只需要在 deployment.yaml 中这样配置:
spec:containers:- name: myappports:- containerPort: 8080livenessProbe:httpGet:path: /actuator/health/livenessport: 8080initialDelaySeconds: 30periodSeconds: 10failureThreshold: 3readinessProbe:httpGet:path: /actuator/health/readinessport: 8080initialDelaySeconds: 10periodSeconds: 5failureThreshold: 1
K8s 的 kubelet 会定期调用这些接口,并根据返回结果采取行动。
🧩 四、两个探针的区别:Liveness vs Readiness
这是最关键的部分!
| 对比项 | Liveness Probe(存活探针) | Readiness Probe(就绪探针) |
|---|---|---|
| 目的 | 检查应用是否“卡死” | 检查应用是否“准备好”处理请求 |
| 失败后果 | 重启容器 ⚠️ | 停止转发流量,但不重启 |
| 何时失败 | 应用启动太慢、死锁、OOM | 正在初始化、数据库未连上 |
| 能否自定义 | ✅ 可配置 | ✅ 可配置 |
| 建议检查什么 | 只检查应用内部状态(不要查外部服务!) | 可选择性检查外部依赖(需谨慎) |
⚠️ 五、关键原则:Liveness 探针不要检查外部系统!
❌ 错误做法:
management:endpoint:health:group:liveness:include: db,redis,livenessState
如果数据库挂了,所有实例的 Liveness 都失败 → K8s 会重启所有实例 → 导致雪崩式重启!
✅ 正确做法:
management:endpoint:health:group:liveness:include: livenessState # 只检查内部状态
✅ Liveness 只关心:Spring 容器是否启动成功、线程是否卡死、内存是否溢出。
✅ 六、Readiness 探针:可以检查外部依赖,但要小心
场景分析:
| 外部依赖类型 | 是否该加入 Readiness? | 说明 |
|---|---|---|
| 数据库(共享) | ❌ 不推荐 | 所有实例共用,一旦挂掉,所有实例都 unready → 整个服务下线 |
| 缓存(如 Redis) | ❌ 不推荐 | 同上,可能造成服务整体不可用 |
| 某个本地文件/端口 | ✅ 推荐 | 只影响当前实例,比如文件锁、端口占用 |
| 有降级机制的服务 | ✅ 可以不加 | 比如用了 Hystrix 断路器,即使依赖挂了也能返回默认值 |
示例配置:
management:endpoint:health:group:readiness:include: readinessState,diskspaceexclude: db,redis
✅ 这样即使数据库暂时连不上,只要应用本身启动了,K8s 仍可转发流量,由应用内部处理降级。
🔄 七、应用生命周期与探针状态的对应关系
Spring Boot 会根据应用的启动和关闭过程,自动更新 Liveness 和 Readiness 状态。
🚀 应用启动过程:
| 阶段 | Liveness State | Readiness State | 含义 |
|---|---|---|---|
| 1. Starting(刚开始启动) | BROKEN | REFUSING_TRAFFIC | K8s 可能会重启(如果超时) |
| 2. Started(上下文加载完成) | CORRECT | REFUSING_TRAFFIC | 应用在做初始化任务,不接流量 |
| 3. Ready(准备就绪) | CORRECT | ACCEPTING_TRAFFIC | 可以接收外部请求了 ✅ |
✅ 这意味着:即使 Spring 容器启动了,但你的
@PostConstruct或异步任务还没完成,K8s 也不会把流量打过来!
🛑 应用关闭过程:
| 阶段 | Liveness State | Readiness State | 含义 |
|---|---|---|---|
| 1. Running | LIVE | READY | 正常运行 |
| 2. Graceful Shutdown(优雅关闭) | LIVE | UNREADY | 停止接收新请求,但处理完正在执行的 |
| 3. Shutdown Complete | BROKEN | UNREADY | 容器即将退出 |
✅ 这样可以实现零停机部署(Rolling Update)!
🧪 八、Startup Probe:解决启动慢的问题
有时候应用启动要几分钟(比如加载大缓存、预热模型),而 Liveness 探针默认 30 秒就超时 → 会被误杀。
解决方案:使用 startupProbe
startupProbe:httpGet:path: /actuator/health/livenessport: 8080failureThreshold: 60 # 最多等待 60 次periodSeconds: 10 # 每 10 秒检查一次 → 最多等 10 分钟timeoutSeconds: 5
✅ 一旦 startupProbe 成功,K8s 就会启用 livenessProbe 和 readinessProbe。
⚠️ 九、重要提醒:Actuator 在独立管理端口时的问题
如果你配置了:
management:server:port: 8081
那么 /actuator/health/readiness 是在 8081 端口,而主应用在 8080。
⚠️ 问题:8081 健康 ≠ 8080 健康!
可能主应用(8080)已经卡死,但 Actuator(8081)还能响应 → K8s 认为它“健康”,继续转发流量 → 请求失败。
✅ 建议:
- 不要用独立管理端口,除非你有特殊安全需求。
- 或者,确保
/actuator/health/readiness的检查能反映主应用的真实状态。
🧩 十、如何自定义 Readiness 检查?
你可以把自定义的健康检查加入 Readiness 组:
management:endpoint:health:group:readiness:include: readinessState,customCheck,diskspace
然后写一个 CustomCheckHealthIndicator:
@Component
public class CustomCheckHealthIndicator implements HealthIndicator {@Overridepublic Health health() {if (isCustomSystemReady()) {return Health.up().build();} else {return Health.outOfService().build();}}
}
📊 总结:一张表看懂核心概念
| 概念 | 作用 | 是否重启 | 建议检查内容 |
|---|---|---|---|
| Liveness Probe | 应用是否“卡死” | ✅ 会重启 | 只检查内部状态(如内存、线程) |
| Readiness Probe | 是否准备好接流量 | ❌ 不重启 | 可检查本地资源(磁盘、端口),慎查共享外部服务 |
| Startup Probe | 启动是否完成 | ✅ 会重启 | 用于启动时间长的应用 |
💡 实际建议
-
开启这两个探针:
management:endpoint:health:probes:enabled: true -
K8s 配置中使用
/actuator/health/liveness和/actuator/health/readiness -
不要让 Liveness 依赖数据库、Redis 等外部服务
-
利用 Readiness 实现优雅上下线
-
长启动应用一定要配
startupProbe
这套机制是 Spring Boot 迈向 云原生(Cloud Native) 的重要一步,让你的应用真正“感知生命周期”,而不仅仅是一个黑盒容器。
如果你需要,我可以给你一个完整的 application.yml + deployment.yaml 示例,展示如何在生产环境中配置这些探针。
