链路追踪 Sleuth + Zipkin
TIP
在微服务架构中,一个请求会经过多个服务。链路追踪可以帮助理解请求的完整调用链,快速定位性能瓶颈和故障点。
核心概念
| 概念 | 说明 |
|---|---|
| TraceId | 一次请求的全局唯一 ID |
| SpanId | 每个服务调用的唯一 ID |
| ParentId | 父 Span 的 ID,形成调用树 |
Sleuth 集成
引入依赖
xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>效果
添加 Sleuth 后,日志会自动包含 TraceId 和 SpanId:
2024-01-01 10:00:00.123 [user-service, trace-id, span-id] INFO UserController
2024-01-01 10:00:00.456 [order-service, trace-id, span-id] INFO OrderController可以看到两个日志的 TraceId 相同,表示它们是同一次请求的调用链。
Zipkin 集成
Zipkin 用于收集和展示链路数据。
部署 Zipkin
bash
docker run -d -p 9411:9411 openzipkin/zipkin配置数据上报
yaml
spring:
sleuth:
sampler:
probability: 1.0 # 采样率 100%(生产环境建议降低)
zipkin:
base-url: http://localhost:9411
sender:
type: web # 通过 HTTP 上报自定义 Span
java
@Service
public class OrderService {
@Autowired
private Tracer tracer;
public Order createOrder(Order order) {
// 创建自定义 Span
Span span = tracer.nextSpan().name("validate-order").start();
try (Tracer.SpanInScope ws = tracer.withSpanInScope(span)) {
// 执行业务逻辑
validateOrder(order);
} finally {
span.finish();
}
return orderDao.save(order);
}
}Zipkin 控制台
Zipkin UI 提供:
- 查找:按 TraceId 或条件搜索链路
- 依赖图:服务间调用关系
- 时间线:各 Span 的耗时分布
Brave(Sleuth 底层)
Sleuth 底层基于 Brave 实现,也可直接使用 Brave API:
java
@Autowired
private Tracer tracer;
public void businessMethod() {
Span span = tracer.nextSpan()
.name("business-method")
.tag("key", "value")
.start();
try {
// 业务代码
} finally {
span.finish();
}
}TIP
- 生产环境中采样率建议设为 0.1~0.01(10%~1%),避免过多数据
- Zipkin 数据可以持久化到 Elasticsearch 实现长时间存储