【Spring Cloud 七】Sleuth+Zipkin 链路追踪

news2024/11/22 18:15:27

Sleuth链路追踪

  • 系列博客
  • 背景
  • 一、 什么是链路追踪
  • 二、为什么要有链路追踪
  • 三、Sleuth与Zipkin
    • Sleuth
    • Zipkin
    • Sleuth和Zipkin的关系是什么?
  • 四、使用Sleuth+zipkin进行链路追踪
    • 4.1下载zipkin
    • 4.2案例说明
      • 项目代码
        • 服务提供者
          • pom文件
          • yml配置文件
          • 项目启动类
          • controller
        • 抽离出来的common-api模块
        • pom文件
          • feign
          • hystrix
        • 服务消费者
          • pom文件
          • yml配置文件
            • 启动类
          • controller
      • 启动服务

系列博客

【Spring Cloud一】微服务基本知识
【Spring Cloud 三】Eureka服务注册与服务发现
【Spring Cloud 四】Ribbon负载均衡
【Spring Cloud 五】OpenFeign服务调用
【Spring Cloud 六】Hystrix熔断

背景

目前开发的项目正是使用sleuth+zipkin的方式进行的链路追踪,为了对sleuth+zipkin这个技术点加深认识。博主对其进行了理论学习和实践。

一、 什么是链路追踪

链路追踪就是追踪微服务的调用路径。

二、为什么要有链路追踪

随着业务越来越复杂,以及微服务架构的兴起,在微服务架构中,一个由客户端发起的请求在后端往往会经过不同的服务节点调用协同完成一个请求。当请求出现问题(不可用,请求时间长等等),我们很难定位到具体是哪一个或者哪几个服务出现了问题,而链路追踪能够帮助我们快速精准的定位到是哪一个服务出现了问题。

三、Sleuth与Zipkin

Sleuth

Sleuth是Spring Cloud提供的一款分布式系统跟踪解决方案,Sleuth可以自动为每一个请求添加唯一的跟踪标识,以便在整个请求链路中跟踪与识别请求。

学习Sleuth之前必须了解它的几个概念,它们是实现链路追踪的基础:

  1. Trace:它代表一个完整的请求链路。每个Trace都有一个全局唯一的Trace ID用于表示整个请求的跟踪信息。
  2. Span:Span是Trace的组成部分,它代表请求链路中的一个环节,一个请求可能经过多个服务,每个服务处理请求的过程就是一个Span。每个Span都有一个唯一的ID,用于标识该环节的跟踪信息。
  3. Trace ID(跟踪ID):
    Trace ID是全局唯一的标识,用于连接整个请求链路。在Sleuth中,Trace ID会被添加到请求的Header中,并在请求经过多个服务时一直传递下去。
  4. Span ID(跨度ID):
    Span ID是用于标识单个Span的唯一标识符。它会随着请求的流转在不同的服务之间传递,用于表示请求链路中的每个环节。
  5. Parent Span ID(父跨度ID):
    Parent Span ID是用于标识当前Span的上一级Span。通过这种方式,Span之间就可以建立起父子关系,形成完整的请求链路。

一条完整的链路请求(Trace):
在这里插入图片描述

Zipkin

Zipkin是一个开源的分布式跟踪系统,它收集并存储跨多个服务的请求链路数据,并提供支援的Web界面吗用于查看和分析这些数据。帮助开发人员快速定位和解决分布式系统中的性能问题。

zipkin的运行关系图:
图片来自官网:https://zipkin.io/pages/architecture.html
zipkin的大致运行流程:

集成zipkin客户端服务通过几种传输(http,kafka,scribe)之一将数据发送到zipkin服务端,Collector将跟踪数据保存到Storage,之后Storage通过API向UI提供数据。

部分名词解释:
1.InstrumentedClient:使用了Zipkin客户端工具的服务调用方

2.InstrumentedServer:使用了Zipkin客户端工具的服务提供方

3.Non-InstrumentedServer:未使用Zipkin客户端工具的服务提供方

Sleuth和Zipkin的关系是什么?

Sleuth和Zipkin通常一起使用来实现分布式系统的请求链路跟踪和性能监控Sleuth主要负责为每个请求添加唯一的跟踪标识,并将跟踪信息传递给下游服务而Zipkin主要负责负责收集和存储这些跟踪信息,并通过可视化界面展示整个请求链路的信息,包括请求的时间、调用的顺序以及每个调用的耗时等

