首页 > 其他分享 >使用 Sleuth 和 Zipkin 实现分布式链路追踪

使用 Sleuth 和 Zipkin 实现分布式链路追踪

时间:2024-06-01 22:32:56浏览次数:26  
标签:Sleuth 调用 zipkin import Zipkin springframework 链路 org cloud

Spring Cloud 微服务之间的调用关系,通常随着业务的不断扩张而变得越来越复杂。如果调用链路上任何一个服务出现问题或者网络超时,导致通过日志快速排查和定位问题非常困难。分布式链路追踪就可以轻松解决该场景所面临的问题,其中一种比较简单的方案是采用 Spring Cloud Sleuth

Spring Cloud Sleuth 是 Spring Cloud 体系中的一个模块,用于在整个分布式系统中跟踪一个用户请求的过程,其具有以下 4 个特点:

  • 提供链路追踪:可以很清楚的看出一个请求经过了哪些服务, 可以方便的理清服务间的调用关系
  • 性能分析:可以很方便的看到每个请求的耗时,分析出哪些服务调用比较耗时,可以对服务的扩容提供一定的提醒作用
  • 数据分析优化链路:可以很清楚的看到微服务之间的依赖关系,分析调用瓶颈,方便针对业务做一些优化措施
  • 可视化:结合 zipkin 对数据进行可视化展示,快速排查定位问题,对于微服务调用的异常,也可以在zipkpin界面上看到

本篇博客通过 Demo 介绍 Sleuth 和 Zipkin 的快速使用,在博客最后会提供源代码下载。

ZipKin 的 GitHub 地址为 https://github.com/openzipkin/zipkin


一、搭建环境

我的 CentOS7 虚拟机 ip 地址是 192.168.136.128,已经安装好了 docker 和 docker-compose

我们使用 Spring Cloud Alibaba,使用 nacos 作为注册中心,有关 nacos 的搭建可参考:https://www.cnblogs.com/studyjobs/p/18014237

在虚拟机上创建 zipkin 的目录:mkdir /data/zipkin -p 在目录中创建 docker-compose.yml 文件,内容如下:

version: '3.2'
services:
  zipkin:
    container_name: zipkin
    restart: always
    image: openzipkin/zipkin:latest
    ports:
      - "9411:9411"
    volumes:
      - /etc/localtime:/etc/localtime

之所以将虚拟机的 /etc/localtime 映射到容器内,主要是想让容器内的时区,与虚拟机的时区保持一致,我的虚拟机时区是东8区北京时间。

然后在 docker-compose.yml 目录下,运行 docker-compose up -d 启动 zipkin 可视化服务。

使用 docker-compose logs -f 可以查看 zipkin 的启动日志,可以看到 zipkin 的版本,我目前使用的是最新版本 2.23.16

打开浏览器访问 http://192.168.136.128:9411,界面展示如下:

image


二、搭建工程

创建一个名称为 springcloud_sleuth_zipkin 的工程,结构如下:

image

在 springcloud_sleuth_zipkin 父工程下包含 3 个子工程:sleuth01、sleuth02、sleuth03

这 3 个子工程的代码,基本上一样,调用关系是:sleuth01 -> sleuth02 -> sleuth03,最后 sleuth03 处理后返回最终结果。

首先看一下 springcloud_sleuth_zipkin 父工程的 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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.jobs</groupId>
    <artifactId>springcloud_sleuth_zipkin</artifactId>
    <version>1.0</version>
    <modules>
        <module>sleuth01</module>
        <module>sleuth02</module>
        <module>sleuth03</module>
    </modules>
    <packaging>pom</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.12.RELEASE</version>
    </parent>

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

    <dependencyManagement>
        <dependencies>
            <!-- 引入 springCloud 依赖-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR10</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--引入 springCloud alibaba 依赖-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.9.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <!--由于 zipkin 中已经包含了 sleuth,所以只需要引入 zipkin 依赖即可-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
</project>

由于 3 个子工程,都需要使用 sleuth 和 zipkin 的依赖包,所以就在父工程的 pom 文件中引用了,子工程就不需要再引用了。

由于 zipkin 的依赖包中,已经包含的 sleuth 的依赖包,所以这里只需要引用 zipkin 依赖包就可以了。

由于 3 个子工程的代码基本一致,都是只有 1 个接口,并通过 openfeign 进行调用,因此详细介绍一个即可,以 sleuth01 为例:

