当前位置: 代码网 > it编程>编程语言>Java > SpringCloud集成sleuth和zipkin实现微服务链路追踪的实战分享

SpringCloud集成sleuth和zipkin实现微服务链路追踪的实战分享

2025年01月01日 Java 我要评论
技术积累spring cloud sleuth介绍sleuth是spring cloud的分布式跟踪解决方案。1.span(跨度),基本工作单元。一次链路调用,创建一个span,span用一个64位i

技术积累

spring cloud sleuth介绍

sleuth是spring cloud的分布式跟踪解决方案。

在这里插入图片描述

1.span(跨度),基本工作单元。一次链路调用,创建一个span,span用一个64位id唯一标识。包括:id,描述,时间戳事件,spanld,span父id.span被启动和停止时,记录了时间信息,初始化span叫:rootspan,它的span id和trace id相等。
2.trace(跟踪),一组共享"root span”的span组成的树状结构称为 trace,trace也有一个64位id,trace中所有span共享一个trace id。类似于一颗 span 树。
3.annotation (标签),annotation用来记录事件的存在,其中,核心annotation用来定义请求的开始和结束cs(client send客户端发起请求)。客户端发起请求描述了span开始,
sr(server received服务端接到请求)。服务端获得请求并准备处理它。sr-cs=网络延迟ss(server send服务器端处理完成,并将结果发送给客户端)。表示服务器完成请求处理,响应客户端时。ss-sr=服务器处理请求的时间,
cr(client received 客户端接受服务端信息)。span结束的标识。客户端接收到服务器的响应。cr-cs=客户端发出请求到服务器响应的总时间。
其实数据结构是一颗树,从root span 开始。

工具定位

spring cloud sleuth是一个用于spring cloud应用程序的分布式追踪工具,它主要专注于在服务间传播追踪信息。

主要功能

传播追踪上下文:在服务调用间传递trace id和span id,确保整个请求链路的追踪信息保持一致。
集成日志框架:修改日志框架的配置,使得日志记录中包含trace和span的id。
与spring cloud生态集成:与spring cloud的其他组件(如ribbon、hystrix、zuul等)无缝集成。
依赖性:sleuth是为spring cloud应用程序设计的,它依赖于spring框架和spring boot。

zipkin介绍

zipkin是一款开源的分布式实时数据追踪系统(distributed tracking system),基于 google dapper的论文设计而来,由 twitter 公司开发贡献。其主要功能是聚集来自各个异构系统的实时监控数据。
工具定位
zipkin是一个分布式追踪系统,它提供了追踪数据的收集、存储、查找和展示功能。
主要功能
收集追踪数据:zipkin通过其客户端库(如brave)收集追踪数据。
存储追踪数据:支持多种存储方案,如内存、mysql、cassandra、elasticsearch等。
查询和展示:提供web界面,用于查询追踪数据,并以可视化的方式展示服务间的调用关系和延迟。
独立性:zipkin可以独立于任何应用程序或框架运行,并且可以与多种编程语言和框架集成。
zipkin 官网
https://zipkin.io/pages/quickstart.html

在这里插入图片描述

zipkin与sleuth的协作

数据收集:sleuth负责在spring cloud应用程序中生成和传播追踪数据,而zipkin负责收集这些数据。
数据展示:sleuth生成的追踪数据可以通过zipkin的web界面进行查询和展示。
集成:在spring cloud应用程序中,sleuth通常与zipkin一起使用,sleuth负责追踪信息的生成和传播,zipkin负责存储和展示。

springcloud多模块搭建

多模块微服务项目结构

在这里插入图片描述

新增父项目来管理微服务各个模块

在这里插入图片描述

在这里插入图片描述

#父模块pom必须声明
pom
新增子模块

在这里插入图片描述

zipkin server部署

由于springcloud f版本不支持自定义zipkin server,故我们采用docker镜像进行部署zipkin server。

docker pull 镜像

docker pull openzipkin/zipkin:latest

启动zipkin server

未持久化(内存):
docker run --name zipkin-server -d --restart=always -p 9411:9411 openzipkin/zipkin:latest
http://127.0.0.1:9411/zipkin/

持久化到mysql5:
docker run --name zipkin-server-mysql -d --restart=always -p 19411:9411 -e mysql_user=root -e mysql_pass=12345678 -e mysql_host=127.0.0.1 -e storage_type=mysql -e mysql_db=zipkin -e mysql_tcp_port=13306 openzipkin/zipkin:3.3
mysql dd语句如下:

https://github.com/openzipkin/zipkin/blob/master/zipkin-storage/mysql-v1/src/main/resources/mysql.sql
--
-- copyright the openzipkin authors
-- spdx-license-identifier: apache-2.0
--

create table if not exists zipkin_spans (
  `trace_id_high` bigint not null default 0 comment 'if non zero, this means the trace uses 128 bit traceids instead of 64 bit',
  `trace_id` bigint not null,
  `id` bigint not null,
  `name` varchar(255) not null,
  `remote_service_name` varchar(255),
  `parent_id` bigint,
  `debug` bit(1),
  `start_ts` bigint comment 'span.timestamp(): epoch micros used for endts query and to implement ttl',
  `duration` bigint comment 'span.duration(): micros used for minduration and maxduration query',
  primary key (`trace_id_high`, `trace_id`, `id`)
) engine=innodb row_format=compressed character set=utf8 collate utf8_general_ci;

alter table zipkin_spans add index(`trace_id_high`, `trace_id`) comment 'for gettracesbyids';
alter table zipkin_spans add index(`name`) comment 'for gettraces and getspannames';
alter table zipkin_spans add index(`remote_service_name`) comment 'for gettraces and getremoteservicenames';
alter table zipkin_spans add index(`start_ts`) comment 'for gettraces ordering and range';

create table if not exists zipkin_annotations (
  `trace_id_high` bigint not null default 0 comment 'if non zero, this means the trace uses 128 bit traceids instead of 64 bit',
  `trace_id` bigint not null comment 'coincides with zipkin_spans.trace_id',
  `span_id` bigint not null comment 'coincides with zipkin_spans.id',
  `a_key` varchar(255) not null comment 'binaryannotation.key or annotation.value if type == -1',
  `a_value` blob comment 'binaryannotation.value(), which must be smaller than 64kb',
  `a_type` int not null comment 'binaryannotation.type() or -1 if annotation',
  `a_timestamp` bigint comment 'used to implement ttl; annotation.timestamp or zipkin_spans.timestamp',
  `endpoint_ipv4` int comment 'null when binary/annotation.endpoint is null',
  `endpoint_ipv6` binary(16) comment 'null when binary/annotation.endpoint is null, or no ipv6 address',
  `endpoint_port` smallint comment 'null when binary/annotation.endpoint is null',
  `endpoint_service_name` varchar(255) comment 'null when binary/annotation.endpoint is null'
) engine=innodb row_format=compressed character set=utf8 collate utf8_general_ci;

alter table zipkin_annotations add unique key(`trace_id_high`, `trace_id`, `span_id`, `a_key`, `a_timestamp`) comment 'ignore insert on duplicate';
alter table zipkin_annotations add index(`trace_id_high`, `trace_id`, `span_id`) comment 'for joining with zipkin_spans';
alter table zipkin_annotations add index(`trace_id_high`, `trace_id`) comment 'for gettraces/byids';
alter table zipkin_annotations add index(`endpoint_service_name`) comment 'for gettraces and getservicenames';
alter table zipkin_annotations add index(`a_type`) comment 'for gettraces and autocomplete values';
alter table zipkin_annotations add index(`a_key`) comment 'for gettraces and autocomplete values';
alter table zipkin_annotations add index(`trace_id`, `span_id`, `a_key`) comment 'for dependencies job';

create table if not exists zipkin_dependencies (
  `day` date not null,
  `parent` varchar(255) not null,
  `child` varchar(255) not null,
  `call_count` bigint,
  `error_count` bigint,
  primary key (`day`, `parent`, `child`)
) engine=innodb row_format=compressed character set=utf8 collate utf8_general_ci;

持久化到es:
docker run --name zipkin-server-es -d -p 19411:9411 --restart=always -e storage_type=elasticsearch -e es_hosts=127.0.0.1:9200 openzipkin/zipkin:latest

jar运行:
curl -ssl https://zipkin.io/quickstart.sh | bash -s
java -jar zipkin.jar --storage_type=mysql --mysql_host=127.0.0.1 --mysql_tcp_port=3306 --mysql_db=zipkin --mysql_user=root --mysql_pass=12345678

我们测试选择不持久化
docker run -d -p 9411:9411 --name zipkinserver --restart=always openzipkin/zipkin
3、启动完成

在这里插入图片描述

在这里插入图片描述

springcloud 接入 sleuth 与 zipkin

pom引入依赖 (springboot2.6+)