补充:其实完全可以单独使用Zipkin进行链路追踪,但是为什么大多数都选择使用Sleuth+Zipkin?

  1. Sleuth的集成很便捷,通过添加依赖和配置,应用程序能够自动实现请求跟踪。
  2. 集成更多功能,Sleuth不仅仅生成和传递跟踪信息,它还提供了其他一些功能,如与日志集成、自定义采样率、整合Span的定制等。
  3. 多语言支持,Sleuth不仅仅生成和传递跟踪信息,它还提供了其他一些功能,如与日志集成、自定义采样率、整合Span的定制等。我们可以实现全链路跟踪
  4. 对Spring Cloud生态的更好支持。

四、使用Sleuth+zipkin进行链路追踪

4.1下载zipkin

Spring Cloud从F版本之后可以不需要自己构建Zipkin服务了,只需要调用jar就可以。
下载Zipkin jar包 https://repo1.maven.org/maven2/io/zipkin/zipkin-server/2.24.3/在这里插入图片描述

下载之后直接在本机运行 java -jar +jar包所在路径
在这里插入图片描述

4.2案例说明

该项目总共有四个服务,一个Zipkin服务端、一个Eureka服务端、一个服务提供者,一个服务消费者。

如何搭建Eurka服务可以访问这篇博客【Spring Cloud 三】Eureka服务注册与服务发现

项目代码

服务提供者

pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>feign-project</artifactId>
        <groupId>com.wangwei</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>order-center</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.wangwei</groupId>
            <artifactId>common-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
yml配置文件
server:
  port: 8080

spring:
    application:
      name: order-service

    zipkin:
      base-url: http://localhost:9411
    sleuth:
      sampler:
        probability: 1 #配置采样率 默认的采样比例为0.1 即10%,所设置的值介于0到1之间,1表示全部采集
        rate: 10  #为了使用速率限制采样器,选择每秒间隔接收的trace量,最小数字为0,最大值为2,147,483,647(最大int) 默认为10
eureka:
  client:
    service-url: #??????
      defaultZone: http://localhost:8761/eureka
    register-with-eureka: true #设置为fasle 不往eureka-server注册
    fetch-registry: true #应用是否拉取服务列表到本地
    registry-fetch-interval-seconds: 10 #为了缓解服务列表的脏读问题,时间越短脏读越少 性能相应的消耗回答


  instance: #实例的配置
    instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port}
    hostname: localhost #主机名称或者服务ip
    prefer-ip-address: true #以ip的形式显示具体的服务信息
    lease-renewal-interval-in-seconds: 10 #服务实例的续约时间间隔


项目启动类
@SpringBootApplication
@EnableEurekaClient
public class OrderServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class,args);
    }
}
controller
@RestController
public class OrderController  {

    @GetMapping("order/getOrderByUserId/{id}")
    Order getOrderByUserId (@PathVariable("id")Integer id){
        System.out.println(id);
        Order order=Order.builder()
                .name("青椒肉丝盖饭")
                .price(15D)
                .orderId(1)
                .build();
        return order;
    }



}

抽离出来的common-api模块

pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>feign-project</artifactId>
        <groupId>com.wangwei</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>common-api</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.wangwei</groupId>
            <artifactId>project-domain</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
        </dependency>

    </dependencies>

</project>
feign
@FeignClient(value = "order-service",fallback = UserOrderFeignHystrix.class)
public interface UserOrderFeign {

    @GetMapping("order/getOrderByUserId/{id}")
    Order getOrderByUserId (@PathVariable("id")Integer id);

}

hystrix
@Component
public class UserOrderFeignHystrix implements UserOrderFeign {
    /**
     * 一般远程调用的熔断可以直接返回null
     * @param id
     * @return
     */
    @Override
    public Order getOrderByUserId(Integer id) {
        return null;
    }
}

服务消费者

pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>feign-project</artifactId>
        <groupId>com.wangwei</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>user-center</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <!--暴露自身检查端点-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>com.wangwei</groupId>
            <artifactId>common-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>

</project>
yml配置文件
server:
  port: 8081

spring:
    application:
      name: user-service
    zipkin:
      base-url: http://localhost:9411
    sleuth:
      sampler:
        probability: 1 #配置采样率 默认的采样比例为0.1 即10%,所设置的值介于0到1之间,1表示全部采集
        rate: 10  #为了使用速率限制采样器,选择每秒间隔接收的trace量,最小数字为0,最大值为2,147,483,647(最大int) 默认为10


