当前位置: 首页 > news >正文

SpringCloud--Sleuth 解析

一、Sleuth 概述

Sleuth 是 Spring Cloud 生态系统中的一个组件,它提供了分布式追踪的解决方案。在微服务架构中,一个请求可能会经过多个服务,Spring Cloud Sleuth 可以帮助我们跟踪这些请求,为每个请求生成一个唯一的追踪ID,并在日志中记录这些ID,从而使得我们可以轻松地追踪请求在各个微服务中的流转情况。

二、Sleuth 核心概念

  1. Trace:一次完整的分布式请求跟踪,相当于一个树状结构,从请求到第一个服务开始,到最后一个服务返回响应结束。每个 Trace 有一个唯一的 Trace ID。
  2. Span:表示一个基本的工作单元,比如一次 HTTP 请求、一次数据库调用等。每个 Span 有一个唯一的 Span ID。一个 Trace 由多个 Span 组成,这些 Span 之间具有父子关系。
  3. Annotation:用于记录事件的时间点,例如:
    • cs(Client Sent):客户端发送请求,表示开始一个 Span。
    • sr(Server Received):服务端接收请求,并开始处理。
    • ss(Server Sent):服务端发送响应,表示处理完成。
    • cr(Client Received):客户端接收响应,表示 Span 结束。

三、Sleuth 核心功能

  1. 分布式追踪:跟踪请求在微服务间的流转路径。
  2. Span 管理:记录每个服务处理单元的工作单元。
  3. Trace 上下文传播:在服务间传递追踪上下文。
  4. 与 Zipkin 集成:将追踪数据导出到 Zipkin 进行可视化分析。

四、Sleuth 实现原理

Spring Cloud Sleuth 的实现原理可以总结为:

  1. 标识与上下文: 通过 TraceId 和 SpanId 唯一标识请求链路和单元。
  2. 传播与透传: 利用 ThreadLocal 进行进程内上下文存储,并通过 HTTP 头等载体进行跨服务上下文传播。
  3. 自动化与透明: 通过自动仪器化主流框架组件,对开发者透明地完成追踪逻辑的植入。
  4. 收集与可视化: 通过 Reporter 将完成的 Span 数据上报给 Zipkin 等后端,进行聚合、存储和图形化展示。
  5. 日志增强: 通过与 MDC 集成,无缝地将追踪信息输出到应用日志中,极大方便了问题排查。

五、实现案例(Sleuth + Zipkin)

使用Spring Boot和Spring Cloud Sleuth与Zipkin来实现分布式链路追踪,主要步骤:

  1. 创建两个Spring Boot服务:一个作为服务提供者(provider),一个作为服务消费者(consumer),消费者调用提供者的服务。
  2. 引入Spring Cloud Sleuth和Zipkin的依赖。
  3. 配置Zipkin服务器地址。
  4. 通过RestTemplate或FeignClient进行服务调用,Sleuth会自动追踪。
  5. 启动Zipkin服务器来收集和展示追踪数据。
5.1 环境准备

使用 Docker 启动 Zipkin Server。

# 使用 Docker 运行 Zipkin
docker run -d -p 9411:9411 --name zipkin openzipkin/zipkin# 或者使用命令行启动(需要 Java 环境)
# curl -sSL https://zipkin.io/quickstart.sh | bash -s
# java -jar zipkin.jar
5.2 添加依赖

在服务提供者和服务消费者服务的pom.xml文件中分别添加Sleuth和Zipkin的依赖。

<!-- Spring Cloud 版本管理 -->
<properties><spring-cloud.version>2022.0.4</spring-cloud.version>
</properties><!-- Sleuth + Zipkin 依赖 -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>
5.3 配置文件

在服务提供者和服务消费者服务的application.yml配置文件中配置Zipkin服务器地址。

spring:application:name: user-servicesleuth:sampler:probability: 1.0  # 采样率,1.0表示100%采样zipkin:base-url: http://localhost:9411  # Zipkin服务器地址sender:type: web
5.4 服务间调用追踪

当服务都启动成功后,进行服务间的调用时,Sleuth会自动在header中添加Trace信息。

@RestController
@RequestMapping("/users")
public class UserController {private final RestTemplate restTemplate;private final UserService userService;public UserController(RestTemplate restTemplate, UserService userService) {this.restTemplate = restTemplate;this.userService = userService;}@GetMapping("/{userId}/orders")public UserOrderInfo getUserOrders(@PathVariable Long userId) {// Sleuth会自动在header中添加Trace信息ResponseEntity<OrderList> orderResponse = restTemplate.exchange("http://order-service/orders/user/" + userId,HttpMethod.GET,null,OrderList.class);User user = userService.getUserById(userId);return new UserOrderInfo(user, orderResponse.getBody());}
}
5.5 查看 Zipkin 链路追踪

访问 http://localhost:9411 查看链路追踪数据:

