作者:微信小助手
发布时间:2020-11-18T19:10:10
关注“脚本之家”,与百万开发者在一起
作者 | 悟空聊架构
来源 | 悟空聊架构(ID:PassJava666)
这篇主要是理论 + 实践相结合。实践部分涉及到如何把链路追踪组件 Sleuth
+ Zipkin
加到我的 Spring Cloud 《佳必过》开源项目上。
本篇知识点:
微服务
架构其实是一个分布式
的架构,按照业务划分成了多个服务单元。
由于服务单元的数量
是很多的,有可能几千个,而且业务也会更复杂,如果出现了错误和异常,很难去定位。
比如一个请求需要调用多个服务才能完成整个业务闭环,而内部服务的代码逻辑和业务逻辑比较复杂,假如某个服务出现了问题,是难以快速确定那个服务出问题的。
而如果我们加上了分布式链路追踪
,去跟踪一个请求有哪些服务参与其中,参与的顺序是怎样的,这样我们就知道了每个请求的详细经过,即使出了问题也能快速定位。
链路追踪组件有 Twitter 的可视化链路追踪组件 Zipkin
、Google 的 Dapper
、阿里的 Eagleeye
等,而 Sleuth 是 Spring Cloud 的组件。Spring Cloud Sleuth 借鉴了 Dapper 的术语。
本文主要讲解 Sleuth + Zipkin 结合使用来更好地实现链路追踪。
为什么能够进行整条链路的追踪?其实就是一个 Trace ID 将 一连串的 Span 信息连起来了。根据 Span 记录的信息再进行整合就可以获取整条链路的信息。下面是链路追踪的核心概念:
大白话:远程调用和 Span 一对一
。
基本的工作单元,每次发送一个远程调用服务就会产生一个 Span。
Span 是一个 64 位的唯一 ID。
通过计算 Span 的开始和结束时间,就可以统计每个服务调用所花费的时间。
大白话:一个 Trace 对应多个 Span,一对多
。
它由一系列 Span 组成,树状结构。
64 位唯一 ID。
每次客户端访问微服务系统的 API 接口,可能中间会调用多个微服务,每次调用都会产生一个新的 Span,而多个 Span 组成了 Trace
链路追踪系统定义了一些核心注解,用来定义一个请求的开始和结束,注意是微服务之间的请求,而不是浏览器或手机等设备。注解包括:
cs
- Client Sent:客户端发送一个请求,描述了这个请求调用的
Span
的开始时间。注意:这里的客户端指的是微服务的调用者,不是我们理解的浏览器或手机等客户端。
sr
- Server Received:服务端获得请求并准备开始处理它,如果将其
sr
减去
cs
时间戳,即可得到网络传输时间。
ss
- Server Sent:服务端发送响应,会记录请求处理完成的时间,
ss
时间戳减去
sr
时间戳,即可得到服务器请求的时间。
cr
- Client Received:客户端接收响应,Span 的结束时间,如果
cr
的时间戳减去
cs
时间戳,即可得到一次微服务调用所消耗的时间,也就是一个
Span
的消耗的总时间。
假定三个微服务调用的链路如下图所示:Service 1
调用 Service 2
,Service 2
调用 Service 3
和 Service 4。
那么链路追踪会在每个服务调用的时候加上 Trace ID 和 Span ID。如下图所示:
大白话解释:
大家注意上面的颜色,相同颜色的代表是同一个 Span ID,说明是链路追踪中的一个节点。
第一步:客户端调用 Service 1
,生成一个 Request
,Trace ID
和 Span ID
为空,那个时候请求还没有到 Service 1
。
第二步:请求到达 Service 1
,记录了 Trace ID = X,Span ID 等于 A。
第三步:Service 1
发送请求给 Service 2
,Span ID 等于 B,被称作 Client Sent,即客户端发送一个请求。
第四步:请求到达 Service 2
,Span ID 等于 B,Trace ID 不会改变,被称作 Server Received,即服务端获得请求并准备开始处理它。
第五步:Service 2
开始处理这个请求,处理完之后,Trace ID 不变,Span ID = C。
第六步:Service 2
开始发送这个请求给 Service 3
,Trace ID 不变,Span ID = D,被称作 Client Sent,即客户端发送一个请求。
第七步: