一、核心概念
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
前缀访问,且默认只暴露health
和info
。
二、详细操作步骤
步骤 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.yml
中 info
前缀的属性。
# 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 信息:
- Maven:确保项目根目录有
.git
目录。 - 添加插件(如果未自动包含):
<plugin> <groupId>pl.project13.maven</groupId> <artifactId>git-commit-id-plugin</artifactId> </plugin>
- 执行
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:动态调整日志级别
查看当前级别:
GET http://localhost:8080/actuator/loggers/com.example
{ "configuredLevel": null, "effectiveLevel": "INFO" }
修改日志级别:
POST http://localhost:8080/actuator/loggers/com.example Content-Type: application/json { "configuredLevel": "DEBUG" }
之后
com.example
包下的日志将输出 DEBUG 级别。
步骤 7:集成 Spring Security(生产环境必须!)
强烈建议为 Actuator 端点配置安全认证。
添加 Security 依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
配置安全规则:
// 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); } }
访问受保护端点:
curl -u admin:admin123 http://localhost:8080/actuator/metrics
步骤 8:与 Prometheus + Grafana 集成(推荐监控方案)
Prometheus 配置 (
prometheus.yml
):scrape_configs: - job_name: 'spring-boot-app' metrics_path: '/actuator/prometheus' static_configs: - targets: ['localhost:8080'] # 你的应用地址
启动 Prometheus。
访问 Prometheus Web UI (
http://localhost:9090
),查询指标如http_server_requests_seconds_count
。配置 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 等调整,通常默认足够 |
四、注意事项
- 安全第一:
- 生产环境绝对禁止暴露
env
,beans
,conditions
,shutdown
等敏感端点到公网。 - 必须配置 Spring Security 或其他认证机制(如 API Gateway 认证)。
- 使用最小权限原则(如
show-details: when-authorized
)。
- 生产环境绝对禁止暴露
- 暴露策略:
- 明确列出需要暴露的端点 (
include: health,info
),而不是使用*
。 - 敏感端点仅限内部网络或通过 JMX 访问。
- 明确列出需要暴露的端点 (
- 性能影响:
- 大多数端点(如
health
,metrics
)开销很小。 beans
,env
端点返回数据量大,频繁访问可能影响性能。httptrace
会存储请求历史,占用内存,需配置HttpTraceRepository
(如InMemoryHttpTraceRepository
有大小限制)。
- 大多数端点(如
- 版本兼容性:
- 注意 Spring Boot 1.x 与 2.x Actuator 的巨大差异(路径、配置方式)。
/actuator/health
的UP
不代表应用完全可用:- 它只检查注册的
HealthIndicator
。确保关键依赖(DB, Cache, MQ)都有对应的检查器。
- 它只检查注册的
/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
指标中。
六、最佳实践
- 启用核心端点:
health
,info
,metrics
,loggers
是基础。 - 安全加固:
- 生产环境必须配置认证(Spring Security, OAuth2, API Gateway)。
- 最小化暴露:只暴露必要的端点。
- 网络隔离:将 Actuator 端点放在内网或通过 VPN 访问。
- 集成监控系统:
- Prometheus + Grafana:收集指标并可视化。
- ELK/EFK:结合日志分析。
- 自定义健康检查:为数据库、缓存、消息队列、外部服务等关键依赖编写
HealthIndicator
。 - 自定义业务指标:使用
MeterRegistry
记录关键业务指标(订单量、支付成功率、错误率)。 - 利用
info
端点:填充构建、Git、版本信息,便于运维和排查。 - 动态日志调优:利用
/actuator/loggers
在生产环境临时开启 DEBUG 日志排查问题,完成后立即关闭。 - 优雅关闭:结合
livenessProbe
/readinessProbe
(K8s) 和/actuator/health
实现滚动更新和故障转移。 - 文档化:记录暴露了哪些端点及其用途。
- 定期审计:检查端点暴露情况和安全配置。
七、性能优化
- 减少敏感端点暴露:避免
env
,beans
等大负载端点被频繁调用。 - 合理配置
httptrace
:- 限制存储大小:
@Bean InMemoryHttpTraceRepository traceRepository() { ... setCapacity(100); }
- 仅在需要时启用。
- 限制存储大小:
- 指标采样:
- Micrometer 默认已优化。避免创建过多维度的指标(高基数 Cardinality 问题)。
- 使用
@Timed
时注意extraTags
的值,避免产生过多时间序列。
- 健康检查优化:
- 避免在
HealthIndicator
中执行耗时或阻塞操作。 - 对于非关键依赖,可以配置
@RefreshScope
或缓存检查结果。
- 避免在
- JVM 调优:
- Actuator 本身开销很小。性能瓶颈通常在应用本身。
- 确保 JVM 内存 (
-Xmx
) 和 GC 配置合理。
- 网络与序列化:
/actuator/metrics
返回数据可能较大,确保网络通畅。- 使用高效的 JSON 库(如 Jackson,默认)。
总结
Spring Boot Actuator 是应用监控的基石。
核心步骤:
- 添加依赖:
spring-boot-starter-actuator
(+micrometer-registry-prometheus
)。 - 配置暴露:在
application.yml
中设置management.endpoints.web.exposure.include
。 - 填充信息:配置
info
端点(构建、Git)。 - 自定义检查:实现
HealthIndicator
。 - 记录指标:使用
MeterRegistry
或@Timed
。 - 安全防护:生产环境必须配置 Spring Security!
黄金法则:可观察性 + 安全性 = 可靠的生产应用。Actuator 提供了强大的工具,正确使用它,你的应用将变得透明且易于管理。