“谁调了谁我咋知道?!” ——基于 Spring Cloud Sleuth 与 Zipkin 的链路追踪系统实战研究

举报
bug菌 发表于 2025/06/05 17:44:13 2025/06/05
【摘要】 🏆本文收录于「滚雪球学SpringBoot」专栏(全网一个名),手把手带你零基础入门Spring Boot,从入门到就业,助你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!

🏆本文收录于「滚雪球学SpringBoot」专栏(全网一个名),手把手带你零基础入门Spring Boot,从入门到就业,助你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!

环境说明:Windows 10 + IntelliJ IDEA 2021.3.2 + Jdk 1.8

🔍前序

🙋‍♂️你有没有遇到这种情况:一个请求从入口开始层层穿透,绕了七八个服务,最后报错了,你一脸懵逼地看着日志说:
“这错误到底是哪冒出来的?!”

✋别急,今天我们就带你搞定微服务中最令人头大的问题之一:服务调用链路追踪

🌟前言:微服务越拆越细,可你看得清楚它们在干嘛吗?

说实话,刚做微服务时,那种“哇,一个服务干一件事,好清晰”的感觉挺爽的。可爽着爽着,几十上百个服务一上线,你就开始头大了。

一个请求经过网关、认证中心、用户服务、订单服务、库存服务,最后在发货服务里跪了。而你,还得翻每个服务的日志,靠 requestId 或者时间戳瞎猜“哪个服务出了问题”。

这时候,就得请出我们今天的主角:Spring Cloud Sleuth + Zipkin

🧠它俩到底是啥?

名称 作用 通俗解释
Sleuth 分布式链路追踪工具,负责生成 Trace ID / Span ID 等 每个请求贴上唯一编号
Zipkin 可视化追踪平台,接收 Sleuth 上报的数据并展示 帮你画出“请求流向图”

🧩微服务链路追踪的核心概念

  • Trace ID:每个请求唯一的追踪编号,一条请求链共享一个 Trace ID
  • Span ID:表示某个服务内部的一个调用片段
  • Parent ID:表示当前 Span 的上级调用
  • Tags / Logs:用于标记事件或记录日志时间点

就像你寄快递,Trace ID 是整个物流单号,Span 就是每一个物流节点。

⚙️实战开始!从 0 构建 Sleuth + Zipkin 链路追踪体系

1️⃣ 添加依赖(以 Spring Boot 2.x 为例)

在每个服务的 pom.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>

2️⃣ 配置 Sleuth 与 Zipkin 上报

在每个服务的 application.yml 中添加:

spring:
  application:
    name: user-service # 服务名称
  zipkin:
    base-url: http://localhost:9411
    sender:
      type: web
  sleuth:
    sampler:
      probability: 1.0 # 打开全量采样,开发阶段推荐;线上可调整为 0.1

🎯温馨提示:probability 决定了 Sleuth 要不要“抓这个请求”,值越大抓得越多。线上环境建议控制在 0.1-0.2,否则 Zipkin 会被压爆。

3️⃣ 启动 Zipkin 服务端(推荐 Docker)

docker run -d \
  -p 9411:9411 \
  openzipkin/zipkin

访问:http://localhost:9411,就能看到, Zipkin 控制台啦!

4️⃣ 示例:三个服务调用链路示意

假设我们有如下服务链路:

Gateway --> Order Service --> Product Service

每个服务都通过 RestTemplateOpenFeign 调用其他服务,Sleuth 会自动将 TraceID/SpanID 注入 Header 并自动传播!

5️⃣ 关键代码:日志 + 手动打点

日志格式建议配置:

logging:
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{X-B3-TraceId}/%X{X-B3-SpanId}] [%thread] %-5level %logger{36} - %msg%n"

输出效果如下:

2025-06-05 14:00:02.123 [9f3e4ccf3d401a12/9f3e4ccf3d401a12] [http-nio-8080-exec-1] INFO  c.m.s.OrderController - 创建订单成功!

看见没?那个 [TraceId/SpanId] 就是你调试的“通关文牒”!

手动打点记录事件:

