查看原文
其他

分布式链路跟踪 Sleuth 与 Zipkin【Finchley 版】

dqqzj SpringForAll社区 2020-10-17

Spring Cloud Sleuth

Span是基本的工作单位。 例如,发送 RPC是一个新的跨度,就像向RPC发送响应一样。 跨度由跨度唯一的64位ID和跨度所包含的另一个64位ID标识。 Spans还有其他数据,例如描述,键值注释,导致它们的跨度的ID以及进程ID(通常为IP地址)。 跨度启动和停止,并且他们跟踪他们的时间信息。 一旦你创建了一个跨度,你必须在将来某个时候停止它。 一组Spans形成一个叫做Trace的树状结构。 例如,如果您正在运行分布式大数据存储,则跟踪可能由放入请求组成。

一般的,一个分布式服务跟踪系统主要由三部分构成:数据收集数据存储数据展示

根据系统大小不同,每一部分的结构又有一定变化。譬如,对于大规模分布式系统,数据存储可分为实时数据和全量数据两部分,实时数据用于故障排查(Trouble Shooting),全量数据用于系统优化;数据收集除了支持平台无关和开发语言无关系统的数据收集,还包括异步数据收集(需要跟踪队列中的消息,保证调用的连贯性),以及确保更小的侵入性;数据展示又涉及到数据挖掘和分析。虽然每一部分都可能变得很复杂,但基本原理都类似。

服务追踪的追踪单元是从客户发起请求(request)抵达被追踪系统的边界开始,到被追踪系统向客户返回响应(response)为止的过程,称为一个 trace。每个 trace 中会调用若干个服务,为了记录调用了哪些服务,以及每次调用的消耗时间等信息,在每次调用服务时,埋入一个调用记录,称为一个 span。这样,若干个有序的 span 就组成了一个 trace。在系统向外界提供服务的过程中,会不断地有请求和响应发生,也就会不断生成 trace,把这些带有 span 的 trace 记录下来,就可以描绘出一幅系统的服务拓扑图。附带上 span 中的响应时间,以及请求成功与否等信息,就可以在发生问题的时候,找到异常的服务;根据历史数据,还可以从系统整体层面分析出哪里性能差,定位性能优化的目标。

Spring Cloud Sleuth 为服务之间调用提供链路追踪。通过 Sleuth 可以很清楚的了解到一个服务请求经过了哪些服务,每个服务处理花费了多长。从而让我们可以很方便的理清各微服务间的调用关系。此外 Sleuth 可以帮助我们:

耗时分析: 通过 Sleuth 可以很方便的了解到每个采样请求的耗时,从而分析出哪些服务调用比较耗时; 可视化错误: 对于程序未捕捉的异常,可以通过集成 Zipkin 服务界面上看到; 链路优化: 对于调用比较频繁的服务,可以针对这些服务实施一些优化措施。 Spring Cloud Sleuth 可以结合 Zipkin,将信息发送到 Zipkin,利用 Zipkin 的存储来存储信息,利用 Zipkin UI 来展示数据。

这是 Spring Cloud Sleuth 的概念图:每个 color的颜色表示一个 span(有七个 spans - 从A到G)。 考虑以下说明:

  1. Trace Id = X

  2. Span Id = D

  3. Client Sent

本说明指出当前的跨度(span)将跟踪标识设置为X,跨度标识设置为D.此外还发生了客户端已发送事件。

下图显示了跨度(span)的父子关系:

Zipkin

Zipkin 是 Twitter 的一个开源项目,它基于 Google Dapper 实现,它致力于收集服务的定时数据,以解决微服务架构中的延迟问题,包括数据的收集、存储、查找和展现。 我们可以使用它来收集各个服务器上请求链路的跟踪数据,并通过它提供的 REST API 接口来辅助我们查询跟踪数据以实现对分布式系统的监控程序,从而及时地发现系统中出现的延迟升高问题并找出系统性能瓶颈的根源。除了面向开发的 API 接口之外,它也提供了方便的 UI 组件来帮助我们直观的搜索跟踪信息和分析请求链路明细,比如:可以查询某段时间内各用户请求的处理时间等。 Zipkin 提供了可插拔数据存储方式:In-Memory、MySql、Cassandra 以及 Elasticsearch。接下来的测试为方便直接采用 In-Memory 方式进行存储,生产推荐 Elasticsearch。

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

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