sleuth01 的 pom 文件内容如下,主要是引用 nacos 和 openfeign 的依赖包:

<?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>springcloud_sleuth_zipkin</artifactId>
        <groupId>com.jobs</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>sleuth01</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-web</artifactId>
        </dependency>
        <!--引入 nacos 客户端依赖包-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--引入 openfeign 依赖包-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.3.12.RELEASE</version>
            </plugin>
        </plugins>
    </build>
</project>

sleuth01 的 application.yml 配置文件内容如下,重点在于配置 sleuth 的跟踪数据采集率,以及 zipkin 部署的地址

server:
  port: 8091

spring:
  application:
    # 微服务的名称
    name: sleuth01
  cloud:
    nacos:
      # 配置 Nacos 的 ip 和 端口
      server-addr: 192.168.136.128:8848
      # 配置登录的 账号 和 密码
      #username: nacos
      #password: nacos
  sleuth:
    sampler:
      # 这个是跟踪日志的收集比例,1表示 100%,比例越大,越耗费性能
      # 在生产环境中,建议设置为 0.5 以下
      probability: 0.5
  zipkin:
    # sleuth 收集的日志,需要发给 zipkin 进行可视化展示,这里设置 zip 的部署地址
    base-url: http://192.168.136.128:9411

#针对具体的服务,配置使用 nacos 的负载均衡策略(随机策略)
#当前项目中接口提供者的服务名称是 sleuth02
#如果去掉以下的配置,则默认使用 ribbon 的轮训策略
sleuth02:
  ribbon:
    NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule

由于要使用 openfeign ,所以启动类上要添加 @EnableFeignClients 注解

package com.jobs;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

@Slf4j
@EnableFeignClients
@SpringBootApplication
public class App1 {
    public static void main(String[] args) {
        SpringApplication.run(App1.class, args);
        log.info("App1 已经启动...");
    }
}

定义 feign 的接口,用于远程调用 sleuth02 微服务提供的接口

package com.jobs.client;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient("sleuth02")
public interface FeignCall {

    @GetMapping("/s02/trace02")
    String getData(@RequestParam("name") String name);
}

最后在 controller 中提供接口,用于我们在浏览器上直接访问调用。

package com.jobs.controller;

import com.jobs.client.FeignCall;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/s01")
@RestController
public class S01Controller {

    @Autowired
    private FeignCall feignCall;

    @GetMapping("/trace01")
    public String Test(@RequestParam("name") String name) {
        //调用 sleuth02 服务提供的接口
        return feignCall.getData(name);
    }
}

sleuth02 的微服务,与 sleuth01 基本上一样,只不过 sleuth02 调用的是 sleuth03 的接口。

sleuth03 的接口,最终返回处理结果,其接口内容如下:

package com.jobs.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/s03")
@RestController
public class S03Controller {

    @GetMapping("/trace03")
    public String Test(@RequestParam("name") String name) {
        return "Hello " + name;
    }
}

三、验证成果

在 IDEA 中启动 3 个微服务,具体端口如下:

image

在 nacos 中也可以看到 3 个微服务已经注册成功:

image

打开浏览器访问 http://localhost:8091/s01/trace01?name=jobs 后,可以看到正常运行的结果:

image

此时查看 zipkin 的界面,我们就可以看到调用的全链路,以及整体所耗费的时间

注意:此时【持续时间】下面的条颜色是淡青色,说明调用链路没有问题。

image

点击 SHOW 按钮,我们可以看到每一步调用所耗费的时间:

image

我们可以停掉 sleuth03 服务,然后再进行调用,看看具体的效果

注意:【持续时间】下面的条颜色为淡红色(也会出现无颜色的情况),说明该调用链出现了问题

image

我们发现调用链路中没有 sleuth03 服务,点击 SHOW 按钮进入查看,在右侧提供的错误日志。

image

点击顶部菜单的【依赖】,在界面中选择合适的时间进行查询,可以看到微服务之间的依赖关系:

image

由于我们做的 demo 比较简单,只有 3 个微服务一次调用,因此展示的调用依赖关系也非常简单。

目前我们只是把追踪数据到 zipkin 所在的服务器内存中进行处理和展示,在 zipkin 的 github 上也提供了将追踪数据存储到 mysql 数据库中的方案,但是也说明了并没有针对 mysql 进行性能优化,当追踪信息累积的数据量比较大时就会出现性能问题,因此不推荐数据库存储方案。


