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 示例,展示如何在生产环境中配置这些探针。

相关推荐
superlls4 小时前
(场景题)Java 导出 Excel 的两种方式
java·开发语言·后端·excel
RationalDysaniaer4 小时前
k8s配置与存储
云原生·容器·kubernetes
绝无仅有4 小时前
某银行大厂面试技术问题深度解析(一)
后端·面试·github
程序新视界4 小时前
一张图解析MySQL中InnoDB的逻辑存储结构
数据库·后端·mysql
Victor3564 小时前
Redis(88)Redis缓存的大小如何合理配置?
后端
Victor3564 小时前
Redis(89)Redis的安全机制有哪些?
后端
绝无仅有4 小时前
面试自述:从单体到微服务的实践之路
后端·面试·github
XXX-X-XXJ5 小时前
Django 用户认证流程详解:从原理到实现
数据库·后端·python·django·sqlite
胡桃姓胡,蝴蝶也姓胡9 小时前
Rag优化 - 如何提升首字响应速度
后端·大模型·rag