Spring Boot 4.x可观测性:分布式追踪与指标监控 技术原理 Spring Boot 4.x引入了全新的可观测性架构,统一了metrics、tracing和logging。基于Micrometer Tracing和OpenTelemetry,提供了开箱即用的分布式追踪和监控能力。 核心组件 Micrometer Tracing: 分布式追踪抽象层 Micrometer Metrics: 指标收集 OpenTelemetry: 可观测性标准实现 Actuator: 生产级监控端点 实践案例:构建可观测的微服务 项目配置 应用配置 自定义追踪 使用@NewSpan 编程式追踪 自定义Metrics Counter指标 Gauge指标 Timer指标 分布式追踪实战
Spring Boot 4.x引入了全新的可观测性架构,统一了metrics、tracing和logging。基于Micrometer Tracing和OpenTelemetry,提供了开箱即用的分布式追踪和监控能力。
<!-- pom.xml --> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!-- Micrometer Tracing --> <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-tracing-bridge-brave</artifactId> </dependency> <!-- Zipkin Exporter --> <dependency> <groupId>io.zipkin.reporter2</groupId> <artifactId>zipkin-reporter-brave</artifactId> </dependency> <!-- Prometheus --> <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId> </dependency> <!-- Observation --> <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-observation</artifactId> </dependency> </dependencies>
# application.yml spring: application: name: order-service # Zipkin配置 zipkin: base-url: http://localhost:9411 enabled: true service: name: ${spring.application.name} management: endpoints: web: exposure: include: health,info,metrics,prometheus endpoint: health: show-details: always metrics: enabled: true metrics: export: prometheus: enabled: true tags: application: ${spring.application.name} distribution: percentiles-histogram: http.server.requests: true sla: http.server.requests: 100ms,200ms,500ms,1s,2s tracing: sampling: probability: 1.0 # 100%采样(生产环境建议0.1)
package com.example.demo.service; import io.micrometer.tracing.annotation.NewSpan; import io.micrometer.tracing.annotation.SpanTag; import org.springframework.stereotype.Service; @Service public class OrderService { @NewSpan("order-service-create-order") public Order createOrder(@SpanTag("orderId") String orderId, @SpanTag("userId") String userId) { // 业务逻辑 Order order = new Order(orderId, userId); processPayment(order); return order; } @NewSpan("order-service-process-payment") public void processPayment(@SpanTag("order.id") Order order) { // 支付处理逻辑 try { Thread.sleep(100); // 模拟处理时间 } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } record Order(String id, String userId) {} }
package com.example.demo.controller; import io.micrometer.observation.Observation; import io.micrometer.observation.ObservationRegistry; import org.springframework.web.bind.annotation.*; import org.springframework.stereotype.Controller; @Controller @RequestMapping("/api") public class OrderController { private final ObservationRegistry observationRegistry; public OrderController(ObservationRegistry observationRegistry) { this.observationRegistry = observationRegistry; } @PostMapping("/orders") public String createOrder(@RequestBody OrderRequest request) { return Observation.createNotStarted("custom.order.create", observationRegistry) .contextualName("create-order") .lowCardinalityKeyValue("orderType", request.type()) .highCardinalityKeyValue("orderId", request.orderId()) .observe(() -> { // 业务逻辑 return processOrder(request); }); } private String processOrder(OrderRequest request) { return "Order created: " + request.orderId(); } record OrderRequest(String orderId, String type) {} }
package com.example.demo.metrics; import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.MeterRegistry; import org.springframework.stereotype.Component; @Component public class OrderMetrics { private final Counter orderCreatedCounter; private final Counter orderCancelledCounter; public OrderMetrics(MeterRegistry registry) { this.orderCreatedCounter = Counter.builder("orders.created") .description("Total orders created") .tag("service", "order-service") .register(registry); this.orderCancelledCounter = Counter.builder("orders.cancelled") .description("Total orders cancelled") .tag("service", "order-service") .register(registry); } public void recordOrderCreated() { orderCreatedCounter.increment(); } public void recordOrderCancelled() { orderCancelledCounter.increment(); } }
@Component public class SystemMetrics { private final Queue<String> orderQueue = new ConcurrentLinkedQueue<>(); public SystemMetrics(MeterRegistry registry) { Gauge.builder("orders.queue.size", orderQueue, Queue::size) .description("Current size of order queue") .tag("service", "order-service") .register(registry); Gauge.builder("orders.queue.latency", this, SystemMetrics::calculateLatency) .description("Average processing latency") .register(registry); } private double calculateLatency() { // 计算延迟逻辑 return 0.0; } }
@Component public class PerformanceMetrics { private final MeterRegistry registry; public PerformanceMetrics(MeterRegistry registry) { this.registry = registry; } public <T> T recordTimer(String operationName, Supplier<T> supplier) { return Timer.builder("operation.duration") .description("Operation duration") .tag("operation", operationName) .publishPercentiles(0.5, 0.95, 0.99) .register(registry) .recordCallable(() -> supplier.get()); } }
# 使用Docker启动Zipkin docker run -d -p 9411:9411 \ --name zipkin \ openzipkin/zipkin
# prometheus.yml global: scrape_interval: 15s scrape_configs: - job_name: 'spring-boot-app' metrics_path: '/actuator/prometheus' static_configs: - targets: ['host.docker.internal:8080']
docker run -d -p 9090:9090 \ -v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml \ --name prometheus \ prom/prometheus
docker run -d -p 3000:3000 \ --name grafana \ grafana/grafana
package com.example.demo.health; import org.springframework.boot.actuate.health.Health; import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.stereotype.Component; import java.sql.Connection; import java.sql.DriverManager; @Component public class DatabaseHealthIndicator implements HealthIndicator { @Override public Health health() { try (Connection conn = DriverManager.getConnection( "jdbc:mysql://localhost:3306/mydb", "user", "password")) { if (conn.isValid(1)) { return Health.up() .withDetail("database", "MySQL") .withDetail("status", "Connected") .build(); } } catch (Exception e) { return Health.down() .withDetail("error", e.getMessage()) .build(); } return Health.down().build(); } }
@Component public class CustomMetricsEndpoint { @ReadOperation public Map<String, Object> customMetrics() { Map<String, Object> metrics = new HashMap<>(); metrics.put("custom.metric1", 100); metrics.put("custom.metric2", "active"); return metrics; } }
# 查看所有metrics curl http://localhost:8080/actuator/metrics # 查看特定metric curl http://localhost:8080/actuator/metrics/http.server.requests # 查看Prometheus格式 curl http://localhost:8080/actuator/prometheus
Spring Boot 4.x的可观测性特性让微服务监控变得简单而强大。通过统一的Metrics、Tracing和Logging,开发者可以快速定位问题、分析性能瓶颈。建议在所有生产环境中启用这些特性,配合Grafana等可视化工具,实现全面的系统监控。