第25课:Spring Cloud监控体系详解 & Actuator端点全解

文章目录

适配版本 :Spring Boot 4.0.8、Spring Cloud 2025.1.3(Oakwood)、Micrometer 2.x、JDK 21

课程定位:监控追踪阶段开篇,从可观测性概念到Actuator端点全解,建立微服务监控的认知框架

一、开篇:从"出问题再查"到"提前发现问题"

第21-24课我们完成了Sentinel熔断限流容错体系的全部建设。Sentinel解决的是**"出问题时怎么办"** ------熔断、降级、限流,让系统在故障时优雅降级而非直接崩溃。

但还有一个更根本的问题没有回答:如何知道系统即将出问题?

假设你的微服务集群运行着20个服务实例。某个实例的内存使用率正在缓慢上升,从60%涨到75%用了3天,再过半天就会触发OOM导致服务崩溃。如果没有监控,你只能在服务崩溃后收到告警,然后开始排查日志。如果有了监控,你可以在内存使用率超过80%时提前收到告警,在服务崩溃前扩容或重启实例,用户对此毫无感知。

这就是可观测性(Observability) 的价值。可观测性由三大支柱构成:指标(Metrics) 告诉你"系统当前状态如何",链路追踪(Tracing) 告诉你"一个请求经过了哪些服务、每段耗时多少",日志(Logging) 告诉你"系统在某个时刻发生了什么"。

Spring Boot Actuator是可观测性的基础设施。它提供了开箱即用的端点(Endpoints),暴露应用的运行状态、健康检查、指标数据、环境配置等信息。第26课的Prometheus+Grafana、第27课的SkyWalking、第28课的ELK,都建立在Actuator和Micrometer的基础之上。

本课将从Actuator的端点体系讲起,深入健康检查机制和探针配置,剖析Micrometer的指标采集原理,实战自定义端点开发,最后给出生产安全配置和2025版适配要点。

二、Actuator端点体系全解

2.1 什么是Actuator端点

Actuator是Spring Boot提供的生产就绪特性(Production-ready Features) 模块,通过HTTP或JMX暴露应用内部的运行时信息。每个端点(Endpoint)是一个命名的功能单元,通过id标识,HTTP暴露时默认映射到/actuator/{id}路径。

Actuator的核心设计原则是 "默认安全" :默认只暴露/health和/info两个端点,其余端点需要显式配置才会暴露。这是为了避免生产环境中意外泄露敏感信息(如环境变量、配置属性、堆转储)。

2.2 核心内置端点清单

Spring Boot 4.0的Actuator内置端点按功能分为以下几类:

类别 端点ID 默认暴露 核心用途
健康检查 health ✅ HTTP 应用健康状态,支持liveness/readiness探针
应用信息 info ✅ HTTP 应用元数据(版本、构建时间、Git信息)
指标 metrics ❌ 需显式开启 所有Micrometer指标的列表和详情
Prometheus prometheus ❌ 需显式开启 Prometheus文本格式的指标流
环境 env ❌ 环境变量和配置属性
Bean beans ❌ 容器中所有Bean的定义和依赖关系
配置属性 configprops ❌ @ConfigurationProperties的绑定值
日志 loggers ❌ 动态修改日志级别
映射 mappings ❌ 所有@RequestMapping路径
线程 threaddump ❌ JVM线程转储
堆 heapdump ❌ JVM堆转储(生产环境应禁用)
关闭 shutdown ❌ 优雅关闭应用(生产环境应禁用)
网关 gateway ❌ Gateway路由信息(需Gateway依赖)

生产环境的暴露原则 :最小暴露,按需开启 。生产环境只暴露health、info、metrics、prometheus四个端点,其余端点通过management.endpoints.web.exposure.include显式指定,或通过management.endpoint.<id>.enabled=false单独禁用高危端点(heapdump、env、shutdown)。

2.3 端点配置

YAML配置方式:

yaml 复制代码
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus   # 只暴露这4个端点
        exclude: env,beans,heapdump,shutdown        # 排除高危端点
  endpoint:
    health:
      show-details: when-authorized                 # 健康详情仅授权用户可见
    prometheus:
      enabled: true
    metrics:
      enabled: true
    env:
      enabled: false                                 # 显式禁用到env端点
    heapdump:
      enabled: false
    shutdown:
      enabled: false

三、健康检查机制与探针配置

3.1 健康检查的语义分层

Spring Boot 4.0的健康检查将健康状态分为三个语义层次,这是理解健康检查的关键:

