一、核心概念

1.1 什么是 Spring Boot Actuator?

  • Actuator(执行器)是 Spring Boot 提供的一个生产就绪功能(Production-ready features)模块。
  • 它通过一系列 HTTP 端点 (Endpoints)JMX 暴露应用的内部运行状态,用于监控、管理和诊断应用。
  • 核心目标是提高应用的可观测性 (Observability)

1.2 为什么需要 Actuator?

在生产环境中,你需要了解应用的:

  • 健康状态(是否存活?数据库连通吗?)
  • 性能指标(CPU、内存、HTTP 请求量、响应时间)
  • 配置信息(当前生效的配置是什么?)
  • 线程状态(是否有死锁?线程堆积?)
  • 环境变量
  • 应用信息(版本、构建信息)
  • 日志级别动态调整

Actuator 提供了标准化的接口来获取这些信息。

1.3 核心术语

术语 说明
Endpoint (端点) 一个可访问的 URL 路径,用于暴露特定的监控信息或执行管理操作。如 /actuator/health
ID 端点的唯一标识符,如 health, info, metrics
Web Exposure 端点通过 HTTP 暴露。
JMX Exposure 端点通过 JMX (Java Management Extensions) 暴露。
Sensitive 旧版本概念,指是否包含敏感信息。新版本通过 角色/权限 控制。
Indicator (指示器) 实现 HealthIndicator 接口的 Bean,用于提供特定组件的健康检查逻辑(如 DiskSpaceHealthIndicator)。

1.4 内置核心端点

端点 ID 路径 (默认) 描述 是否敏感/默认启用
health /actuator/health 应用健康状况汇总(UP/DOWN/OUT_OF_SERVICE)。可包含数据库、磁盘、Redis 等检查。 Web: true, JMX: true
info /actuator/info 应用基本信息(Git 提交、构建时间、版本号等)。 Web: true, JMX: true
metrics /actuator/metrics 应用性能指标(计数器、度量器),如 JVM 内存、HTTP 请求计数、响应时间。 Web: true, JMX: true
env /actuator/env 当前 Spring 环境变量(所有 PropertySource)。 Web: false, JMX: true
configprops /actuator/configprops 所有 @ConfigurationProperties Bean 的配置信息。 Web: false, JMX: true
beans /actuator/beans 应用上下文中的所有 Spring Bean 及其依赖关系。 Web: false, JMX: true
conditions /actuator/conditions 自动配置类的报告(哪些生效了,哪些没生效及原因)。 Web: false, JMX: true
loggers /actuator/loggers 查看和修改应用日志级别。 Web: true, JMX: true
httptrace /actuator/httptrace 最近的 HTTP 请求/响应跟踪(需 HttpTraceRepository)。 Web: false, JMX: true
shutdown /actuator/shutdown 关闭应用(POST 请求)。极其危险!默认禁用 Web: false, JMX: true
prometheus /actuator/prometheus 将指标暴露为 Prometheus 可抓取的格式(需 micrometer-registry-prometheus)。 Web: false, JMX: N/A

注意:从 Spring Boot 2.x 开始,所有端点都通过 /actuator 前缀访问,且默认只暴露 healthinfo


二、详细操作步骤

步骤 1:添加 Actuator 依赖

pom.xml 中添加:

<dependencies>
    <!-- Spring Boot Actuator -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <!-- 如果需要将指标暴露给 Prometheus (推荐用于监控系统) -->
    <dependency>
        <groupId>io.micrometer</groupId>
        <artifactId>micrometer-registry-prometheus</artifactId>
    </dependency>
</dependencies>

