Spring Boot健康检查全解析

🌟 一、什么是"健康信息"(Health Information)?

在生产环境中,我们需要知道一个应用是否"活着"且"正常工作"。

Spring Boot 提供了一个内置的 健康检查机制 ------ /actuator/health 接口。

当你访问:

复制代码
http://localhost:8080/actuator/health

你会看到类似这样的返回:

json 复制代码
{
  "status": "UP",
  "components": {
    "db": { "status": "UP" },
    "diskSpace": { "status": "UP" }
  }
}

这个接口就是用来告诉监控系统:"我是不是挂了?"、"数据库连得上吗?"、"磁盘够不够?"等等。


🔐 二、如何控制谁能看到健康详情?(show-details)

你可以通过配置决定:谁能看到详细的健康信息。

配置值 含义
never 谁都看不到细节(默认)→ 只显示 "status": "UP"
when-authorized 只有授权用户(如管理员)能看到细节
always 所有人都能看到细节(包括未登录用户)

示例配置(在 application.yml 中):

yaml 复制代码
management:
  endpoint:
    health:
      show-details: always

⚠️ 注意:如果你设置了 always,但你的安全框架(如 Spring Security)禁止了未登录用户访问 /health,那还是看不到!

授权角色控制:

yaml 复制代码
management:
  endpoint:
    health:
      roles: ADMIN, OPERATOR

表示只有拥有 ADMIN 或 OPERATOR 角色的用户才能看详情(当 show-details=when-authorized 时)。


🧩 三、健康检查是怎么组成的?(HealthContributor)

Spring Boot 的健康检查是一个 树状结构,由多个"健康贡献者"组成。

两种类型的 HealthContributor:

类型 作用
HealthIndicator 单个组件的健康检查(如数据库、磁盘)
CompositeHealthContributor 包含多个子检查的组合(比如把 DB + Redis 组合成一个组)
示例:
  • db → 是一个 HealthIndicator
  • redis → 是一个 HealthIndicator
  • customGroup → 是一个 CompositeHealthContributor,包含 db 和 redis

📊 四、整体状态怎么算出来的?(StatusAggregator)

最终显示的 status(如 UP/DOWN)是怎么定的?

Spring Boot 会根据所有 HealthIndicator 返回的状态,按优先级排序,取最严重的那个。

默认状态优先级(从高到低):

复制代码
DOWN > OUT_OF_SERVICE > UNKNOWN > UP
举个例子:
组件 状态
数据库 DOWN
磁盘 UP
Redis UNKNOWN

👉 最终整体状态是:DOWN

你也可以自定义优先级顺序:

yaml 复制代码
management:
  endpoint:
    health:
      status:
        order: fatal,down,out-of-service,unknown,up

🧰 五、Spring Boot 自动配置了哪些健康检查?

Spring Boot 会根据你项目的依赖,自动启用一些健康检查。

Key(键) 检查什么 条件
db 数据库连接 有 DataSource
redis Redis 服务 引入了 spring-boot-starter-data-redis
mongo MongoDB 引入了 spring-boot-starter-data-mongodb
elasticsearch ES 集群 有 ES 客户端
diskSpace 磁盘空间 默认开启
ping 心跳 总是 UP,用于测试接口是否通

✅ 你可以关闭某个检查:

yaml 复制代码
management:
  health:
    db:
      enabled: false

🚫 关闭所有默认检查:

yaml 复制代码
management:
  health:
    defaults:
      enabled: false

✅ 六、如何自定义健康检查?

你可以写自己的健康检查逻辑,比如检查某个第三方 API 是否可用。

示例:自定义 MyHealthIndicator

java 复制代码
@Component
public class MyHealthIndicator implements HealthIndicator {

    @Override
    public Health health() {
        int errorCode = checkApi(); // 自定义检查逻辑
        if (errorCode != 0) {
            return Health.down()
                       .withDetail("Error Code", errorCode)
                       .build();
        }
        return Health.up().build();
    }

    private int checkApi() {
        // 比如调用一个外部服务
        return 0; // 0 表示正常
    }
}

✅ 效果:

访问 /actuator/health 会多出一项:

json 复制代码
"my": {
  "status": "UP"
}

注意:my 是因为类名是 MyHealthIndicator,去掉 HealthIndicator 后小写首字母得到。


🌈 七、支持自定义状态吗?

可以!比如你想加一个 FATAL 状态。

步骤:

  1. 在 health() 中返回 Health.status("FATAL")
  2. 配置状态优先级:
yaml 复制代码
management:
  endpoint:
    health:
      status:
        order: fatal,down,out-of-service,unknown,up

📡 八、HTTP 状态码映射

健康接口的 HTTP 返回码也会根据状态变化:

状态 默认 HTTP 状态码
DOWN 503 Service Unavailable
OUT_OF_SERVICE 503
UP 200 OK
UNKNOWN 200 OK

你也可以自定义映射:

yaml 复制代码
management:
  endpoint:
    health:
      status:
        http-mapping:
          down: 503
          fatal: 500
          out-of-service: 500

⚡ 九、响应式应用(Reactive)支持

如果你用的是 WebFlux(非阻塞式),Spring Boot 也支持 异步健康检查。

使用 ReactiveHealthIndicator:

java 复制代码
@Component
public class MyReactiveHealthIndicator implements ReactiveHealthIndicator {
    @Override
    public Mono<Health> health() {
        return checkAsync()
            .map(up -> Health.up().build())
            .onErrorReturn(Health.down().build());
    }
}

✅ 优势:不会阻塞线程,适合高并发场景。


🧩 十、健康分组(Health Groups)------ 最实用的功能!

你可以把不同的健康检查分组管理,用于不同场景。

场景举例:

  • 运维只关心数据库和磁盘 → operations 组
  • K8s 探针只关心是否存活 → liveness 组
  • 流量网关关心是否准备好接收请求 → readiness 组

示例:创建一个只包含数据库的组

yaml 复制代码
management:
  endpoint:
    health:
      group:
        custom:
          include: db
          show-details: always

👉 访问:/actuator/health/custom → 只显示数据库状态

更复杂的组:

yaml 复制代码
management:
  endpoint:
    health:
      group:
        liveness:
          include: livenessstate
          show-details: never
        readiness:
          include: readinessstate
          exclude: db  # 准备就绪时,不检查数据库?
        operations:
          include: db,redis,diskSpace
          roles: OPERATOR
          status:
            http-mapping:
              down: 503

✅ 这样就可以实现:

  • /health/liveness → K8s 的 livenessProbe
  • /health/readiness → K8s 的 readinessProbe

🎯 总结:核心要点一览

问题 答案
健康检查是干嘛的? 检查应用是否正常运行,供监控系统使用
在哪看? GET /actuator/health
谁能看到详情? 通过 show-details 和 roles 控制
整体状态怎么定? 取所有组件中最严重的状态(DOWN > UP)
有哪些内置检查? db, redis, mongo, diskSpace, ping 等
能自定义吗? 能!实现 HealthIndicator 接口
支持异步吗? 支持!用 ReactiveHealthIndicator
能分组吗? 能!用 management.endpoint.health.group.xxx

💡 实际应用场景

场景 配置建议
K8s 健康探针 使用 liveness 和 readiness 分组
生产环境监控 show-details=when-authorized,限制权限
节省资源 关闭不需要的健康检查(如不用 Redis 就关掉)
快速排错 自定义健康检查,检查关键外部服务

如果你正在开发微服务或准备上 Kubernetes,熟练掌握 Spring Boot Actuator 的健康检查机制是非常重要的。

需要我给你一个完整的 application.yml 示例,展示如何配置健康分组用于 K8s 吗?

相关推荐
金銀銅鐵2 小时前
为什么枚举类中可以定义抽象方法
java·后端·ai编程
陈随易2 小时前
Vue 编译器换掉 source map,快了三四成
前端·后端·程序员
文丑颜不良啊3 小时前
LeetCode1941~1960题目解析
java·leetcode
txxzjmzlh4 小时前
SpringBoot 统⼀功能处理
java·spring boot·后端
nice_lcj5205 小时前
Java Lambda 表达式入门:怎么写、怎么用、常用方法有哪些
java·开发语言·后端·面试
码农小河666 小时前
基于SSM+JSP+MySQL的在线医疗服务系统的设计与实现
java·开发语言·mysql
IT_陈寒6 小时前
Redis大key删除为什么会导致服务卡顿?我的线上事故复盘
前端·人工智能·后端
系统集成-鹰翔6 小时前
ERP图片改名后仍命中识别缓存:缓存键、十分钟到期与调用计数
javascript·经验分享·后端
用户8356290780516 小时前
使用 Python 在 Excel 中添加和自定义迷你图
后端·python
码事漫谈7 小时前
给AI看一颗❤️,它就开始写递归了
后端