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 中这样配置:

yaml 复制代码
spec:
  containers:
    - name: myapp
      ports:
        - containerPort: 8080
      livenessProbe:
        httpGet:
          path: /actuator/health/liveness
          port: 8080
        initialDelaySeconds: 30
        periodSeconds: 10
        failureThreshold: 3

      readinessProbe:
        httpGet:
          path: /actuator/health/readiness
          port: 8080
        initialDelaySeconds: 10
        periodSeconds: 5
        failureThreshold: 1

K8s 的 kubelet 会定期调用这些接口,并根据返回结果采取行动。


🧩 四、两个探针的区别:Liveness vs Readiness

这是最关键的部分!

对比项 Liveness Probe(存活探针) Readiness Probe(就绪探针)
目的 检查应用是否"卡死" 检查应用是否"准备好"处理请求
失败后果 重启容器 ⚠️ 停止转发流量,但不重启
何时失败 应用启动太慢、死锁、OOM 正在初始化、数据库未连上
能否自定义 ✅ 可配置 ✅ 可配置
建议检查什么 只检查应用内部状态(不要查外部服务!) 可选择性检查外部依赖(需谨慎)

⚠️ 五、关键原则:Liveness 探针不要检查外部系统!

❌ 错误做法:

yaml 复制代码
management:
  endpoint:
    health:
      group:
        liveness:
          include: db,redis,livenessState

如果数据库挂了,所有实例的 Liveness 都失败 → K8s 会重启所有实例 → 导致雪崩式重启

✅ 正确做法:

yaml 复制代码
management:
  endpoint:
    health:
      group:
        liveness:
          include: livenessState  # 只检查内部状态

✅ Liveness 只关心:Spring 容器是否启动成功、线程是否卡死、内存是否溢出。


✅ 六、Readiness 探针:可以检查外部依赖,但要小心

场景分析:

外部依赖类型 是否该加入 Readiness? 说明
数据库(共享) ❌ 不推荐 所有实例共用,一旦挂掉,所有实例都 unready → 整个服务下线
缓存(如 Redis) ❌ 不推荐 同上,可能造成服务整体不可用
某个本地文件/端口 ✅ 推荐 只影响当前实例,比如文件锁、端口占用
有降级机制的服务 ✅ 可以不加 比如用了 Hystrix 断路器,即使依赖挂了也能返回默认值

示例配置:

yaml 复制代码
management:
  endpoint:
    health:
      group:
        readiness:
          include: readinessState,diskspace
          exclude: 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

yaml 复制代码
startupProbe:
  httpGet:
    path: /actuator/health/liveness
    port: 8080
  failureThreshold: 60  # 最多等待 60 次
  periodSeconds: 10     # 每 10 秒检查一次 → 最多等 10 分钟
  timeoutSeconds: 5

✅ 一旦 startupProbe 成功,K8s 就会启用 livenessProbereadinessProbe


⚠️ 九、重要提醒:Actuator 在独立管理端口时的问题

如果你配置了:

yaml 复制代码
management:
  server:
    port: 8081

那么 /actuator/health/readiness 是在 8081 端口,而主应用在 8080。

⚠️ 问题:8081 健康 ≠ 8080 健康!

可能主应用(8080)已经卡死,但 Actuator(8081)还能响应 → K8s 认为它"健康",继续转发流量 → 请求失败。

✅ 建议:

  • 不要用独立管理端口,除非你有特殊安全需求。
  • 或者,确保 /actuator/health/readiness 的检查能反映主应用的真实状态。

🧩 十、如何自定义 Readiness 检查?

你可以把自定义的健康检查加入 Readiness 组:

yaml 复制代码
management:
  endpoint:
    health:
      group:
        readiness:
          include: readinessState,customCheck,diskspace

然后写一个 CustomCheckHealthIndicator

java 复制代码
@Component
public class CustomCheckHealthIndicator implements HealthIndicator {
    @Override
    public Health health() {
        if (isCustomSystemReady()) {
            return Health.up().build();
        } else {
            return Health.outOfService().build();
        }
    }
}

📊 总结:一张表看懂核心概念

概念 作用 是否重启 建议检查内容
Liveness Probe 应用是否"卡死" ✅ 会重启 只检查内部状态(如内存、线程)
Readiness Probe 是否准备好接流量 ❌ 不重启 可检查本地资源(磁盘、端口),慎查共享外部服务
Startup Probe 启动是否完成 ✅ 会重启 用于启动时间长的应用

💡 实际建议

  1. 开启这两个探针

    yaml 复制代码
    management:
      endpoint:
        health:
          probes:
            enabled: true
  2. K8s 配置中使用 /actuator/health/liveness/actuator/health/readiness

  3. 不要让 Liveness 依赖数据库、Redis 等外部服务

  4. 利用 Readiness 实现优雅上下线

  5. 长启动应用一定要配 startupProbe


这套机制是 Spring Boot 迈向 云原生(Cloud Native) 的重要一步,让你的应用真正"感知生命周期",而不仅仅是一个黑盒容器。

如果你需要,我可以给你一个完整的 application.yml + deployment.yaml 示例,展示如何在生产环境中配置这些探针。

相关推荐
编织幻境的妖13 分钟前
Docker和Kubernetes 常用命令
docker·容器·kubernetes
在人间负债^1 小时前
Rust 实战项目:TODO 管理器
开发语言·后端·rust
Moonbit1 小时前
入围名单公布|2025 MGPIC 决赛即将拉开帷幕!
后端·算法
爱吃烤鸡翅的酸菜鱼1 小时前
用【rust】实现命令行音乐播放器
开发语言·后端·rust
黛琳ghz1 小时前
用 Rust 从零构建高性能文件加密工具
开发语言·后端·rust
悟世君子1 小时前
Rust 开发环境搭建
开发语言·后端·rust
OlahOlah1 小时前
Go 入门实战:音乐专辑管理 API
后端
黛琳ghz1 小时前
用 Rust 打造高性能 PNG 压缩服务
开发语言·后端·rust
回家路上绕了弯2 小时前
订单超时自动取消:从业务场景到技术落地的完整设计方案
分布式·后端
shengjk12 小时前
一张图 + 五条时间线,彻底拆透 StarRocks 主键表 UPSERT 链路
后端