本篇博客的源代码下载地址为:https://files.cnblogs.com/files/blogs/699532/springcloud_sleuth_zipkin.zip

标签:Sleuth,调用,zipkin,import,Zipkin,springframework,链路,org,cloud
From: https://www.cnblogs.com/studyjobs/p/18226509

相关文章

  • 2024拼多多 最新理论+实战干货,从入门到精通全链路多角度学习-7节课
    基于最新规则理论结合实际的干货课程内容:012024年多多防比价新规则破局理论课与实操课.mp40224年多多强付费第二节课基础内功.mp40324年多多强付费第三节课直通车实操.mp40424年多多强付费第一节课市场定价格段,mp40524年多多自然流第一节课市场分析-small.mp40......
  • 一站式链路追踪:阿里云的端到端解决方案
    作者:涯海炎炎夏日,当你打开外卖APP购买奶茶却发现下单失败;五一佳节,当你自驾游途中发现导航响应缓慢,频繁错过路口;深更半夜,当你辅导孩子功课,却发现GPT应用迟迟无法应答。不知你有没有想过,这些程序运行的背后到底是怎样的世界,每一次点击,每一次交互,又到底发生了什么?如果你是一名......
  • M-LAG(跨设备链路聚合)二层基础配置
    一、拓扑结构  二、接口配制S6850_1S6850_2interfaceVlan-interface999ipaddress1.1.1.1255.255.255.252#interfaceFortyGigE1/0/53portlink-modebridgeportaccessvlan999#interfaceGigabitEthernet1/0/1portlink-modebridgecomboenablefiber......
  • 数据链路层的检错与纠错
    通讯链路都不是完全理想的。比特在传输过程中可能会产生比特差错,即1可能变成0,0也可能变成11帧包含m个数据位(即报文)和r个冗余位(即校验位)。假设帧的总长度为n,则有n=m+r。包含数据和校验位的n位单元,通常称为n位码字奇偶校验\(\color{red}{奇偶校验只能检测出错误,而无......
  • 使用skywalking对k8s应用进行链路监控
    方案一、修改代码,引入jar包方案二、无侵入,使用探针自动注入到pod以下使用helm安装,提前安装helm环境1.添加SkyWalking的helm仓库helmrepoaddapache-skywalkinghttps://apache.jfrog.io/artifactory/skywalking-helm2.更新Helm仓库helmrepoupdate3.创建一个k8s命......
  • JINGWHALE ABCDE 概念模型系统设计建模法,用户画像进行场景化业务需求分析与归纳,帮你规
    JINGWHALE对此论文相关未知以及已知概念、定理、公式、图片等内容的感悟、分析、创新、创造等拥有作品著作权。未经JINGWHALE授权,禁止转载与商业使用。《一种基于概念模型思想的ABCDE系统设计建模法的研究与应用》张云龙(JINGWHALE数字科学艺术创新中心,浙江杭州,310......
  • 《计算机网络微课堂》第三章 链路层
    3.1:概述---本节课我们对数据链路层进行概述,我们首先来看看数据链路层在网络体系结构中的地位。如图所示主机H1给主机H2发送数据,中间要经过三个路由器和电话网、局域网以及广域网等多种网络。​​从五层协议原理体系结构的角度来看,主机应具有体系结构中的各个层次,而路由器......
  • 书生·浦语大模型全链路开源体系笔记
    大模型成为发展通用人工智能的重要途径专用模型专用模型:针对特定任务,一个模型解决一个问题。通用大模型:一个模型应对多种任务、多种模态。书生·浦语大模型开源历程书生·浦语2.0(InternLM2)的体系面向不同的使用需求,每个规格包含三个模型版本。7B:为轻量级的研......
  • Docker Desktop部署微软微服务Dapr(Redis+Zipkin+Placement)
    DockerDesktop部署微软微服务Dapr(Redis+Zipkin+Placement)说明系统:Windows11专业版23H2Docker:DockerDesktopv4.29.0+本文为开发环境学习和测试使用安装DaprCLI使用MSI安装程序安装每个DaprCLI的发布版本还包括一个适用于Windows的安装程序。您可以手动下......
  • 华为S5700交换机配下链路聚合
    学习目标  ·掌握接口速率的配置方法·掌握使用手动模式配置链路聚合的方法·掌握使用静态LACP模式配置链路聚合的方法·掌握在静态LACP模式下配置接口优先级的方法 拓扑图   图4.1以太网链路聚合拓扑图 场景 您是公司的网络管理员。现在公司购买了两......