快速上手

Zipkin 分为两端,一个是 Zipkin 服务端,一个是 Zipkin 客户端,客户端也就是微服务的应用。 客户端会配置服务端的 URL 地址,一旦发生服务间的调用的时候,会被配置在微服务里面的 Sleuth 的监听器监听,并生成相应的 Trace 和 Span 信息发送给服务端。 发送的方式主要有两种,一种是 HTTP 报文的方式,还有一种是消息总线的方式如 RabbitMQ。

不论哪种方式,我们都需要:

一个 Eureka 服务注册中心,这里我们就用之前的eureka项目来当注册中心。一个 Zipkin 服务端。

Zipkin服务端

  1. <dependency>

  2.    <groupId>io.zipkin.java</groupId>

  3.    <artifactId>zipkin-server</artifactId>

  4. </dependency>

  5. <dependency>

  6.    <groupId>io.zipkin.java</groupId>

  7.    <artifactId>zipkin-autoconfigure-ui</artifactId>

  8. </dependency>

application.yml

  1. spring:

  2.  application:

  3.    name: zipkin-server

  4. server:

  5.  port: 9411

看起来似乎很简单,不过springboot2.x过后更简单!关于 Zipkin 的服务端,在使用 Spring Boot 2.x 版本后,官方就不推荐自行定制编译了,反而是直接提供了编译好的 jar 包来给我们使用,详情参考连接如果你的jdk是1.8+可以使用如下方式:

  1. $ curl -sSL https://zipkin.io/quickstart.sh | bash -s

  2. $ java -jar zipkin.jar

如果你的是docker部署请:

  1. docker run -d -p 9411:9411 openzipkin/zipkin

Zipkin客户端

导入核心依赖:

  1. <dependency>

  2.    <groupId>org.springframework.cloud</groupId>

  3.    <artifactId>spring-cloud-starter-zipkin</artifactId>

  4. </dependency>

spring-cloud-starter-zipkin依赖内部包含了两个依赖,等于同时引入了 spring-cloud-starter-sleuthspring-cloud-sleuth-zipkin两个依赖。名字特别像,注意区分。

我的springgateway的配置文件 application.yml

  1. ## SERVER

  2. server:

  3.  port: 8764

  4. management:

  5.  server:

  6.    port: 9275

  7.  endpoints:

  8.    web:

  9.      exposure:

  10.        include: "*"

  11.      base-path: /actuator

  12.      path-mapping:

  13.        health: /healthcheck

  14.        info:  /infocheck

  15. eureka:

  16.  instance:

  17.    hostname: localhost

  18.    health-check-url-path: ${management.endpoints.web.base-path}${management.endpoints.web.path-mapping.health}

  19.    status-page-url-path: ${management.endpoints.web.base-path}${management.endpoints.web.path-mapping.info}

  20.  client:

  21.    service-url:

  22.      defaultZone: http://localhost:8763/eureka/

  23.  server:

  24.    renewal-percent-threshold: 0.8

  25. spring:

  26.  application:

  27.    name: gateway #1

  28.  zipkin:

  29.    base-url: http://localhost:9411 #2

  30.  sleuth:

  31.    sampler:

  32.      probability: 1.0 #3

指定项目名称可以方便的标记应用,在之后的监控页面可以看到这里的配置名称

指定zipkin的服务端,用于发送链路调用报告

采样率,值为[0,1]之间的任意实数,顾名思义,这里代表100%采集报告。

总结:

本篇文章参考官网讲解了一下 SpringCloudSleuth实现链路监控的一些知识点,以及一些简单的入门使用,最重要的是注意版本是 Springboot2.x,官方已经推荐使用它自己的 zipkin服务端的jar包了,尽量别自行修改代码,否则出现问题不好解决!

参考资料

Spring Cloud Sleuth官方资料

http://cloud.spring.io/spring-cloud-sleuth/single/spring-cloud-sleuth.html#_distributed_tracing_with_zipkin

openzipkin/zipkin

https://github.com/openzipkin/zipkin

spring4all社区资料【使用Spring Cloud Sleuth实现链路监控】

http://www.spring4all.com/article/156

推荐:Dubbo x Cloud Native 服务架构长文总结(很全)

上一篇:SpringCloudGateway【Finchley 版】上的监控

关注公众号

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存