步骤 2:基础配置(通过 application.yml

# application.yml
management:
  # 通用配置
  endpoints:
    enabled-by-default: true # 是否启用所有端点的默认状态 (true/false)
  # Web 端点配置
  endpoint:
    health:
      show-details: always # always, when-authorized, never. 显示健康详情
      # show-details: when-authorized # 推荐生产环境使用,需要认证
      roles: "ADMIN" # 需要 ADMIN 角色才能查看详情 (结合 Spring Security)
    info:
      enabled: true # 默认 true
    # 启用 Prometheus 端点 (如果添加了 micrometer-registry-prometheus 依赖)
    prometheus:
      enabled: true
    # 启用 metrics 端点 (默认 true)
    metrics:
      enabled: true
    # 启用 loggers 端点 (默认 true)
    loggers:
      enabled: true
    # 启用 shutdown 端点 (极其危险!默认 false)
    # shutdown:
    #   enabled: true
  # Web 暴露配置
  endpoints:
    web:
      exposure:
        # 指定哪些端点通过 Web 暴露。使用通配符 * 表示全部,或列出具体 ID
        # **生产环境严禁暴露敏感端点!**
        # include: health,info,metrics,loggers,prometheus # 推荐明确列出需要的
        # exclude: env,beans,conditions,shutdown # 明确排除敏感端点
        include: "health,info,metrics,loggers,prometheus" # 常用安全组合
        # exclude: "*"
      # 基础路径,默认 /actuator
      # base-path: /management # 可自定义
      # 路径映射 (可选)
      # path-mapping:
      #   health: healthcheck
  # JMX 暴露配置 (可选)
  # endpoints:
  #   jmx:
  #     exposure:
  #       include: "*"
  #       exclude: shutdown

  # 指标 (Micrometer) 配置
  metrics:
    # 启用特定指标
    enable:
      jvm: true
      logback: true
      # datasource: true # 如果有数据源
    # 指标前缀
    tags:
      application: ${spring.application.name}
      instance: ${spring.application.instance_id:${random.value}}
    # Prometheus 特定配置
    export:
      prometheus:
        enabled: true
        # 需要 micrometer-registry-prometheus
        # 将 /actuator/prometheus 暴露

步骤 3:配置 info 端点信息

/actuator/info 的信息来源于 application.ymlinfo 前缀的属性。

# application.yml
info:
  app:
    name: @project.artifactId@ # Maven 属性占位符
    description: @project.description@
    version: @project.version@
    encoding: @project.build.sourceEncoding@
    java:
      source: @java.version@
      target: @java.version@
  # 构建信息 (需要 Maven/Gradle 插件生成)
  build:
    artifact: @project.artifactId@
    name: @project.name@
    description: @project.description@
    version: @project.version@
  # Git 信息 (需要 spring-boot-starter-git 插件或生成 git.properties)
  git:
    branch: ${git.branch}
    commit:
      id: ${git.commit.id}
      time: ${git.commit.time}

生成 Git 信息

  1. Maven:确保项目根目录有 .git 目录。
  2. 添加插件(如果未自动包含):
    <plugin>
        <groupId>pl.project13.maven</groupId>
        <artifactId>git-commit-id-plugin</artifactId>
    </plugin>
    
  3. 执行 mvn clean package,插件会生成 target/classes/git.properties

步骤 4:自定义健康检查 (HealthIndicator)

// DatabaseHealthIndicator.java
@Component
public class DatabaseHealthIndicator implements HealthIndicator {

    @Autowired
    private DataSource dataSource; // 假设有数据源

    @Override
    public Health health() {
        try (Connection connection = dataSource.getConnection()) {
            // 执行一个简单的查询
            try (PreparedStatement ps = connection.prepareStatement("SELECT 1");
                 ResultSet rs = ps.executeQuery()) {
                if (rs.next()) {
                    return Health.up()
                        .withDetail("database", "MySQL")
                        .withDetail("version", connection.getMetaData().getDatabaseProductVersion())
                        .build();
                }
            }
        } catch (SQLException e) {
            return Health.down(e)
                .withDetail("error", e.getMessage())
                .build();
        }
        return Health.unknown().build(); // 不应该到达这里
    }
}

访问 /actuator/health 将包含类似:

{
  "status": "UP",
  "components": {
    "db": { "status": "UP", "details": { "database": "MySQL", ... } },
    "diskSpace": { "status": "UP", ... },
    // ... 其他内置检查
    "databaseHealthIndicator": { "status": "UP", ... } // 你的自定义检查
  }
}

步骤 5:自定义指标 (MeterRegistry)

// OrderService.java
@Service
public class OrderService {

    private final MeterRegistry meterRegistry;

    public OrderService(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
    }

    public void createOrder(Order order) {
        // 业务逻辑...

        // 计数器 (Counter): 记录订单创建次数
        meterRegistry.counter("order.created.total", "type", order.getType()).increment();

        // 计时器 (Timer): 记录订单创建耗时
        Timer.Sample sample = Timer.start(meterRegistry);
        try {
            // 模拟耗时操作
            Thread.sleep(100);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        sample.stop(Timer.builder("order.creation.duration").register(meterRegistry));

        // 度量器 (Gauge): 记录当前待处理订单数 (假设有一个队列)
        // Gauge 指标通常在注册时提供一个 Supplier
        // Gauge.builder("orders.pending", orderQueue, Queue::size).register(meterRegistry);
    }
}

访问 /actuator/metrics/order.created.total 查看计数。

步骤 6:动态调整日志级别

  1. 查看当前级别

    GET http://localhost:8080/actuator/loggers/com.example
    
    {
      "configuredLevel": null,
      "effectiveLevel": "INFO"
    }
    
  2. 修改日志级别

    POST http://localhost:8080/actuator/loggers/com.example
    Content-Type: application/json
    {
      "configuredLevel": "DEBUG"
    }
    

    之后 com.example 包下的日志将输出 DEBUG 级别。

步骤 7:集成 Spring Security(生产环境必须!)

强烈建议为 Actuator 端点配置安全认证。

  1. 添加 Security 依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    
  2. 配置安全规则

    // SecurityConfig.java
    @Configuration
    @EnableWebSecurity
    public class SecurityConfig {
    
        @Bean
        public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
            http
                .authorizeHttpRequests(authz -> authz
                    .requestMatchers("/actuator/health", "/actuator/info").permitAll() // 允许公开访问
                    .requestMatchers("/actuator/**").hasRole("ADMIN") // 其他 actuator 端点需要 ADMIN 角色
                    .anyRequest().authenticated() // 其他请求需要认证
                )
                .httpBasic(); // 使用 HTTP Basic 认证 (简单示例)
            return http.build();
        }
    
        // 配置内存用户 (仅用于演示)
        @Bean
        public UserDetailsService userDetailsService() {
            UserDetails admin = User.withUsername("admin")
                .password("{noop}admin123") // {noop} 表示不加密,生产环境必须加密!
                .roles("ADMIN")
                .build();
            return new InMemoryUserDetailsManager(admin);
        }
    }
    
  3. 访问受保护端点

    curl -u admin:admin123 http://localhost:8080/actuator/metrics
    

步骤 8:与 Prometheus + Grafana 集成(推荐监控方案)

  1. Prometheus 配置 (prometheus.yml):

    scrape_configs:
      - job_name: 'spring-boot-app'
        metrics_path: '/actuator/prometheus'
        static_configs:
          - targets: ['localhost:8080'] # 你的应用地址
    
  2. 启动 Prometheus

  3. 访问 Prometheus Web UI (http://localhost:9090),查询指标如 http_server_requests_seconds_count

  4. 配置 Grafana

    • 添加 Prometheus 为数据源。
    • 导入 Spring Boot 监控仪表盘(如 ID 12856)。

三、常见错误与解决方案

错误现象 原因分析 解决方案
404 Not Found /actuator/xxx 1. 端点未启用或未通过 Web 暴露
2. 依赖未添加
1. 检查 management.endpoints.web.exposure.include 配置
2. 确认 spring-boot-starter-actuator 已引入
401 Unauthorized / 403 Forbidden 1. 未配置 Security,但端点需要认证
2. 认证信息错误
1. 配置 SecurityFilterChain 允许访问或提供正确凭证
2. 检查用户名密码
/actuator/env 返回 404 默认未通过 Web 暴露 management.endpoints.web.exposure.include 中添加 env
自定义 HealthIndicator 未生效 1. 类未被 @Component 扫描
2. Bean 名称冲突
1. 确保类在组件扫描路径下且有 @Component
2. 检查是否有同名 Bean
Prometheus 抓取失败 1. micrometer-registry-prometheus 依赖缺失
2. management.endpoint.prometheus.enabled=true 未配置
3. Prometheus 配置错误
1. 添加依赖
2. 检查配置
3. 检查 Prometheus targets 配置
内存指标不准确 Micrometer 默认采样频率 可通过 management.metrics.export.prometheus.desired-compactness 等调整,通常默认足够

四、注意事项

  1. 安全第一
    • 生产环境绝对禁止暴露 env, beans, conditions, shutdown 等敏感端点到公网。
    • 必须配置 Spring Security 或其他认证机制(如 API Gateway 认证)。
    • 使用最小权限原则(如 show-details: when-authorized)。
  2. 暴露策略
    • 明确列出需要暴露的端点 (include: health,info),而不是使用 *
    • 敏感端点仅限内部网络或通过 JMX 访问。
  3. 性能影响
    • 大多数端点(如 health, metrics)开销很小。
    • beans, env 端点返回数据量大,频繁访问可能影响性能。
    • httptrace 会存储请求历史,占用内存,需配置 HttpTraceRepository(如 InMemoryHttpTraceRepository 有大小限制)。
  4. 版本兼容性
    • 注意 Spring Boot 1.x 与 2.x Actuator 的巨大差异(路径、配置方式)。
  5. /actuator/healthUP 不代表应用完全可用
    • 它只检查注册的 HealthIndicator。确保关键依赖(DB, Cache, MQ)都有对应的检查器。
  6. /actuator/shutdown
    • 极其危险!默认禁用。如果启用,必须严格保护。

五、使用技巧

5.1 自定义端点 (@Endpoint, @ReadOperation)

@Component
@Endpoint(id = "custom")
public class CustomEndpoint {

    @ReadOperation
    public Map<String, Object> getInfo() {
        Map<String, Object> info = new HashMap<>();
        info.put("timestamp", System.currentTimeMillis());
        info.put("status", "OK");
        return info;
    }

    @WriteOperation
    public String resetCounter(@Selector String name) {
        // 执行重置逻辑
        return "Counter " + name + " reset.";
    }
}

访问 GET /actuator/custom

5.2 使用 @EndpointExtension 扩展内置端点

@Component
@EndpointExtension(filter = HealthEndpoint.class, type = WebEndpointExtension.class)
public class CustomHealthWebExtension {

    @ReadOperation
    public WebEndpointResponse<Health> getHealthWithDetails(@Selector InstanceInfo instanceInfo) {
        // 可以添加额外逻辑
        return new WebEndpointResponse<>(instanceInfo.getHealth());
    }
}

5.3 过滤器中收集 httptrace

// HttpTraceFilter.java
@Component
@Order(-2) // 在 Actuator 的 TraceFilter 之前
public class HttpTraceFilter implements Filter {

    @Autowired
    private HttpExchangeTracer tracer;

    @Autowired
    private HttpTraceRepository repository;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {
            chain.doFilter(request, response);
            return;
        }

        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

        HttpTrace trace = new HttpTrace();
        // 设置请求信息
        trace.setRequest(new HttpTrace.Request(httpRequest.getMethod(), httpRequest.getRequestURI(),
                httpRequest.getProtocol(), httpRequest.getHeaderNames()));
        // ... 设置响应信息

        chain.doFilter(request, response);

        // 保存 trace
        repository.add(trace);
    }
}

5.4 使用 @Timed 注解自动记录方法耗时

@Service
public class BusinessService {

    @Timed(value = "business.operation.duration", extraTags = {"operation", "calculate"})
    public String doBusiness() {
        // 业务逻辑
        return "result";
    }
}

该方法的执行时间会自动记录到 business_operation_duration_seconds 指标中。


六、最佳实践

  1. 启用核心端点health, info, metrics, loggers 是基础。
  2. 安全加固
    • 生产环境必须配置认证(Spring Security, OAuth2, API Gateway)。
    • 最小化暴露:只暴露必要的端点。
    • 网络隔离:将 Actuator 端点放在内网或通过 VPN 访问。
  3. 集成监控系统
    • Prometheus + Grafana:收集指标并可视化。
    • ELK/EFK:结合日志分析。
  4. 自定义健康检查:为数据库、缓存、消息队列、外部服务等关键依赖编写 HealthIndicator
  5. 自定义业务指标:使用 MeterRegistry 记录关键业务指标(订单量、支付成功率、错误率)。
  6. 利用 info 端点:填充构建、Git、版本信息,便于运维和排查。
  7. 动态日志调优:利用 /actuator/loggers 在生产环境临时开启 DEBUG 日志排查问题,完成后立即关闭。
  8. 优雅关闭:结合 livenessProbe/readinessProbe (K8s) 和 /actuator/health 实现滚动更新和故障转移。
  9. 文档化:记录暴露了哪些端点及其用途。
  10. 定期审计:检查端点暴露情况和安全配置。

七、性能优化

  1. 减少敏感端点暴露:避免 env, beans 等大负载端点被频繁调用。
  2. 合理配置 httptrace
    • 限制存储大小:@Bean InMemoryHttpTraceRepository traceRepository() { ... setCapacity(100); }
    • 仅在需要时启用。
  3. 指标采样
    • Micrometer 默认已优化。避免创建过多维度的指标(高基数 Cardinality 问题)。
    • 使用 @Timed 时注意 extraTags 的值,避免产生过多时间序列。
  4. 健康检查优化
    • 避免在 HealthIndicator 中执行耗时或阻塞操作。
    • 对于非关键依赖,可以配置 @RefreshScope 或缓存检查结果。
  5. JVM 调优
    • Actuator 本身开销很小。性能瓶颈通常在应用本身。
    • 确保 JVM 内存 (-Xmx) 和 GC 配置合理。
  6. 网络与序列化
    • /actuator/metrics 返回数据可能较大,确保网络通畅。
    • 使用高效的 JSON 库(如 Jackson,默认)。

总结

Spring Boot Actuator 是应用监控的基石。

核心步骤

  1. 添加依赖spring-boot-starter-actuator (+ micrometer-registry-prometheus)。
  2. 配置暴露:在 application.yml 中设置 management.endpoints.web.exposure.include
  3. 填充信息:配置 info 端点(构建、Git)。
  4. 自定义检查:实现 HealthIndicator
  5. 记录指标:使用 MeterRegistry@Timed
  6. 安全防护生产环境必须配置 Spring Security

黄金法则可观察性 + 安全性 = 可靠的生产应用。Actuator 提供了强大的工具,正确使用它,你的应用将变得透明且易于管理。