eureka:
  client:
    service-url: #??????
      defaultZone: http://localhost:8761/eureka
    register-with-eureka: true #设置为fasle 不往eureka-server注册
    fetch-registry: true #应用是否拉取服务列表到本地
    registry-fetch-interval-seconds: 10 #为了缓解服务列表的脏读问题,时间越短脏读越少 性能相应的消耗回答


  instance: #实例的配置
    instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port}
    hostname: localhost #主机名称或者服务ip
    prefer-ip-address: true #以ip的形式显示具体的服务信息
    lease-renewal-interval-in-seconds: 10 #服务实例的续约时间间隔
feign:
  hystrix:
    enabled: true #开启熔断
management:
  endpoints:
    web:
      exposure:
        include: '*'




启动类
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class,args);
    }
}
controller
@RestController
public class UserController {

    @Autowired
    private UserOrderFeign userOrderFeign;

    @GetMapping("findOrder")
    public Order findOrder(){
        return userOrderFeign.getOrderByUserId(1);
    }

}

启动服务

先启动Eureka服务端在启动zipkin服务端,再启动服务提供者最后启动服务消费者。

访问zipkin服务端:
在这里插入图片描述
服务消费者调用服务提供者之后再次访问zipkin服务端
在这里插入图片描述

查看详细信息
在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/841301.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android network — iptables四表五链

Android network — iptables四表五链 1. iptables简介2. iptables的四表五链2.1 iptables流程图2.2 四表2.3 五链2.4 iptables的常见情况 3. NAT工作原理3.1 BNAT3.2 NAPT 4. iptables配置 本文主要介绍了iptables的基本工作原理和四表五链等基本概念以及NAT的工作原理。 1. i…

MyBatis-Flex 一个优雅的 MyBatis 增强框架

文章目录 网站MyBatis-Flex 是什么特征1、很轻量2、只增强3、高性能4、更灵动 快速开始hello world&#xff08;原生&#xff09;QueryWrapper 示例select *select columnsselect functionswherewhere 动态条件 1where 动态条件 2where 自动忽略 null 值where selectexists, no…

AlmaLinux 9 安装 Go 1.20

AlmaLinux 9 安装 Golang 1.20 1. 下载 go 安装包2. 安装 go3. 配置环境变量4. 确认 go 版本 1. 下载 go 安装包 访问 https://go.dev/dl/&#xff0c;下载你想安装的版本&#xff0c;比如 go1.20.7.linux-amd64.tar.gz&#xff0c; 2. 安装 go (可选)删除旧版本&#xff0c;…

检查网站是HTTP那种协议与获取域名的ipv6地址

前言 最近在做HTTPS的应用&#xff0c;可能需要使用ipv6的地址做SLB&#xff0c;但是怎么检查配置正确&#xff0c;总不能每次都看日志吧&#xff0c;实际上客户端也很容易查看&#xff0c;总结工作经验。 检查HTTP协议版本 笔者想到了使用浏览器方式&#xff0c;或者抓包&a…

div 按钮和 button 按钮

我们通常可以通过 HTML 元素结合需求的样式作为按钮触发一些事件&#xff0c;但原始 button 标签其实内置了许多功能&#xff0c;并且可以通过一些方法&#xff0c;一键清楚默认样式&#xff0c;从而定制需求样式。 首先是原始的 button 标签和 div 标签 作为按钮时的效果展示…

【N32L40X】学习笔记14-在RT-thread系统中读取eeprom数据

eeprom 说明 eeprom介绍 AT24C01A&#xff0c;1K串行EEPROM&#xff1a;内部组织16页8字节&#xff0c;1K需要一个7位数据字地址进行随机字寻址。AT24C02,2K串行EEPROM&#xff1a;内部组织32页8字节&#xff0c;2K需要一个8位数据字地址进行随机字寻址。AT24C04,4K串行EEPRO…

JDK动态代理的原理解析、代码实现

代理就像是&#xff1a;买家(客户端)——销售(代理对象)——工厂(目标) 买家不用直接去工厂买&#xff0c;而是直接通过销售就可以购买到&#xff0c;假设工厂生产的是杯子&#xff0c;那么工厂只需要提供杯子&#xff0c;而销售在不改变杯子的生产过程的情况下对杯子进行包装设…

C语言单链表OJ题(较难)

一、链表分割 牛客网链接 题目描述&#xff1a; 现有一链表的头指针 ListNode* pHead&#xff0c;给一定值x&#xff0c;编写一段代码将所有小于x的结点排在其余结点之前&#xff0c;且不能改变原来的数据顺序&#xff0c;返回重新排列后的链表的头指针。 思路&#xff1a;…

idea如何开启远程调试

