Sleuth--链路追踪

1. 为什么需要链路追踪?(核心痛点)

在微服务架构中,一个用户请求往往需要经过多个服务(比如:网关→订单→商品→库存)。当请求变慢或出错时,我们面临的核心问题是:

  • 问题定位难:日志分散在不同服务器的不同服务里,很难快速找到是哪一步出了问题。

  • 依赖梳理难:不清楚服务间的调用关系是否合理,是否有循环依赖。

  • 性能分析难:无法直观看到每个服务环节的耗时,难以找到性能瓶颈。

分布式链路追踪就是为了解决这些问题,它能把一次请求经过的所有服务串联起来,形成一个完整的调用链视图。


2. Sleuth核心术语(理解链路数据模型)

Sleuth是Spring Cloud提供的链路追踪解决方案,它会在日志中注入追踪信息。理解这三个核心概念是关键:

  • Trace(追踪) :代表一次完整的请求链路。从用户发起请求到最终收到响应,这整个过程中经过的所有服务,都属于同一个Trace。它有一个全局唯一的ID,即TraceId

  • Span(跨度) :代表链路中的一个基本工作单元。比如,订单服务调用商品服务这个远程调用(RPC)过程,就是一个Span。每个Span也有自己的唯一ID,即SpanId 。一个Trace由多个Span组成,它们通过ParentId形成树状结构。

  • Annotation(注解) :用来标记一个Span生命周期中的关键事件,主要用于计算耗时:

    • cs (Client Send):客户端发起请求,标志着Span开始。

    • sr (Server Receive) :服务端收到请求。sr - cs = 网络延迟。

    • ss (Server Send) :服务端处理完成,准备返回响应。ss - sr = 服务端处理时间。

    • cr (Client Receive) :客户端收到响应,标志着Span结束。cr - sr = 整个请求的总时间。


3. 准备工作(实验环境搭建)

这是为了排除干扰,搭建一个干净的测试环境,我帮你解释一下每一步的意图:

  1. 注释掉网关的自定义断言/过滤器:防止自定义逻辑对请求链路产生干扰,让测试结果更纯粹。

  2. 采用最简单的网关配置 :直接使用服务名作为请求前缀(如 /order-serv/...),这是Spring Cloud Gateway配合服务发现(如Nacos)的默认路由方式,简单直观。

  3. 在商品服务中加入 Thread.sleep(5000)这是人为制造一个性能瓶颈。这样在Zipkin的UI界面上,就能清晰地看到"商品服务"这个Span耗时5秒,直观展示链路追踪对性能问题的定位能力。

  4. 修改订单服务的Feign超时配置 :因为商品服务被故意延迟了5秒,而Feign默认的readTimeout是1秒,会导致请求提前超时失败。将超时设为5000ms,是为了确保调用链路能够完整走通,以便在Zipkin中看到完整的追踪记录。


4. Sleuth入门(日志中观察链路)

  • 操作 :在公共模块(common)引入 spring-cloud-starter-sleuth 依赖,所有微服务就具备了生成追踪信息的能力。

  • 效果 :调用接口后,在每个微服务的控制台日志 中,你会看到格式类似的输出:[应用名, TraceId, SpanId, 是否采样]

  • 分析 :通过对比不同服务日志中的 TraceId,你就能手动将一次请求的各个服务环节串联起来。但日志太多时,这种方式效率很低,所以需要Zipkin。


5. Zipkin集成(可视化展示)

Zipkin提供了服务端(收集、存储、展示)和客户端(上报数据)的完整方案。

  • Zipkin架构

    • Collector:接收客户端上报的追踪数据。

    • Storage:存储数据(默认内存,生产用MySQL或Elasticsearch)。

    • API & Web UI:提供查询界面和RESTful API,用于展示调用链。

  • 客户端集成 :在每个需要追踪的微服务中,引入 spring-cloud-starter-zipkin 依赖,并配置 spring.zipkin.base-url 指向Zipkin服务端地址。

    • 采样率(spring.sleuth.sampler.probability=1.0:表示100%采样。生产环境建议调低(如0.1),因为全量采集会产生大量数据,影响性能和存储。

集成后,访问 http://localhost:9411,就能看到可视化的调用链,直观地发现哪个环节耗时最长。


6. Zipkin数据持久化(生产必备)

Zipkin默认将数据存在内存中,服务重启数据会丢失,且无法应对大量数据。生产环境必须持久化。

方案一:MySQL持久化

  • 原理:将Span和Annotation信息存储到关系型数据库。

  • 特点:适合数据量不大、查询简单的场景。但面对海量追踪数据,MySQL的读写性能会成为瓶颈。

  • 关键点 :启动Zipkin Server时通过命令行参数指定 STORAGE_TYPE=mysql 和数据库连接信息。

方案二:Elasticsearch持久化(推荐)

  • 原理:将追踪数据存储到Elasticsearch中。

  • 特点:Elasticsearch专为海量数据搜索和分析设计,读写性能高,是链路追踪系统最常用的存储方案,非常适合大规模生产环境。

  • 关键点 :启动Zipkin Server时通过参数指定 STORAGE_TYPE=elasticsearch 和ES的地址。


总结与常见面试点

  1. Sleuth的作用:在日志中注入TraceId和SpanId,将分布式请求链路标记出来。

  2. Zipkin的作用:收集、存储和展示这些链路数据,提供可视化UI。

  3. Trace与Span的关系:一个Trace包含多个Span,Span之间有父子关系(通过ParentId关联)。

  4. 采样率的重要性:生产环境不建议设置100%,通常配置为0.1~0.5,以减少性能损耗和存储压力。

  5. 持久化方案选择:小规模或演示用MySQL,中大规模生产用Elasticsearch。

相关推荐
行百里er19 小时前
Spring Insight 里上报 Span 为什么用 JDK HttpClient 而不是 RestTemplate
spring boot·spring cloud·监控
陈皮波比茶19 小时前
SpringCloudAlibaba
java·spring cloud·微服务
欢迎来到祖安!1 天前
企业微信 API 接口能力介绍:支持消息收发、图片发送、表情互动、联系人管理等多场景应用
java·前端·数据仓库·spring cloud·企业微信
行百里er2 天前
BlockingQueue:异步批量上报
spring boot·spring cloud·监控
wno7043 天前
Spring Cloud Hystrix Dashboard仪表盘
spring·spring cloud·hystrix
BUG指挥官3 天前
Redis已接入AI
数据库·人工智能·spring boot·redis·spring cloud
wno7043 天前
Spring Cloud Hystrix服务容错
spring·spring cloud·hystrix
苏渡苇4 天前
Spring Insight 里上报 Span 为什么用 JDK HttpClient 而不是 RestTemplate
java·后端·spring·spring cloud·springboot·性能监控
YOU OU5 天前
Spring Cloud Consul
spring cloud·consul·java-consul
重生之我是Java开发战士5 天前
【Spring Cloud】Eureka服务注册发现与LoadBalancer负载均衡
spring cloud·eureka·负载均衡