spring-cloud sleuth 链路追踪

  • 添加跟踪依赖 ,日志信息存在跟踪信息

 

如何为上面的trace1和trace2添加服务跟踪功能呢?SpringCloudSleuth对于此进行封装,使得我们为应用增加服务跟踪能力的操作非常简单,满足前面所说设计目标(低入侵,应用透明),只需在trace1和trace2的pom.xml依赖管理中增加Spring-cloud-starter-sleuth依赖即可,具体如下所示:

 

<dependency>

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

         <artifactId>spring-cloud-starter-sleuth</artifactId>

     </dependency>

 

添加sleuth依赖后,分别重启trace1和trace2,再次通过浏览器或者postman调用http://localhost:8080/trace1,可以返回trace2相应接口的内容,同时我们看到控制台日志已经存在跟踪信息,微服务应用trace1和trace2的日志信息具体如下图所示:

 

 

从上面的控制台输出内容中,我们看到多出了一些形如[trace1,454445a6a7d9ea44,912a7c66c17214e0,false]的日志信息,而这些元素正是实现分布式服务跟踪的重要组成部分,它们的含义分别如下所示:

 

 

第一个值:trace1,它表示应用的名称,也就是配置文件spring.application.name的值。

第二个值:454445a6a7d9ea44,它是SpringCloudSleuth生成的一个ID,称为Trace ID,它用来标识一条请求链路,一条请求链路中包含一个Trace ID,多个Span ID。

第三个值:912a7c66c17214e0,它是SpringCloudSleuth生成的另外一个ID,称为Span ID,它表示一个基本的工作单元,比如发送一个http请求。

第四个值:false,表示是否要将该信息输出到Zipkin等服务中来收集和展示。

 

上面四个值中的Trace ID 和Span ID是SpringCloudSleuth实现分布式服务跟踪的核心。在一次服务请求链路的调用过程中,会保持并传递同一个Trace ID,从而将整个分布于不同微服务进程中的请求跟踪信息串联起来。例如,在一次前端请求链路中,上面trace1和trace2的Trace ID是相同的。

 

  • 跟踪原理

 

 

分布式服务跟踪系统主要包括下面三个关键点:

 

(1)Trace:它是由一组有相同Trace ID的Span串联形成一个树状结构。为了实现请求跟踪,当请求请求到分布式系统的入口端点时,只需要服务跟踪框架为该请求创建一个唯一的跟踪标识(即前文提到的Trace ID),同时在分布式系统内部流转的时候,框架始终保持传递该唯一标识,直到返回请求为止,我们通过它将所有请求过程中的日志关联起来;

 

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

 

 

(3)Annotation:它用于记录一段时间内的事件。内部使用的最重要的注释是:

 

  • cs (Client Send):客户端发出请求,为开始跨度

  • sr (Server Received):服务器已收到请求并开始处理。timestampsr - timestampcs =网络延迟。

  • ss (Server Send):服务器处理完毕准备发送到客户端。timestampss - timestampsr =服务器上的请求处理时间。

  • cr (Client Received):客户端接收到服务器响应,为跨度结束。客户端已成功接收到服务器的响应。timestampcr - timestampcs =请求的总时间。


以下是在使用Sleuth的两个微服务之间的调用中请求的行为方式,除了生成唯一标识符并将其添加到应用程序日志之外,还需要在作为请求的一部分的微服务器之间正确传播它们。

 

 

  • 抽样收集

 

我们在对接分析系统时就会碰到一个问题:分析系统在收集跟踪信息的时候,需要收集多少跟踪信息才合适呢?生产环境与开发环境跟踪信息收集比例应该不一致,我们是否可以调整呢?同时,不同业务系统收集比例可能也不一样。

 

理论上来说,我们收集的跟踪信息越多就可以越好反映出系统的实际运行情况,并给出更精确的预警和分析。但在高并发的分布式系统运行时,大量的请求调用会产生海量的跟踪日志信息,如果收集过多的跟踪信息将会对整个分布式系统的性能造成一定的影响,同时保存大量的日志信息也需要不少的存储开销。所以,在Sleuth中采用了抽象收集的方式来跟踪信息打上标记,也就是我们前面第四个布尔值,它代表了该信息是否要被后续的跟踪信息收集器获取和存储。

 

默认情况下,Sleuth会使用PercentageBasedSampler实现的抽样策略,以请求百分比的方式配置和收集跟踪信息,默认值0.1(代表收集10%的请求跟踪信息),可以通过配置spring.sleuth.sampler来修改收集的百分比。

 

  • 与ELK整合

 

前面随着已经有了跟踪信息,但是由于日志文件都分布在各个服务实例的文件系统上,如果链路上服务比较多,查看日志文件定位问题是一件非常麻烦的事情,所以我们需要一些工具来帮忙集中收集、存储和搜素这些跟踪信息。引入基于日志的分析系统是一个不错的选择,比如ELK平台,SpringCloudSleuth在与ELK平台整合使用时,实际上只需要与负责日志收集的Logstash完成数据对接即可,所以我们需要为logstash准备Json格式的日志输出(SpringBoot应用默认使用logback来记录日志,而logstash自身也有对logback日志工具支持)。与ELK整合架构图如下所示:

 

 

  • 与Zipkin整合

 

虽然通过ELK平台提供的收集、存储、搜索等强大功能,但是缺少对请求链路中各阶段时间延迟的关注,而很多时候我们追溯请求链路的一个原因是为了找出整个链路中出现延迟过高的瓶颈源,或者找出问题服务实例等监控与时间消耗相关的需求,ELK就显得乏力,反而引入Zipkin就能够轻松解决。

 

Zipkin是Twitter的一个开源项目,它基于Google Dapper实现。我们可以使用它来收集各个服务器上请求链路的跟踪数据,并通过它提供的Rest API接口来辅助查询跟踪数据以分布式系统的监控程序,通过UI组件帮助我们及时发现系统中出现的延迟升高问题以及系统性能瓶颈根源。下面展示Zipkin的基础架构,它主要由4个核心组件构成:


 

Collector(收集器组件):主要负责收集外部系统跟踪信息,转化为Zipkin内部的Span格式。

Storage(存储组件):主要负责收到的跟踪信息的存储,默认为内存,同时支持存储到Mysql、Cassandra以及Elasticsearch。

Restful API(API组件):提供接口,方便外部系统进行集成。

Web UI(展示组件):基于API开发的自带展示界面,方便进行跟踪信息的查看以及查询,同时进行相关的分析。

 

其他相关信息:https://my.oschina.net/lhztt/blog/795307

猜你喜欢

转载自blog.csdn.net/anxunzp/article/details/79483220