在微服务架构盛行的当下,系统健康状态的可观测性已成为工程实践的刚需。SpringBoot Actuator 作为 Spring 生态中的监控利器,其价值远不止于简单的"健康检查"——它实际上为开发者提供了一套完整的应用自省(Introspection)机制。我曾在一个日活百万级的电商系统中深度使用 Actuator,仅通过合理配置端点就快速定位了三次线上事故的根因。
Actuator 的核心优势在于其"非侵入式"的设计理念。它通过自动装配(Auto-Configuration)机制将监控能力注入应用,开发者几乎不需要修改业务代码即可获得:
这种设计特别适合需要快速迭代的互联网项目。去年我们团队接手的一个遗留系统,就是通过 Actuator 的 /heapdump 端点发现了一个隐藏多年的内存泄漏问题——某个缓存组件在并发场景下会持续增长却从不释放。
Actuator 的端点(Endpoint)分为两类:
/health, /metrics)@Endpoint 注解扩展在 application.yml 中的典型配置如下:
yaml复制management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
base-path: /internal-monitor
endpoint:
health:
show-details: always
prometheus:
enabled: true
关键配置解析:
base-path 建议修改默认值 /actuator 以提高安全性show-details 控制健康检查的敏感信息暴露程度micrometer-registry-prometheus警告:生产环境切勿直接暴露
shutdown或env端点。我曾见过某公司因测试环境误开shutdown端点,被内部监控系统误触发导致服务下线。
网络层隔离:
management.server.port=8081)认证鉴权:
java复制@Configuration
@ConditionalOnProperty(name = "management.security.enabled", havingValue = "true")
public class ActuatorSecurity extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/internal-monitor/**")
.authorizeRequests()
.anyRequest().hasRole("ACTUATOR")
.and()
.httpBasic();
}
}
敏感信息脱敏:
@ConfigurationProperties 绑定配置时添加 @JsonFilterHealthIndicator 时过滤敏感数据继承 AbstractHealthIndicator 实现业务健康检查:
java复制@Component
public class PaymentServiceHealthIndicator extends AbstractHealthIndicator {
@Autowired
private PaymentClient paymentClient;
@Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
boolean isHealthy = paymentClient.ping();
if (isHealthy) {
builder.up()
.withDetail("version", paymentClient.getVersion());
} else {
builder.down()
.withDetail("error", paymentClient.getLastError());
}
}
}
该检查会自动聚合到 /health 端点,在 Kubernetes 的存活探针中可直接使用。
添加依赖:
xml复制<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
配置指标采集:
yaml复制management:
metrics:
export:
prometheus:
enabled: true
distribution:
percentiles-histogram:
http.server.requests: true
web:
server:
request:
autotime:
enabled: true
Grafana 仪表盘关键指标:
jvm_memory_used_bytes / jvm_memory_max_bytes)http_server_requests_seconds)hikaricp_connections_active)某次大促期间,我们通过 /threaddump 发现大量线程阻塞在 Redis 操作上。根本原因是某个热点 key 没有设置超时时间,导致分布式锁无法释放。解决方案:
ThreadPoolTaskExecutor 配置拒绝策略@Timed 注解监控关键方法耗时使用 /heapdump + Eclipse MAT 分析步骤:
bash复制curl -u actuator:password http://localhost:8081/internal-monitor/heapdump -o heap.hprof
无需重启修改日志级别:
bash复制POST /internal-monitor/loggers/com.example.demo
Content-Type: application/json
{"configuredLevel": "DEBUG"}
这个功能在排查线上问题时特别有用,但要注意:
对于高频查询的端点(如 /metrics),添加缓存减少性能损耗:
java复制@Configuration
public class ActuatorCacheConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new WebContentInterceptor() {
{
setCacheSeconds(10);
}
}).addPathPatterns("/internal-monitor/metrics");
}
}
统计订单创建成功率:
java复制@RestController
public class OrderController {
private final Counter orderCounter;
public OrderController(MeterRegistry registry) {
this.orderCounter = registry.counter("order.create",
"region", System.getenv("REGION"));
}
@PostMapping("/orders")
public Order createOrder() {
try {
Order order = orderService.create();
orderCounter.increment();
return order;
} catch (Exception e) {
orderCounter.increment(-1.0);
throw e;
}
}
}
在 Kubernetes 中区分关键/非关键检查:
yaml复制management:
health:
db:
enabled: true
redis:
enabled: true
diskspace:
enabled: ${ENV:PROD:false}
readinessState:
enabled: true
对应的探针配置:
yaml复制livenessProbe:
httpGet:
path: /internal-monitor/health/liveness
initialDelaySeconds: 60
readinessProbe:
httpGet:
path: /internal-monitor/health/readiness
initialDelaySeconds: 30
这种分级策略能避免非核心组件故障导致整个 Pod 被重启。