Liveness(存活) :进程是否活着。只回答"JVM是否还在运行"这个问题。如果liveness探针失败,K8s会重启Pod。注意:liveness不应该检查外部依赖(如数据库),否则数据库短暂不可用会导致Pod被反复重启,形成重启风暴。

Readiness(就绪) :应用是否能接收流量。检查关键依赖(数据库、Redis、下游服务)是否可用。如果readiness探针失败,K8s会将Pod从Service的端点列表中移除,摘除流量但不重启Pod。

Dependency Health(依赖健康) :每个外部依赖的详细健康状态。MySQL、Redis、Elasticsearch等组件的连接状态。

核心实践原则 :liveness和readiness必须分开配置。只看PID存在与否,等于把"进程卡死"和"依赖不可用"两类故障混在一起,导致错误的处理策略。

3.2 健康组配置

Spring Boot 4.0支持通过健康组(Health Groups)将不同的健康指标组合到不同的探针中:

yaml 复制代码
management:
  endpoint:
    health:
      probes:
        add-additional-paths: true      # 在根路径暴露 /livez 和 /readyz
      group:
        liveness:
          include: livenessState        # 只包含应用存活状态
        readiness:
          include: readinessState,db    # 包含就绪状态 + 数据库
          show-details: always

配置效果:

路径 含义 失败后果
/actuator/health/liveness 存活探针 K8s重启Pod
/actuator/health/readiness 就绪探针 K8s摘除流量
/livez 存活探针(根路径) 同上(add-additional-paths=true时)
/readyz 就绪探针(根路径) 同上(add-additional-paths=true时)

add-additional-paths=true的作用是在根路径暴露/livez和/readyz,这是K8s编排器期望的常规路径。原有的/actuator/health/liveness路径仍然保留,新路径是追加的,不是替换的。

3.3 自定义健康指示器

当需要检查外部服务(如第三方API、自定义缓存)的健康状态时,实现HealthIndicator接口:

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

    @Autowired
    private ThirdPartyApiClient apiClient;

    @Override
    public Health health() {
        try {
            boolean available = apiClient.ping();
            if (available) {
                return Health.up()
                        .withDetail("endpoint", apiClient.getEndpoint())
                        .withDetail("latency", apiClient.getLastLatency() + "ms")
                        .build();
            }
            return Health.down()
                    .withDetail("reason", "API returned non-OK status")
                    .build();
        } catch (Exception e) {
            return Health.down(e)
                    .withDetail("endpoint", apiClient.getEndpoint())
                    .build();
        }
    }
}

自定义健康指示器会自动注册到/actuator/health的响应中,键名为thirdPartyApi(去掉HealthIndicator后缀、驼峰转小写)。

踩坑提示 :HealthIndicator的实现不应抛出异常 。如果health()方法抛出异常,Spring Boot会捕获并将其转换为DOWN状态,但不会包含异常详情。应该像上面的代码一样,捕获异常并返回带有详情的Health.down()。

3.4 健康检查的性能考量

健康检查端点会被K8s频繁调用 (liveness每10秒、readiness每5秒是常见的配置)。因此健康检查的实现必须轻量且快速。

反模式 :在HealthIndicator中执行复杂的数据库查询或HTTP调用,导致健康检查端点本身成为性能瓶颈。

正确做法:

  • 使用连接池的isValid()方法检查数据库连接,而非执行SELECT 1
  • 对于外部HTTP依赖,使用缓存的健康状态(每30秒刷新一次),而非每次健康检查都发起真实请求
  • 为健康检查设置独立的超时时间(如2秒),避免因依赖服务超时导致健康检查阻塞
yaml 复制代码
management:
  health:
    redis:
      enabled: true
    db:
      enabled: true
    diskspace:
      enabled: true
      threshold: 100MB

四、指标采集与Micrometer集成

4.1 Micrometer:指标采集的门面

Spring Boot Actuator的指标采集基于Micrometer 。Micrometer是一个指标门面 ,类似于SLF4J之于日志------它提供了一套统一的API,底层可以对接不同的监控系统(Prometheus、Datadog、CloudWatch等)。引入micrometer-registry-prometheus后,Actuator会自动将指标以Prometheus格式暴露在/actuator/prometheus端点。

4.2 Spring Boot 4.0的模块化变更

Spring Boot 4.0对可观测性模块进行了模块化重构,这是升级时最容易踩坑的地方:

旧依赖 新依赖
spring-boot-starter-actuator(包含所有) spring-boot-starter-actuator(仅核心)
--- spring-boot-micrometer-metrics(指标模块)
--- spring-boot-micrometer-tracing(追踪模块)
spring-boot-starter-actuator + micrometer-tracing-bridge-brave spring-boot-starter-actuator + spring-boot-micrometer-tracing-brave

关键变化 :追踪相关的模块被拆分,spring-boot-micrometer-tracing是基础模块,需要配合具体的桥接实现(Brave或OpenTelemetry)。

xml 复制代码
<!-- Spring Boot 4.0 的可观测性依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-micrometer-metrics</artifactId>
</dependency>
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

4.3 核心指标清单

启用Actuator和Prometheus注册表后,以下指标自动可用:

指标类别 指标名 含义
JVM内存 jvm.memory.used 各内存池使用量
JVM GC jvm.gc.pause GC停顿时间和次数
JVM线程 jvm.threads.live 存活线程数
HTTP请求 http.server.requests 每个端点的请求数、耗时、状态码
CPU system.cpu.usage 系统CPU使用率
进程 process.cpu.usage 进程CPU使用率
数据库 hikaricp.connections.active 连接池活跃连接数
负载均衡 spring.cloud.loadbalancer.requests.active 各服务的活跃请求数

4.4 自定义指标

通过MeterRegistry注册自定义业务指标:

java 复制代码
@Service
public class OrderMetricsService {

    private final Counter orderCreatedCounter;
    private final Timer orderProcessTimer;

    public OrderMetricsService(MeterRegistry registry) {
        // 计数器:订单创建总数,按状态标记
        this.orderCreatedCounter = Counter.builder("order.created.total")
                .description("Total orders created")
                .tag("status", "pending")
                .register(registry);

        // 计时器:订单处理耗时
        this.orderProcessTimer = Timer.builder("order.process.duration")
                .description("Order processing duration")
                .publishPercentiles(0.5, 0.95, 0.99)
                .register(registry);
    }

    public void recordOrderCreated(String status) {
        orderCreatedCounter.increment();
    }

    public <T> T recordProcessTime(Supplier<T> operation) {
        return orderProcessTimer.record(operation);
    }
}

4.5 2025版可观测性新特性

Spring Boot 4.0将可观测性从"可选增强"升级为运行时核心契约 ,首次将JVM Agent集成深度内置于启动生命周期中。应用启动时,Spring Boot自动检测并加载兼容的Java Agent(如Micrometer Registry Agent或OpenTelemetry Java Agent),通过字节码增强实现零侵入的指标采集。

Agent-Ready的核心变化 :旧版本需要手动添加-javaagent参数,Spring Boot 4.0由spring-boot-loader自动发现并初始化Agent。启用方式:

yaml 复制代码
spring:
  instrumentation:
    opentelemetry:
      enabled: true
      resource:
        attributes:
          service.name: "order-service"
          environment: "prod"

同时,Spring Boot 4.0新增了/actuator/agent/status端点,实时暴露已激活的Agent列表、插桩覆盖率和性能开销统计。

五、自定义端点开发实战

5.1 @Endpoint注解开发

通过@Endpoint、@ReadOperation、@WriteOperation等注解定义自定义端点:

java 复制代码
@Component
@Endpoint(id = "release")
public class ReleaseEndpoint {

    @Autowired
    private ReleaseInfoProvider releaseInfoProvider;

    @ReadOperation
    public ReleaseInfo release() {
        return releaseInfoProvider.getCurrentRelease();
    }

    @ReadOperation
    public ReleaseInfo releaseForVersion(@Selector String version) {
        return releaseInfoProvider.getRelease(version);
    }

    @WriteOperation
    public void updateRelease(@Selector String version) {
        releaseInfoProvider.setCurrentRelease(version);
    }

    @DeleteOperation
    public void clearRelease(@Selector String version) {
        releaseInfoProvider.clearRelease(version);
    }
}

注解语义:

注解 HTTP方法 用途
@ReadOperation GET 读取数据
@WriteOperation POST 写入数据
@DeleteOperation DELETE 删除数据
@Selector 路径变量 从URL路径中提取参数

访问方式 :/actuator/release、/actuator/release/{version}。

5.2 端点安全:RequestMatcher

自定义端点默认受Actuator的安全配置保护。如果需要为特定端点配置独立的安全策略,使用EndpointRequest:

java 复制代码
@Configuration
public class ActuatorSecurityConfig {

