
基于Spring Cloud Sleuth与Zipkin的分布式链路追踪实战指南
随着微服务架构的普及,服务间调用链条变得越来越复杂。在生产环境中,定位跨服务调用的性能瓶颈、故障根因,往往需要分布式链路追踪能力。本文结合Spring Cloud Sleuth与Zipkin,分享完整的链路追踪实战经验,包括架构设计、关键配置、代码示例、踩坑及优化建议。
1. 业务场景描述
在某电商平台中,下单流程涉及多个微服务:
- API 网关(Spring Cloud Gateway)
- 订单服务(Order Service)
- 库存服务(Inventory Service)
- 支付服务(Payment Service)
当用户下单时,请求从网关开始,依次调用订单、库存、支付。最近系统在高并发场景下出现请求延迟时长不一致、偶发超时等问题,需要基于链路追踪快速定位延迟热点。
特点:
- 微服务数量 10+,基于 Spring Cloud 构建
- 部署在 Kubernetes 集群中
- 日调用量峰值 5 万次/秒
- 需要结合 Zipkin UI 进行可视化追踪
2. 技术选型过程
在链路追踪技术选型时,核心考虑:
- 与 Spring 生态兼容性:优先选用 Spring Cloud Sleuth
- 可视化 UI:开源 Zipkin 提供成熟界面
- 性能开销:轻量级埋点,采样率可配置
- 部署 & 可扩展:支持集群级别扩展
综上,最终选择 Spring Cloud Sleuth + Zipkin 组合。Sleuth 在应用中自动注入 TraceID、SpanID,并通过 HTTP Header 传递调用链;Zipkin 负责集中存储、聚合与 UI 展示。
3. 实现方案详解
3.1 系统架构图
+------------+ +------------+ +------------+ +------------+
| API Gateway|---(HTTP)-->|Order Svc |---(RPC)--->|Inventory Svc|---(gRPC)-->|Payment Svc |
| (Gateway) | |(Spring Boot)| |(Spring Boot)| |(Spring Boot)|
+------------+ +------------+ +------------+ +------------+
| | | |
+----------------------> Zipkin Collector <----------+-------------------------+
(Spring Boot)
各服务通过注入 Spring Cloud Sleuth 自动上报 span 信息,Zipkin Collector 收集并存储到 Elasticsearch 或 MySQL 中。
3.2 关键依赖与配置
在每个微服务的 pom.xml 中添加:
xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
在 application.yml 中配置:
yaml
spring:
application:
name: order-service
sleuth:
sampler:
probability: 0.2 # 采样率 20%
zipkin:
base-url: http://zipkin.example.com # Zipkin 服务地址
sender:
type: web # 通过 HTTP 上报
compression-enabled: true # 启用压缩
3.3 核心代码示例
3.3.1 REST Controller 中自定义 Span
java
@RestController
@RequestMapping("/order")
public class OrderController {
private final Tracer tracer;
public OrderController(Tracer tracer) {
this.tracer = tracer;
}
@PostMapping
public ResponseEntity<OrderDTO> createOrder(@RequestBody OrderRequest req) {
// 创建自定义子 Span
Span newSpan = tracer.nextSpan().name("custom-order-processing");
try (Tracer.SpanInScope ws = tracer.withSpan(newSpan.start())) {
// 业务逻辑
log.info("开始处理订单: {}", req);
OrderDTO order = orderService.process(req);
return ResponseEntity.ok(order);
} finally {
newSpan.end();
}
}
}
3.3.2 RPC 客户端自动链路传递
使用 Feign 或 RestTemplate 时无需额外配置,Sleuth 自动拦截并传递 TraceID。
java
@FeignClient("inventory-service")
public interface InventoryClient {
@PostMapping("/inventory/reserve")
void reserve(@RequestBody ReserveRequest req);
}
3.3.3 Zipkin Server 部署示例
使用 Docker 方式快速启动 Zipkin:
bash
docker run -d -p 9411:9411 openzipkin/zipkin
3.4 项目结构示例
order-service/
├── pom.xml
├── src/main/java/com/example/order
│ ├── OrderApplication.java
│ ├── controller/OrderController.java
│ ├── service/OrderService.java
│ └── config/ZipkinConfig.java
└── src/main/resources/application.yml
4. 踩过的坑与解决方案
-
问题:采样率过低导致链路不完整。 解决:根据流量大小,合理调整
spring.sleuth.sampler.probability
。 -
问题:Zipkin 存储后端压力大。 解决:可切换到 Elasticsearch 集群,或使用 Kafka + Cassandra 存储方案。
-
问题:跨域请求丢失 TraceID。 解决:在网关中配置过滤器,统一转发
X-B3-*
Header。
5. 总结与最佳实践
- 合理设置采样率,兼顾性能与链路覆盖率。
- 针对关键业务节点自定义 Span,提升可视化粒度。
- Zipkin 存储后端可根据数据量扩展,避免单点瓶颈。
- 在 Kubernetes 环境中部署时,可结合 Sidecar 模式进一步解耦链路上报。
通过本文示例,您可以快速在生产环境中集成 Spring Cloud Sleuth 与 Zipkin,实现高效的分布式链路追踪,帮助团队准确定位服务性能瓶颈与故障根因。