🌟 一、什么是"健康信息"(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→ 是一个HealthIndicatorredis→ 是一个HealthIndicatorcustomGroup→ 是一个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 状态。
步骤:
- 在
health()中返回Health.status("FATAL") - 配置状态优先级:
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 吗?