    @Bean
    public SecurityFilterChain actuatorSecurityFilterChain(HttpSecurity http) throws Exception {
        http.securityMatcher(EndpointRequest.toAnyEndpoint())
            .authorizeHttpRequests(auth -> auth
                .requestMatchers(EndpointRequest.to("health", "info")).permitAll()
                .requestMatchers(EndpointRequest.to("release")).hasRole("ACTUATOR_ADMIN")
                .anyRequest().authenticated()
            );
        return http.build();
    }
}

注意 :EndpointRequest.toAnyEndpoint()匹配所有Actuator端点,包括/actuator根路径。EndpointRequest.to("health", "info")只匹配指定的端点。

六、生产安全配置

6.1 2026年Actuator安全漏洞警示

2026年披露了两个与Actuator相关的安全漏洞,必须引起重视:

CVE-2026-22731 :Actuator健康组(Health Groups)的"附加路径"映射逻辑存在缺陷。当通过additional-path配置了健康组路径时,可能绕过身份认证直接访问健康端点。修复版本:Spring Boot 4.0.3、3.5.11、3.4.15或更高版本。

CVE-2026-40976 :当应用是Servlet-based、依赖spring-boot-actuator-autoconfigure但不依赖spring-boot-health 时,默认安全过滤链可能缺少授权规则,允许未授权访问所有端点。修复版本:Spring Boot 4.0.6或更高版本。

Spring Cloud Commons的CVE-2026-59284:writable env actuator endpoint缺少allow list,Spring Cloud 2025.1.3已修复此漏洞。

行动建议:确保Spring Boot版本不低于4.0.8,Spring Cloud版本为2025.1.3;在防火墙或网络ACL层面限制管理端点的访问来源;显式配置安全规则,不依赖默认行为。

6.2 独立管理端口

将Actuator端点暴露在独立端口上,与业务流量隔离:

yaml 复制代码
management:
  server:
    port: 8081    # Actuator 独立端口,仅内网可访问
  endpoints:
    web:
      base-path: /manage   # 修改基础路径

优势 :业务端口(如8080)不暴露Actuator端点,降低攻击面。防火墙只需放行8081端口的内网访问,公网完全不可达。

6.3 高危端点的处理

以下端点在生产环境中必须禁用,除非有明确的业务需求:

端点 风险 处理方式
heapdump 下载堆转储可获取内存中的敏感数据(密码、Token) management.endpoint.heapdump.enabled=false
env 暴露所有环境变量和配置属性 management.endpoint.env.enabled=false
shutdown 远程关闭应用 management.endpoint.shutdown.enabled=false
threaddump 线程转储可能包含敏感信息 仅在排查时临时开启

6.4 健康检查的安全配置

健康检查端点虽然默认暴露,但健康详情 (show-details)应限制为授权用户可见:

yaml 复制代码
management:
  endpoint:
    health:
      show-details: when-authorized   # 仅授权用户可见详情
      roles: ACTUATOR_ADMIN            # 需要该角色

未授权用户访问时,/actuator/health只返回{"status":"UP"},不包含数据库、Redis等依赖的详细状态。

七、踩坑指南

坑一:健康检查导致Pod重启风暴

现象:数据库短暂不可用后,K8s反复重启Pod,服务完全不可用。

原因:liveness探针包含了数据库健康检查。数据库不可用时,liveness失败,K8s重启Pod;Pod重启后数据库仍然不可用,再次重启,形成循环。

解决 :liveness只检查livenessState,不包含任何外部依赖。数据库、Redis等依赖放入readiness探针。

坑二:Actuator端点参数使用了错误的空安全注解

现象:升级到Spring Boot 4.0后,自定义端点的可选参数报编译错误。

原因 :Spring Boot 4.0移除了javax.annotations.NonNull和org.springframework.lang.Nullable在Actuator端点参数上的支持。必须使用@OptionalParameter或org.jspecify.annotations.Nullable。

解决 :将端点参数注解迁移到@OptionalParameter或JSpecify的@Nullable。

坑三:Micrometer Tracing依赖缺失导致Trace ID不显示

现象:升级到Spring Boot 4.0后,日志中不再显示Trace ID和Span ID。

原因:Spring Boot 4.0将追踪模块拆分,需要显式添加桥接依赖:

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-micrometer-tracing-brave</artifactId>
</dependency>

解决 :添加spring-boot-micrometer-tracing-brave或spring-boot-micrometer-tracing-opentelemetry依赖。

