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。

相关推荐
Devin~Y1 天前
从内容社区到AI智能客服:Spring Boot + Spring Cloud + Spring AI 全栈实战面试拆解
java·spring boot·redis·elasticsearch·spring cloud·kafka·mybatis
IT机器猫1 天前
RabbitMQ基础二
java·spring boot·分布式·spring cloud·log4j·rabbitmq·springamqp
卷心菜的学习路1 天前
基于 Spring Cloud Tencent 元数据路由实现个人开发泳道,告别频繁部署
java·spring cloud
砍材农夫2 天前
spring-ai|Spring‑AI 2.0.0 新特性 + 入门教程
spring boot·spring·spring cloud
Java成神之路-3 天前
Spring Cloud 微服务契约先行:为什么 Controller 建议要实现 Feign 接口?
spring·spring cloud·微服务
vx-程序开发3 天前
springboot旅游推介平台---附源码24175
java·spring boot·python·spring cloud·eclipse·django·idea
952366 天前
Spring-cloud配置中心
java·spring·spring cloud·微服务
ruofu336 天前
如何让docker使用提前下载好的镜像,而不是在线拉取
java·spring cloud·docker
过客随尘9 天前
网关扩容了,流量却还是打不过去?企业级 Spring Cloud Gateway 生产动态化部署实战
spring cloud·微服务·架构