首页 / Spring Boot 入门教程 / 健康检查与指标

Spring Boot 入门教程

健康检查与指标

本教程共 48 篇 · 第 37 篇 · 更新于 2026-08-13 · 约 5 分钟阅读

Spring Boot健康检查Micrometer指标PrometheusHealthIndicator探针

本节目标:看懂 health 端点,会写自定义健康指示器,掌握 Micrometer 指标埋点,并把指标接到 Prometheus。

health 端点:应用活着吗

/actuator/health 返回整体状态:

{"status": "UP"}

状态有四级:UP(正常)、DOWN(挂了)、OUT_OF_SERVICE(主动下线)、UNKNOWN(未知)。

默认只显示总状态。想看细节:

management:
  endpoint:
    health:
      show-details: when-authorized

show-details 三档:never(默认)、when-authorized(登录可见)、always

Warning

新手常在这里栽跟头:配置了 show-details: always,调用却看不到 details。如果应用套了 Spring Security,health 端点默认是匿名可访问的,但 always 会暴露内部细节,建议用 when-authorized

健康指示器

health 的状态是多个「健康指示器」汇总的结果。Spring Boot 自动配置了一批,按需启用:

Key检查内容
db数据源能否拿到连接
diskspace磁盘空间是否充足
ping总是 UP,验证探活链路
redisRedis 是否可连
mongoMongoDB 是否可连
mail邮件服务器
sslSSL 证书是否快过期

汇总规则:所有指示器里最差的等级就是整体状态。排序由 StatusAggregator 决定,默认顺序 DOWN 最严重。HTTP 状态码也跟着映射:DOWNOUT_OF_SERVICE 返回 503,UP 返回 200。想自定义映射:

management:
  endpoint:
    health:
      status:
        http-mapping:
          down: 503
          out-of-service: 503

自定义指示器:实现 HealthIndicator 接口。注意 Spring Boot 4 的包名:

package com.example.demo.health;

import org.springframework.boot.health.contributor.Health;
import org.springframework.boot.health.contributor.HealthIndicator;
import org.springframework.stereotype.Component;

@Component
public class DiskHealthIndicator implements HealthIndicator {

    @Override
    public Health health() {
        long free = checkFreeSpace();
        if (free < 1024L * 1024 * 1024) {
            return Health.down().withDetail("freeBytes", free).build();
        }
        return Health.up().withDetail("freeBytes", free).build();
    }

    private long checkFreeSpace() {
        return 8L * 1024 * 1024 * 1024; // 示例:实际用 File 检查
    }
}

Bean 名去掉 HealthIndicator 后缀就是它在响应里的 key:disk

Note

版本对照:Boot 3.x 的 org.springframework.boot.actuate.health.Health 在 4.x 移到了 org.springframework.boot.health.contributor 包。旧 import 会编译报错。

Tip

健康检查要在超时前返回。Spring Boot 会给超过 10 秒的指示器打警告日志,阈值可用 management.endpoint.health.logging.slow-indicator-threshold 调整。

健康组与 Kubernetes 探针

健康指示器可以分组。比如「只看数据库」:

management:
  endpoint:
    health:
      group:
        db-only:
          include: "db"

访问 /actuator/health/db-only 只看这组。健康组默认继承全局的 show-details 和角色配置,也可以单独覆盖,比如 management.endpoint.health.group.db-only.show-details=always

Kubernetes 部署时,探针直接映射到两个内置健康组:

  • /actuator/health/liveness:存活探针
  • /actuator/health/readiness:就绪探针
management:
  endpoint:
    health:
      probes:
        add-additional-paths: true

加上这行后,主端口额外暴露 /livez/readyz,K8s 探针直接指过去。

liveness 探针别挂外部依赖检查:数据库挂了不该重启应用,该摘流量的是 readiness。这是 K8s 探针设计的核心原则,面试常问。

Micrometer 指标

指标是数字化的健康。Spring Boot 用 Micrometer 收集,统一门面,可对接十几个监控系统。

先看有哪些指标:

curl http://localhost:8080/actuator/metrics

内置指标按前缀分:

  • jvm.*:内存、GC、线程、类加载
  • system.* / process.*:CPU、文件描述符、运行时长
  • http.server.requests:HTTP 请求数、耗时、状态码分布