坑四:Prometheus端点暴露了敏感标签

现象 :Prometheus指标中包含uri标签,暴露了内部API路径。

原因 :http.server.requests指标默认包含请求URI。如果URI中包含敏感参数(如/api/user/{id}中的id实际值),可能泄露信息。

解决:配置指标标签过滤:

yaml 复制代码
management:
  metrics:
    tags:
      application: ${spring.application.name}
  web:
    server:
      request:
        autotime:
          enabled: true

同时确保URI使用路径模板(/api/user/{id}),而非实际值。

坑五:CVE-2026-22731 健康组路径认证绕过

现象 :配置了add-additional-paths=true后,/livez和/readyz路径可能绕过安全认证。

原因:健康组的附加路径映射逻辑存在缺陷。

解决 :升级到Spring Boot 4.0.8(或至少4.0.3+)。同时,如果不需要根路径的/livez和/readyz,不要开启add-additional-paths。

八、课后作业

作业一 :在service-user中引入Actuator依赖,配置只暴露health、info、metrics、prometheus四个端点。访问/actuator/health,确认返回了UP状态。

作业二 :配置liveness和readiness探针。在service-user中实现一个HealthIndicator,检查一个模拟的外部服务。配置readiness组包含该检查,liveness组只包含livenessState。验证:模拟外部服务不可用时,/actuator/health/readiness返回DOWN,而/actuator/health/liveness仍返回UP。

作业三 :实现一个自定义@Endpoint,暴露当前服务的版本信息和启动时间。配置该端点仅ACTUATOR_ADMIN角色可访问。

作业四 :通过MeterRegistry注册一个自定义的Counter,记录某个业务方法的调用次数。访问/actuator/metrics/{your.metric.name},验证指标存在且计数正确。

作业五(进阶) :配置Actuator独立管理端口(8081),验证业务端口8080无法访问Actuator端点。配置show-details: when-authorized,验证未授权用户只能看到{"status":"UP"}。

九、下节预告

第26课将进入Prometheus+Grafana指标监控大盘搭建。我们将从Prometheus的指标采集原理讲起,完成Prometheus部署、指标暴露、Grafana可视化大盘搭建,配置CPU/内存/QPS/延迟监控和告警规则。本课完成了Actuator的端点体系和指标采集基础,第26课将把这些指标真正"用起来"------采集、存储、可视化、告警。Actuator是数据源,Prometheus是采集器,Grafana是展示层,三者构成指标监控的完整链路。

🔗《最新版 SpringCloud 2025 从入门到实战》系列课程导航

去订阅

第一部分:微服务前置基础 & 新版环境搭建(第1-5课)

第二部分:注册中心核心(Nacos 最新版)(第6-9课)

第三部分:配置中心核心(Nacos配置中心)(第10-12课)

第四部分:服务通信核心(OpenFeign + LoadBalancer)(第13-16课)

第五部分:网关核心(SpringCloud Gateway 新版)(第17-20课)

第六部分:熔断、限流、降级(Sentinel 新版)(第21-24课)

第七部分:微服务监控、链路追踪、日志体系(第25-28课)

第八部分:微服务高阶特性 & 分布式核心能力(第29-31课)

第九部分:企业级完整项目实战 & 架构复盘(第32-35课)

相关推荐
今年下半年3 小时前
【Spring Cloud】Spring Cloud Gateway 防 XSS / 防 CSRF 实现
spring cloud·xss·csrf
Wang's Blog5 小时前
Java 项目实战: 交友项目 - SpringCloud 整合 Dubbo 的需求分析与模块规划
java·spring cloud·交友
流烟默6 小时前
Spring Cloud 微服务 Sentinel 热点参数与授权规则集成指南(附架构建议)
spring cloud·微服务·架构·sentinel
EAIReport8 小时前
SpringBoot 与 SpringCloud 深度解析:核心特点、差异与协同关系
spring boot·后端·spring cloud
Wang's Blog9 小时前
Java 项目实战: 交友项目 - SpringCloud 整合 Dubbo 的方案概述
java·spring cloud·交友
Thomas.Sir1 天前
第23课:Sentinel熔断降级、系统自适应保护、集群限流
spring cloud·sentinel
2501_933923252 天前
SpringCloud组件:Eureka服务注册与发现
java·开发语言·后端·spring cloud·eureka
叶总没有会2 天前
Gateway--网关
spring cloud·微服务·gateway
海马3 天前
Spring Cloud 开发知识整理
spring·spring cloud·wpf