SpringBoot Actuator监控端点
Spring Boot 简化了配置,但日志管理依然需要重视。日志配置、链路追踪、排查思路都是日常开发中会遇到的问题。本文讲实际项目中的日志管理经验。
引入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
|
常用端点
| 端点 |
路径 |
说明 |
| health |
/actuator/health |
健康检查 |
| info |
/actuator/info |
应用信息 |
| metrics |
/actuator/metrics |
指标列表 |
| metrics/jvm.memory.used |
/actuator/metrics/jvm.memory.used |
JVM 内存使用 |
| env |
/actuator/env |
环境属性 |
| beans |
/actuator/beans |
所有 Bean |
| loggers |
/actuator/loggers |
日志级别 |
| threaddump |
/actuator/threaddump |
线程 dump |
| heapdump |
/actuator/heapdump |
堆 dump |
| mappings |
/actuator/mappings |
URL 映射 |
| httptrace |
/actuator/httptrace |
HTTP 请求追踪 |
配置
management: server: port: 8081 endpoints: web: exposure: include: health,info,metrics,prometheus exclude: env,beans base-path: /actuator endpoint: health: show-details: when_authorized probes: enabled: true metrics: enabled: true loggers: enabled: true metrics: export: prometheus: enabled: true
|
健康检查
#
内置 HealthIndicator
| Indicator |
检查内容 |
| DataSourceHealthIndicator |
数据库连接 |
| RedisHealthIndicator |
Redis 连接 |
| DiskSpaceHealthIndicator |
磁盘空间 |
| RabbitHealthIndicator |
RabbitMQ |
| ElasticsearchHealthIndicator |
ES 集群 |
#
自定义 HealthIndicator
@Component public class CustomServiceHealthIndicator implements HealthIndicator { @Autowired private CustomService customService; @Override public Health health() { try { customService.ping(); return Health.up() .withDetail("service", "custom") .withDetail("responseTime", "10ms") .build(); } catch (Exception e) { return Health.down() .withDetail("service", "custom") .withDetail("error", e.getMessage()) .build(); } } }
|
#
健康检查分组
management: endpoint: health: group: readiness: include: db, redis, diskSpace liveness: include: ping
|
curl http://localhost:8081/actuator/health/readiness curl http://localhost:8081/actuator/health/liveness
|
指标监控(Micrometer)
#
内置指标
curl http://localhost:8081/actuator/metrics
curl http://localhost:8081/actuator/metrics/jvm.memory.used curl http://localhost:8081/actuator/metrics/http.server.requests
|
#
自定义指标
@Service public class OrderService { private final Counter orderCounter; private final Timer orderTimer; private final Gauge queueGauge; private final AtomicInteger queueSize = new AtomicInteger(0); public OrderService(MeterRegistry meterRegistry) { this.orderCounter = Counter.builder("orders.created") .description("创建订单数") .register(meterRegistry); this.orderTimer = Timer.builder("orders.process.time") .description("订单处理时间") .register(meterRegistry); this.queueGauge = Gauge.builder("orders.queue.size", queueSize, AtomicInteger::get) .description("订单队列长度") .register(meterRegistry); } public void createOrder() { orderTimer.record(() -> { orderCounter.increment(); }); } }
|
Prometheus 集成
#
引入依赖
<dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId> </dependency>
|
#
查看指标
curl http://localhost:8081/actuator/prometheus
|
#
Prometheus 配置
scrape_configs: - job_name: 'spring-boot' metrics_path: '/actuator/prometheus' static_configs: - targets: ['localhost:8081']
|
自定义端点
#
@Endpoint
@Component @Endpoint(id = "custom") public class CustomEndpoint { @ReadOperation public Map<String, Object> read() { Map<String, Object> result = new HashMap<>(); result.put("status", "ok"); result.put("timestamp", System.currentTimeMillis()); return result; } @WriteOperation public void write(@Selector String name, @Nullable String value) { } @DeleteOperation public void delete(@Selector String name) { } }
|
#
访问
curl http://localhost:8081/actuator/custom
curl -X POST http://localhost:8081/actuator/custom/name -d "value=test"
curl -X DELETE http://localhost:8081/actuator/custom/name
|
安全配置
#
Spring Security
@Configuration public class ActuatorSecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.securityMatcher("/actuator/**") .authorizeHttpRequests(auth -> auth .requestMatchers("/actuator/health", "/actuator/info").permitAll() .requestMatchers("/actuator/**").hasRole("ADMIN") .anyRequest().authenticated() ) .httpBasic(); return http.build(); } }
|
#
防火墙限制
iptables -A INPUT -p tcp --dport 8081 -s 10.0.0.0/8 -j ACCEPT iptables -A INPUT -p tcp --dport 8081 -j DROP
|
Kubernetes 探针
apiVersion: v1 kind: Pod spec: containers: - name: app livenessProbe: httpGet: path: /actuator/health/liveness port: 8081 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: /actuator/health/readiness port: 8081 initialDelaySeconds: 5 periodSeconds: 5
|
最佳实践
| 实践 |
说明 |
| 独立端口 |
management.server.port 单独设置 |
| 安全加固 |
/actuator 路径需要认证 |
| 最小暴露 |
只暴露必要的端点 |
| 健康检查 |
自定义业务健康检查 |
| 指标命名 |
使用 dot 命名法:orders.created |
总结
Spring Boot Actuator 提供了完善的生产监控能力:
- 健康检查: readiness / liveness 探针
- 指标收集:Micrometer 统一指标
- 端点暴露:按需暴露管理端点
- Prometheus:云原生监控集成
合理使用 Actuator,可以大幅提升系统的可观测性。
核心要点
日志级别设置:根据环境设置合适的级别
日志格式配置:添加 traceId 便于链路追踪
日志输出:控制台输出和文件输出的配置
日志归档:设置滚动策略和保留时间
总结
日志是排查问题的生命线,合理配置日志可以提升排查效率。在实际项目中,结合 ELK 等工具搭建日志系统,可以更好地管理和分析日志。