一&#xff1a;打包需要部署的jar包上传到服务器 二&#xff1a;服务器&#xff08;开启远程调试接口&#xff09; nohup java -jar -Xdebug -Xrunjdwp:transportdt_socket,servery,suspendn,address8453 xxx.jar > xxx.log 2>&1 & 三&#xff1a; idea配置rem…

【Linux】Linux下的一些系统文件详细介绍总结

一&#xff0c;~/.bashrc文件 简介 .bashrc 文件是 Linux 系统中的一个脚本文件&#xff0c;其主要作用是在用户登录 Shell 时自动执行一系列的命令和设置环境变量。它通常位于用户的家目录下&#xff0c;文件名为 ".bashrc"&#xff0c;是每个用户都可以修改的个性化…

QtWebApp开发https服务器,完成客户端与服务器基于ssl的双向认证,纯代码操作

引言&#xff1a;所谓http协议&#xff0c;本质上也是基于TCP/IP上服务器与客户端请求和应答的标准&#xff0c;web开发中常用的http server有apache和nginx。Qt程序作为http client可以使用QNetworkAccessManager很方便的进行http相关的操作。Qt本身并没有http server相关的库…

2023年实验班招生考试题解

比赛连接&#xff1a;传送门 密码&#xff1a;2023qsb A.Zlzs problem(Easy Version) 题目描述&#xff1a; This is the easy version of this problem. The only difference between the easy and hard versions is the constraints on n and m. So I wont even take a g…

1、Spark SQL 概述

1、Spark SQL 概述 Spark SQL概念 Spark SQL is Apache Spark’s module for working with structured data. 它是spark中用于处理结构化数据的一个模块 Spark SQL历史 Hive是目前大数据领域&#xff0c;事实上的数据仓库标准。 Shark&#xff1a;shark底层使用spark的基于…

项目中使用git vscode GitHubDesktopSetup-x64

一、使用git bash 1.使用git bash拉取gitee项目 1.在本地新建一个文件夹&#xff08;这个文件夹是用来存放从gitee上拉下来的项目的&#xff09; 2.在这个文件夹右键选择 git bash here 3.输入命令 git init (创建/初始化一个新的仓库) 4.输入命令 git remote add origin …

opencv基础41-图像梯度-sobel算子详解cv2.Sobel()(边缘检测基础)

图像梯度是用于描述图像变化率的概念。在图像处理中&#xff0c;梯度指的是图像中每个像素的灰度值变化速率或方向。它常用于边缘检测和图像特征提取。 一维图像的梯度表示为函数 f(x) 的导数&#xff0c;而在二维图像中&#xff0c;梯度是一个向量&#xff0c;包含两个分量&am…

《HeadFirst设计模式(第二版)》第六章代码——命令模式

代码文件目录&#xff1a; Command package Chapter6_CommandPattern.Command;/*** Author 竹心* Date 2023/8/6**/public interface Command {public void execute();public void undo();//撤销该指令 }CeilingFan package Chapter6_CommandPattern.ElectricAppliance;/*** …

阿里云快速部署开发环境 (Apache + Mysql8.0+Redis7.0.x)

本文章的内容截取于云服务器管理控制台提供的安装步骤&#xff0c;再整合前人思路而成&#xff0c;文章末端会提供原文连接 ApacheMysql 8.0部署MySQL数据库&#xff08;Linux&#xff09;步骤一&#xff1a;安装MySQL步骤二&#xff1a;配置MySQL步骤三&#xff1a;远程访问My…

协议,序列化,反序列化,Json

文章目录 协议序列化和反序列化网络计算器protocol.hppServer.hppServer.ccClient.hppClient.cclog.txt通过结果再次理解通信过程 Json效果 协议 协议究竟是什么呢&#xff1f;首先得知道主机之间的网络通信交互的是什么数据&#xff0c;像平时使用聊天APP聊天可以清楚&#x…

【网络编程】利用套接字实现一个简单的网络通信(UDP实现聊天室 附上源码)

网络编程套接字 &#x1f41b;预备知识&#x1f98b;理解源IP地址和目的IP地址&#x1f40c;认识端口号&#x1f41e; 理解 "端口号" 和 "进程ID"&#x1f41c;简单认识TCP协议&#x1f99f;简单认识UDP协议&#x1f997; 什么是网络字节序 &#x1f577;相…

MySQL的关键指标及采集方法

MySQL 是个服务&#xff0c;所以我们可以借用 Google 四个黄金指标的思路来解决问题。 1、延迟 应用程序会向 MySQL 发起 SELECT、UPDATE 等操作&#xff0c;处理这些请求花费了多久&#xff0c;是非常关键的&#xff0c;甚至我们还想知道具体是哪个 SQL 最慢&#xff0c;这样…