<properties>
    <spring-cloud.version>2021.0.5</spring-cloud.version>
</properties>
<dependencies>
    <dependency>
        <groupid>org.springframework.cloud</groupid>
        <artifactid>spring-cloud-dependencies</artifactid>
        <version>${spring-cloud.version}</version>
        <type>pom</type>
        <scope>import</scope>
    </dependency>
    <dependency>
        <groupid>org.springframework.cloud</groupid>
        <artifactid>spring-cloud-starter-sleuth</artifactid>
        <version>3.1.10</version>
    </dependency>
    <dependency>
        <groupid>org.springframework.cloud</groupid>
        <artifactid>spring-cloud-sleuth-zipkin</artifactid>
        <version>3.1.10</version>
    </dependency>
</dependencies>

appilication.yml配置修改

spring:
  zipkin:
    #zipkin服务所在地址
    base-url: http://127.0.0.1:9411/
    sender:
      type: web #使用http的方式传输数据
    #配置采样百分比
    sleuth:
      sampler:
        probability: 1 # 将采样比例设置为 1.0,也就是全部都需要。默认是0.1也就是10%,一般情况下,10%就够用了
##打开debug日志
logging:
  level:
    org.springframework.web.servlet.dispatcherservlet: debug

type=web也就是通过 http 的方式发送数据到 zipkin 。
如果请求量比较大,这种方式其实性能是比较低的,一般情况下我们都是通过消息中间件来发送,比如 rabbitmq 。如果日志数据量比较大,一般推荐拥有更高吞吐量的 kafka 来进行日志推送。这种方式就是让服务将 sleuth 收集的日志推给 mq ,让 zipkin 去监控 mq 的信息,通过 mq 的队列获取到服务的信息。这样就提高了性能。

而日志的存储则可以采用mysql、 elasticsearch 对数据进行持久化,这样可以保证 zipkin 重启后,链路信息不会丢失。

增加测试链路代码

链路为:
user-service --> order-service --> finance-service
user-service增加请求入口getorderamount:

/**
 * 计算订单金额
 * @param orderid
 * @author senfel
 * @date 2024/12/9 18:25
 * @return java.lang.string
 */
@requestmapping("/getorderamount")
public string getorderamount(@requestparam(name = "orderid") string orderid) {
    return orderservice.getorderamount(orderid);
}

user-service增加feign调用order-service:

/**
 * feeservice
 * @author senfel
 * @version 1.0
 * @date 2024/12/9 18:02
 */
@feignclient(name = "order-service",fallback = orderservicefallback.class)
public interface getorderamount {

    /**
     * 获取订单金额
     * @param orderid
     * @author senfel
     * @date 2024/12/9 18:06
     * @return java.lang.string
     */
    @requestmapping(value = "/order/getorderamount",method = requestmethod.get)
    string getorderamount(@requestparam(name = "orderid") string orderid);
}

order-service增加调用入口getorderamount:

/**
 * 获取订单金额
 * @param orderid
 * @author senfel
 * @date 2024/12/9 18:06
 * @return java.lang.string
 */
@requestmapping(value = "/getorderamount",method = requestmethod.get)
public string getorderamount(@requestparam(name = "orderid") string orderid){
    return financeservice.getfee(orderid);
}

order-service增加feign调用finance-service:

/**
 * financeservice
 * @author senfel
 * @version 1.0
 * @date 2024/12/9 18:10
 */
@feignclient(name = "finance-service",fallback = financeservicefallback.class)
public interface financeservice {

    /**
     * 获取费用
     * @param orderid
     * @author senfel
     * @date 2024/12/9 18:12
     * @return java.lang.string
     */
    @requestmapping(value = "/finance/getfee",method = requestmethod.get)
    string getfee(@requestparam(name = "orderid") string orderid);
}

finance-service增加请求入口getfee:

/**
 * 获取费用
 * @param orderid
 * @author senfel
 * @date 2024/12/9 18:12
 * @return java.lang.string
 */
@requestmapping(value = "/getfee",method = requestmethod.get)
public string getfee(@requestparam(name = "orderid") string orderid) {
    return "100";
}

调用微服务进行验证

启动微服务调用getorderamount()

在这里插入图片描述

进入zipkin界面查看请求调用链路和各个阶段耗时

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

至此,我们已经完微服务链路追踪实战.。

以上就是springcloud集成sleuth和zipkin实现微服务链路追踪的实战分享的详细内容,更多关于springcloud sleuth和zipkin链路追踪的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com