微服务架构中一次请求跨越多个服务节点,故障定位和性能分析需要全链路追踪支持。OpenTelemetry是CNCF的观测性标准,统一了Traces、Metrics和Logs三种信号的采集协议。Jaeger是Uber开源的分布式追踪后端,支持Span存储、查询和可视化。分布式链路追踪通过Trace ID关联各服务节点的Span,还原完整调用链路。
OpenTelemetry SDK集成与Span传播机制
OpenTelemetry通过Trace Context和Baggage两种传播协议在服务间传递追踪上下文。W3C Trace Context使用traceparent HTTP头传递Trace ID、Span ID和采样标志。
Java应用集成OpenTelemetry SDK:
// pom.xml依赖
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-spring-boot-starter</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-otlp</artifactId>
<version>1.39.0</version>
</dependency>
application.yml配置OTLP导出器:
otel:
service.name: order-service
exporter.otlp.endpoint: http://otel-collector:4317
exporter.otlp.protocol: grpc
traces.exporter: otlp
sampler.parentbased: true
sampler.traceidratiobased: 0.1
traces.exporter设为otlp通过gRPC发送Span数据到Collector。sampler.traceidratiobased设为0.1表示10%采样率,生产环境中高流量服务可降低采样率以减少存储开销。
手动创建Span记录业务逻辑:
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.api.GlobalOpenTelemetry;
public class OrderService {
private static final Tracer tracer = GlobalOpenTelemetry.getTracer("order-service");
public Order createOrder(OrderRequest request) {
Span span = tracer.spanBuilder("createOrder")
.setAttribute("order.userId", request.getUserId())
.setAttribute("order.amount", request.getAmount())
.startSpan();
try (Scope scope = span.makeCurrent()) {
// 验证库存
Span inventorySpan = tracer.spanBuilder("checkInventory").startSpan();
boolean available = inventoryService.check(request.getProductId());
inventorySpan.setAttribute("inventory.available", available);
inventorySpan.end();
if (!available) {
span.recordException(new RuntimeException("库存不足"));
span.setStatus(StatusCode.ERROR);
throw new BusinessException("库存不足");
}
// 创建订单
Order order = orderRepository.save(request);
span.setAttribute("order.id", order.getId());
return order;
} finally {
span.end();
}
}
}
setAttribute添加业务标签,便于在Jaeger UI中按标签查询。recordException记录异常堆栈,setStatus标记Span状态。子Span(checkInventory)自动继承父Span的Trace ID。
OpenTelemetry Collector管道配置与数据转发
Collector是OpenTelemetry的核心组件,负责接收、处理和导出遥测数据。支持多接收器(OTLP gRPC/HTTP、Zipkin、Jaeger)和多导出器(Jaeger、Prometheus、Elasticsearch)。
# otel-collector-config.yaml
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
timeout: 5s
send_batch_size: 1024
memory_limiter:
check_interval: 2s
limit_mib: 512
filter:
error_mode: ignore
traces:
span:
- 'attributes["http.status_code"] == 404'
exporters:
otlp/jaeger:
endpoint: jaeger:4317
tls:
insecure: true
logging:
loglevel: warn
service:
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, filter, batch]
exporters: [otlp/jaeger]
batch处理器批量发送Span减少网络请求。memory_limiter防止Collector内存溢出。filter处理器过滤404状态的Span,减少无效数据存储。
Jaeger后端部署与查询分析
Jaeger支持内存存储(测试用)和Elasticsearch/Cassandra存储(生产用)。Docker Compose部署Jaeger + Elasticsearch:
version: "3.8"
services:
jaeger:
image: jaegertracing/all-in-one:1.57
environment:
SPAN_STORAGE_TYPE: elasticsearch
ES_SERVER_URLS: http://elasticsearch:9200
ES_TAGS_AS_FIELDS_ALL: "true"
ports:
- "16686:16686"
depends_on:
- elasticsearch
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.13.0
environment:
discovery.type: single-node
xpack.security.enabled: "false"
ES_JAVA_OPTS: "-Xms2g -Xmx2g"
Jaeger UI(端口16686)支持按服务名、Trace ID、标签和持续时间查询。Find Traces页面中设置minDuration可筛选慢请求,Tags搜索框输入order.userId=12345可按业务字段精确查询。
Trace详情页展示调用链路的瀑布图,每个Span显示服务名、操作名、起止时间和耗时占比。错误Span以红色标记,展开可查看异常堆栈和标签。通过Trace Flame Graph视图直观展示并发Span和串行调用关系。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/fen-bu-shi-lian-lu-zhui-zong-shi-zhan-opentelemetry-yu/