  1. 在 Zipkin UI 中可以看到服务间的调用关系。
  2. 查看每个请求的详细链路信息。
  3. 分析服务调用的耗时和依赖关系。

六、高级配置和自定义

6.1 自定义 Span 标签
@Service
public class UserService {private final Tracer tracer;public UserService(Tracer tracer) {this.tracer = tracer;}public User getUserById(Long userId) {// 创建自定义SpanSpan userSpan = tracer.nextSpan().name("db.user.query").start();try (Tracer.SpanInScope ws = tracer.withSpanInScope(userSpan)) {// 业务逻辑userSpan.tag("user.id", userId.toString());userSpan.event("query.user.from.database");// 模拟数据库查询return userRepository.findById(userId);} catch (Exception e) {userSpan.error(e);throw e;} finally {userSpan.end();}}
}
6.2 异步方法追踪
@Async
@Sleuth
public CompletableFuture<User> getUserAsync(Long userId) {// Sleuth会自动传递Trace上下文return CompletableFuture.supplyAsync(() -> userRepository.findById(userId));
}
6.3 自定义采样策略
@Configuration
public class TraceConfig {@Beanpublic Sampler defaultSampler() {// 自定义采样策略:只追踪重要接口return new Sampler() {@Overridepublic boolean isSampled(TraceContext traceContext) {// 根据请求路径决定是否采样String path = getCurrentRequestPath();return path.startsWith("/api/") || path.startsWith("/internal/");}};}
}
6.4 数据库调用追踪
@Configuration
public class DataSourceConfig {@Beanpublic DataSource dataSource() {// 使用P6Spy拦截SQL语句P6SpyDataSource dataSource = new P6SpyDataSource(actualDataSource());return dataSource;}
}
6.5 消息队列追踪
@Component
public class MessageService {private final Tracer tracer;private final StreamBridge streamBridge;public void sendUserCreatedEvent(User user) {// 手动注入Trace信息到消息头Message<User> message = MessageBuilder.withPayload(user).setHeader("traceId", tracer.currentSpan().context().traceId()).setHeader("spanId", tracer.currentSpan().context().spanId()).build();streamBridge.send("user-created-out-0", message);}
}
http://www.dtcms.com/a/540035.html

相关文章:

  • 【C++:继承和多态】多态加餐:面试常考——多态的常见问题11问
  • 零基础新手小白快速了解掌握服务集群与自动化运维(十五)Redis模块-哨兵集群
  • 今日Cortex-M3/M4研究总结
  • 2014吉林省赛题解 | CCUT应用OJ题解——Sign in
  • 涿州网站建设推广浙江建筑信息网站
  • 前端性能优化实战指南:从首屏加载到用户体验的全面提升
  • 【OPENGL ES 3.0 学习笔记】第十一天:glDrawArrays和glDrawElements
  • Linux入门1(2/2)
  • ubuntu24安装mysql遇到的坑----解决Mysql报错缺少libaio.so.1
  • 【星光不负 码向未来 | 万字解析:基于ArkUI声明式UI与分布式数据服务构建生产级跨设备音乐播放器】
  • UniApp 在手机端(Android)打开选择文件和文件写入
  • HarmonyOS分布式媒体播放器——跨设备音视频无缝流转
  • 【金融行业案例】基于Vaadin全栈Java框架重构内部系统,全面提升开发效率与用户体验
  • 小型网站开发要多少钱苏州专业做网站的公司哪家好
  • RocketMQ 生产环境性能调优实战:从 0 到 1 打造高可用消息队列系统
  • 脉冲按摩贴方案开发, 脉冲按摩贴MCU控制方案设计
  • 特别酷炫网站做网站有费用吗
  • DrissionPage 基于 Python 的网页自动化工具
  • Next.js vs Vue.js:2025年全栈战场,谁主沉浮?
  • DAY01笔记
  • 10-js基础(ESMAScript)
  • 一次深入排查:Spring Cloud Gateway TCP 连接复用导致 K8s 负载均衡失效
  • 基于 Vue3 及TypeScript 项目后的总结
  • Android下解决滑动冲突的常见思路是什么?
  • 建筑外观设计网站如何做一个门户网站
  • SQL多表查询完全指南-从JOIN到复杂关联的数据整合利器
  • Redis主从复制与哨兵集群
  • 电科金仓“异构多活架构”:破解浙江省人民医院集团化信创难题的密钥
  • 从零搭建群晖私有影音库:NasTool自动化追剧全流程拆解与远程访问协议优化实践
  • Maven项目管理:高效构建与依赖管理!