下钻查询:

curl "http://localhost:8080/actuator/metrics/jvm.memory.used?tag=area:heap"
Note

查询用的名字要和代码里的指标名一致。jvm.memory.used 在 Prometheus 里显示为 jvm_memory_used(下划线命名),但查 actuator 时仍写点号。

自定义指标

注入 MeterRegistry,业务代码里埋点。三种基本计量:

  • Counter:只增不减,适合计数
  • Timer:记录耗时分布,适合接口耗时
  • Gauge:可增可减的当前值,适合队列长度
package com.example.demo.service;

import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.stereotype.Service;

@Service
public class OrderService {

    private final Counter orderCounter;

    public OrderService(MeterRegistry registry) {
        this.orderCounter = registry.counter("shop.orders.created", "channel", "web");
    }

    public void createOrder() {
        // 业务逻辑
        orderCounter.increment();
    }
}

registry.counter("名字", "标签名", "标签值") 创建计数器。指标名用点分段,标签用 tag=KEY:VALUE 下钻。

接口耗时用 Timer

Timer orderTimer = registry.timer("shop.order.processing");
orderTimer.record(() -> {
    // 业务逻辑
});

Timer 自带耗时分布统计,接 Prometheus 后能算 P95、P99。队列长度这类当前值用 Gauge

Tip

全局公共标签(环境、机房)用配置统一加:management.metrics.tags.region=cn-east-1,所有指标自动带上。
埋点注意标签基数:用户 ID、订单号这类高基数标签会撑爆指标系统,别往指标里塞。

对接 Prometheus

Prometheus 是拉模式的监控系统。三步对接:

  1. 加依赖:
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
  1. 暴露端点:
management:
  endpoints:
    web:
      exposure:
        include: "health,prometheus"
  1. Prometheus 配置抓取任务:
scrape_configs:
  - job_name: "spring-boot-app"
    metrics_path: "/actuator/prometheus"
    static_configs:
      - targets: ["localhost:8080"]

Prometheus 定期来抓 /actuator/prometheus,拿到 jvm_*http_server_requests_* 等指标,配上 Grafana 就能画监控大盘。

Note

加了 micrometer-registry-prometheus 后,/actuator/prometheus 端点才存在,别忘记在 exposure 里放行。
想关掉某个指标,用 management.metrics.enable.<前缀>=false。想给特定接口算 P99,用 management.metrics.distribution.percentiles-histogram.http.server.requests=true

从指标到告警

指标接进 Prometheus 只是第一步,配上告警才有意义。

Prometheus 的告警规则文件里写条件,比如「5 分钟内错误率超过 5%」:

groups:
  - name: spring-boot-app
    rules:
      - alert: HighErrorRate
        expr: rate(http_server_requests_seconds_count{status="500"}[5m]) > 0.05
        for: 5m
        labels:
          severity: page

告警触发后,Alertmanager 负责通知:邮件、钉钉、企业微信都行。

落地建议:先盯三个基础指标——错误率、P95 耗时、线程与连接池使用率。指标多了看不过来,告警疲劳比没告警更可怕。告警规则先设宽松再收紧:刚开始太频繁,大家会习惯性忽略,真出事反而没人响应。

初学者常栽的坑

  • show-details 配了 always,监控系统能看,黑客也能看
  • 健康检查里查数据库,数据库抖动导致整个应用被判 DOWN
  • 指标名随手写,没有前缀规范,后期排查靠猜
  • 埋了 Counter 但从不看,指标成了摆设
  • 忘了暴露 prometheus 端点,抓取 404 还以为是 Prometheus 的问题
  • 健康组 include 写错名字:Spring Boot 默认校验组成员存在性,启动直接失败,可用 management.endpoint.health.validate-group-membership=false 关掉校验

本节小结

  • health 汇总各健康指示器,show-details 控制细节可见性
  • 自定义健康检查实现 HealthIndicator(4.x 新包名)
  • K8s 探针用 liveness/readiness 健康组,add-additional-paths 暴露 /livez/readyz
  • Micrometer 统一指标,Counter/Timer/Gauge 三种基本计量
  • Prometheus 对接 = 依赖 + 暴露端点 + scrape 配置