微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Spring Cloud Alibaba-Sleuth+Zipkin链路追踪

一、Sleuth介绍

        SpringCloud Sleuth主要功能就是在分布式系统中提供追踪解决方。它大量借用了Google Dapper的设计, 先来了解一下Sleuth中的术语和相关概念。

Trace (一条完整链路--包含很多span(微服务接口))

        由一组Trace Id(贯穿整个链路)相同的Span串联形成一个树状结构。为了实现请求跟踪,当请求到达分布式系统的入口端点时,只需要服务跟踪框架为该请求创建一个唯一的标识(即TraceId),同时在分布式系统内部流转的时候,框架始终保持传递该唯一值,直到整个请求的返回。那么我们就可以使用该唯一标识将所有的请求串联起来,形成一条完整的请求链路。

代表了一组基本的工作单元。为了统计各处理单元的延迟,当请求到达各个服务组件的时候,也通过一个唯一标识(SpanId)来标记它的开始、具体过程和结束。通过SpanId的开始和结束时间戳,就能统计span调用时间,除此之外,我们还可以获取如事件的名称。请求信息等元数据。

Annotation

用它记录一段时间内的事件,内部使用的重要注释:

  1. csClient Send)客户端发出请求,开始一个请求的命令
  2. srServer Received)服务端接受到请求开始进行处理, srcs = 网络延迟(服务调用的时间)
  3. ssServer Send)服务端处理完毕准备发送到客户端,ss - sr = 服务器上的请求处理时间
  4. crClient Reveived)客户端接受到服务端的响应,请求结束。 cr - cs = 请求的总时间

二、Sleuth的使用

1.引入依赖

修改父工程引入Sleuth依赖

        <!--sleuth依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>

2. 启动微服务

调用之后,我们可以在控制台观察到sleuth的日志输出

其中 2a9568f2be337eac是TraceId, ab8b7a23ddaffdf5是SpanId,依次调用一个全局的TraceId,将调用链路串起来。仔细分析每个微服务的日志,不难看出请求的具体过程。

查看日志文件并不是一个很好的方法,当微服务越来越多日志文件也会越来越多,通过Zipkin可以将日志聚合,并进行可视化展示全文检索。

三、Zipkin的集成

1.Zipkin介绍

        Zipkin 是 Twitter 一个开源项目,它基于Google Dapper实现,它致力于收集服务的定时数据,以解决微服务架构中的延迟问题,包括数据的收集、存储展现、查找和我们可以使用它来收集各个服务器上请求链路的跟踪数据,并通过它提供的REST API接口来辅助我们查询跟踪数据以实现对分布式系统的监控程序,从而及时地发现系统中出现的延迟升高问题并找出系统性能瓶颈的根源

        除了面向开发的 API 接口之外,它也提供了方便的UI组件来帮助我们直观的搜索跟踪信息和分析请求链路明细,比如:可以查询某段时间内各用户请求的处理时间等。

        Zipkin 提供了可插拔数据存储方式:In-MemoryMysqLCassandra 以及 Elasticsearch

 

上图展示了 Zipkin 的基础架构,它主要由 4 个核心组件构成:

  1. Collector:收集器组件,它主要用于处理从外部系统发送过来的跟踪信息,将这些信息转换为Zipkin 内部处理的 Span 格式,以支持后续的存储、分析、展示等功能
  2. Storage:存储组件,它主要对处理收集器接收到的跟踪信息,认会将这些信息存储在内存中,我们也可以修改此存储策略,通过使用其他存储组件将跟踪信息存储到数据库中。
  3. RESTful API:API 组件,它主要用来提供外部访问接口。比如给客户端展示跟踪信息,或是外接系统访问以实现监控等。
  4. Web UI:UI 组件,基于 API 组件实现的上层应用。通过 UI 组件用户可以方便而有直观地查询和分析跟踪信息。

Zipkin 分为两端,一个是 Zipkin 服务端,一个是 Zipkin 客户端,客户端也就是微服务的应用。客户端会配置服务端的 URL 地址,一旦发生服务间的调用的时候,会被配置在微服务里面的 Sleuth 的监听器监听,并生成相应的 Trace 和 Span 信息发送给服务端。

2.ZipKin服务端安装

(1)下载的Zipkin的jar包

(2)通过命令运行jar包

通过命令行,输入下面的命令启动ZipKin Server

java -jar zipkin-server-2.12.9-exec.jar

(3)访问

通过浏览器访问 http://localhost:9411访问 

3.Zipkin客户端集成

ZipKin客户端和Sleuth的集成非常简单,只需要在微服务中添加其依赖和配置即可。

(1)在父类服务上添加依赖

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

(2)修改配置文件

properties文件这样修改:

#指定zipkin服务器所在的地址
spring.zipkin.base-url=http://localhost:9411
#不在nacos上注册zipkin
spring.zipkin.discovery-client-enabled=false
#设置zipkin对sleuth链路日志的采样比例 企业为3%
spring.sleuth.sampler.probability=1.0

yml文件这样修改

spring:
  zipkin:
    base-url: http://localhost:9411
    #不让zipkin注册到nacos
    discovery-client-enabled: false
    #设置zipkin对sleuth链路日志的采样比例  企业为3%
  sleuth:
    sampler:
      probability: 1.0

(3)访问微服务

(4)访问zipkinUI界面,观察效果

 (5)点击其中一条记录,可观察一次访问的详细线路

四、ZipKin数据持久化

        Zipkin Server认会将追踪数据信息保存到内存,但这种方式不适合生产环境。Zipkin支持将追踪数据持久化到MysqL数据库elasticsearch中。

使用MysqL实现数据持久化

1.创建数据库名为zipkin的数据库

2.创建表结构

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, 
`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' )
 ENGINE=InnoDB ROW_FORMAT=COMpressed CHaraCTER SET=utf8 COLLATE utf8_general_ci;

ALTER TABLE zipkin_spans ADD UNIQUE KEY(`trace_id_high`, `trace_id`, `id`) COMMENT 'ignore insert on duplicate'; 
ALTER TABLE zipkin_spans ADD INDEX(`trace_id_high`, `trace_id`, `id`) COMMENT 'for joining with zipkin_annotations'; 
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(`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';
 ALTER TABLE zipkin_annotations ADD INDEX(`a_key`) COMMENT 'for getTraces'; 
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 ) 
ENGINE=InnoDB ROW_FORMAT=COMpressed CHaraCTER SET=utf8 COLLATE utf8_general_ci; 
ALTER TABLE zipkin_dependencies ADD UNIQUE KEY(`day`, `parent`, `child`);

3.在启动ZipKin Server的时候,指定数据保存的MysqL的信息

java -jar zipkin-server-2.12.9-exec.jar --STORAGE_TYPE=MysqL --MysqL_HOST=127.0.0.1 --MysqL_TCP_PORT=3306 --MysqL_DB=zipkin --MysqL_USER=root --MysqL_PASS=root

原文地址:https://www.jb51.cc/wenti/3288283.html

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

相关推荐