@Autowired
private Tracer tracer;

public void someLogic() {
    Span span = tracer.nextSpan().name("do-some-logic").start();
    try (Tracer.SpanInScope ws = tracer.withSpan(span)) {
        // 你的业务逻辑
        log.info("Doing something inside span...");
    } finally {
        span.end(); // 必须结束 span!
    }
}

🧠场景:需要对关键逻辑手动标记时间点或性能瓶颈的,可以通过自定义 span 实现可视化跟踪!

📈Zipkin 可视化界面长啥样?

在 Zipkin UI 输入 TraceId 或者任意查询条件,就能看到如下展示:

+-------------------------------------------------------------+
| Trace: c9f65c312bbc3d49                                     |
+-------------------------------------------------------------+
| Service Name   | Operation      | Duration | Start Time     |
|----------------|----------------|----------|----------------|
| gateway        | GET /api/order | 35ms     | 14:00:00.000   |
| order-service  | createOrder()  | 28ms     | 14:00:00.005   |
| product-service| checkStock()   | 18ms     | 14:00:00.012   |
+-------------------------------------------------------------+

是不是很像一个“时间片排查神器”?!💥

💡高级技巧拓展玩法

玩法 用法 说明
🔗 Sleuth + Kafka 通过 Kafka 异步发送链路数据 降低 Zipkin 写入压力
🧠 Sleuth + ELK 配合 ELK 联动日志搜索 日志与链路统一查询体验
🕵️‍♂️ Sleuth + Prometheus 跨服务调用耗时指标采集 性能瓶颈实时预警
☁️ Sleuth + SkyWalking 可选替代方案,更强大的 APM 支持 SQL、Redis、线程等深度追踪

⚠️开发中你可能遇到的坑

问题 原因 解决方案
Zipkin 页面没数据 没有采样 / 没配置地址 检查 probabilityzipkin.base-url
TraceID 不一致 手动调用 HTTP 没带 header 使用 RestTemplate + Sleuth 或 Feign
日志太多性能下降 采样率太高 线上设置 probability < 1.0

✅总结:链路追踪,不是可有可无,而是微服务“生命线”

想象一个没有链路追踪的系统,就像一个没有 Google Maps 的城市,你只能凭经验猜路,哪儿堵了、哪儿断了完全靠天意。

而 Sleuth + Zipkin 就是你的“导航 + 监控塔”,它告诉你请求从哪儿来,去哪儿了,哪儿慢了,哪儿跪了。

❓最后留个问题给你:你的日志,是“审判日志”还是“溯源日志”?

是不是只有在报错时,才开始一行一行翻日志?
那你就输了。

有了链路追踪系统,日志从此不是“背锅证据”,而是你系统健康的实时“体检报告”!

🧧福利赠与你🧧

  无论你是计算机专业的学生,还是对编程有兴趣的小伙伴,都建议直接毫无顾忌的学习此专栏「滚雪球学SpringBoot」专栏(全网一个名),bug菌郑重承诺,凡是学习此专栏的同学,均能获取到所需的知识和技能,全网最快速入门SpringBoot,就像滚雪球一样,越滚越大, 无边无际,指数级提升。

  最后,如果这篇文章对你有所帮助,帮忙给作者来个一键三连,关注、点赞、收藏,您的支持就是我坚持写作最大的动力。

  同时欢迎大家关注公众号:「猿圈奇妙屋」 ,以便学习更多同类型的技术文章,免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板、技术文章Markdown文档等海量资料。

✨️ Who am I?

我是bug菌(全网一个名),CSDN | 掘金 | InfoQ | 51CTO | 华为云 | 阿里云 | 腾讯云 等社区博客专家,C站博客之星Top30,华为云多年度十佳博主/价值贡献奖,掘金多年度人气作者Top40,掘金等各大社区平台签约作者,51CTO年度博主Top12,掘金/InfoQ/51CTO等社区优质创作者;全网粉丝合计 30w+;更多精彩福利点击这里;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试真题、4000G PDF电子书籍、简历模板等海量资料,你想要的我都有,关键是你不来拿。

-End-

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。