SpringCloud 之 Zipkin + Sleuth 服务链路追踪搭建与讲解

前言

Zipkin: 负责接收 Sleuth 发来的跟踪数据,进行存储,UI 可视化。
Sleuth: 微服务跟踪(Sleuth)其实是一个工具,它在整个分布式系统中能跟踪一个用户请求的过程(包括数据采集,数据传输,数据存储,数据分析,数据可视化),捕获这些跟踪数据,就能构建微服务的整个调用链的视图,这是调试和监控微服务的关键工具。

基本概念

Span(跨度): 基本工作单元。我将它理解成一个个的事件节点,它还包含:描述,时间戳等。
Trace(跟踪): Span 组成的树状结构称为 TraceTrace 中的所有 Span 都共享该 Trace 的ID。
Annotation(标注): Annotation 用来记录事件的存在,其中核心 Annotation 用来定义请求的开始和结束。

  • cs(Client Sent): 客户端发起一个请求,这个注释指示了一个 Span 的开始。
  • sr(Server Received): 服务端接收请求并开始处理它,如果用 sr 时间戳减去 cs 时间戳便能看出有多少网络延迟。
  • ss(Server Sent): 注释请求处理完成(响应已发送给客户端),如果用 ss 时间戳减去 sr 时间戳便可得出服务端处理请求耗费的时间。
  • cr(Client Received): 预示了一个 Span 的结束,客户端成功地接收到了服务端的响应,如果用 cr 时间戳减去 cs 时间戳便可得出客户端从服务端获得响应所需耗费的整个时间。

Zipkin 安装

下载 Zipkin-Server.jar

wget -O zipkin.jar 'https://search.maven.org/remote_content?g=io.zipkin.java&a=zipkin-server&v=LATEST&c=exec'

或者手动下载:Zipkin-Server

启动 Zipkin 并持久化数据到数据库

PS:Zipkin 默认存储在内存里的,即浪费内存又存在宕机丢失数据的隐患。如果知识跑着玩下,可以直接 java -jar zipkin.jar 直接启动即可

建表

官方:mysql.sql

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;

启动

参考:官方文档

下面我给出我启动的示例:

  • --STORAGE_TYPE=mysql:类别为 mysql
  • --MYSQL_HOST=127.0.0.1:设置数据库 Host
  • --MYSQL_TCP_PORT=7000:设置数据库端口号
  • --MYSQL_DB=zipkin:设置库名
  • --MYSQL_USER=root:数据库账号
  • --MYSQL_PASS=123456:数据库密码
java -jar zipkin.jar --STORAGE_TYPE=mysql --MYSQL_HOST=127.0.0.1 --MYSQL_TCP_PORT=7000 --MYSQL_DB=zipkin --MYSQL_USER=root --MYSQL_PASS=123456

访问 Zipkin

默认端口为 9411

http://localhost:9411/zipkin/

在这里插入图片描述

客户端配置

即需要被追踪的服务新增配置,使得他的调用信息能够发送到 Zipkin Server

加注解

<!-- sleuth + zipkin -->
 <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-sleuth-zipkin</artifactId>
 </dependency>

加配置

spring:
  # zipkin 配置
  zipkin:
    base-url: http://localhost:9411/ # zipkin服务器的地址
    sender:
      type: web  # 设置使用http的方式传输数据
  # sleuth 配置
  sleuth:
    sampler:
      probability: 1 # 设置抽样采集为100%,默认为0.1,即10%

基本使用

查找

UI 界面:
在这里插入图片描述
点击一个请求:
可以看到中间经历了哪些的事件,比如:可以看到 feign-demo 在发送请求到 service-a 前还经历了一层断路器 Hystrix,因此我们知道,从这里开始断路器开始监控发送给 service-a 的请求,如果这个请求挂了,就进行断路。
在这里插入图片描述点击一个 Span 详情:
在这里插入图片描述
可以看到更加详细的调用相求,内容都看得懂,就不多介绍了
在这里插入图片描述

依赖

可以看到调用的链路
在这里插入图片描述
点击其中一个节点,比如 feign-demo
在这里插入图片描述
点击 Zuul 看看里面的信息

可以看到我调用了 4 次,还没有失败的
在这里插入图片描述

请求失败

来看看如果调用失败的情况,这里我把 service-a 服务停止了,因此调用失败,feign 进行了降级处理
在这里插入图片描述
Zipkin-Server 这也可以看到服务调用出现了问题
在这里插入图片描述
在这里插入图片描述
这里由于调用失败,所以异常由自己来处理
在这里插入图片描述
点击进去,可以看到失败的次数,我刚调用了两次,因此失败了两次
在这里插入图片描述

发布了108 篇原创文章 · 获赞 416 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/qq_37143673/article/details/105110926