分布式链路追踪
分布式服务的典型特点是调用关系复杂,用户发起的一次请求可能经过一系列相关的服务调用才能完成整个业务,具体的调用链路是什么,每个微服务处理的时间有多长,哪个链路快,哪个链路慢,哪个服务节点是业务瓶颈,这些很难去分析和判断。微服务调用链路如图3-38所示。因此,微服务需要一个重要的能力就是链路追踪能力。
图3-38 微服务调用链路
如图3-39所示,某个业务的请求过程为用户→A→B→C, 应答过程为C→B→A→用户。怎样用一张表来记录整个交易链路关系、每个节点的耗时,以及任意两点之间的耗时呢?
图3-39 链路调用请求应答
首先可以设计一张链路追踪记录表,如表3-1所示。
表3-1 链路追踪记录
那么,图3-39整个交易过程的数据如表3-2所示。
表3-2 链路追踪记录示例
续表
将表3-2中的数据标记到链路图中,如图3-40所示,T01作为TraceID会在整个交易链路中被逐级传递下去,因此使用T01就可以查询到整个交易链路,在什么时间经过了哪些节点。
图3-40 交易链路记录
整个交易被分为S01~S05共5个区间段,S01结束时间减去S01开始时间就可以得出交易总耗时。同理,S03结束时间减去S03开始时间就可以得出服务B、C的总处理时长。同理,就可以计算任意两点之间的耗时情况。
(1) 计算服务A和服务B之间的总耗时:用S03开始时间减去S02 开始时间。
(2) 计算服务B的总耗时:用S03结束时间减去S03开始时间。
(3) 计算服务C接收到用户请求的总耗时:用S05开始时间减去S01开始时间。
链路追踪的开源服务有很多,SkyWalking是其中较好的一款,以下内容来源于SkyWalking官网,如图3-41所示。
SkyWalking是一个可观察性分析平台和应用程序性能管理系统。提供分布式跟踪、服务网格遥测分析、度量聚合和可视化多合一解决
方案。支持Java、.Net Core、PHP、Node.js、Golang、Lua、C++代理、Istio+Envoy Service Mesh。Pinpoint也是一款十分优秀的分布式系统监控服务,如果使用Spring Cloud框架,则可以使用Sleuth+Zipkin的组合。
图3-41 SkyWalking工作
设计思考:链路监控的核心设计是什么?
TraceID链式传递设计,对于任何需要追踪整体链路的业务,都需要设计一个唯一的TraceID,采用逐级传递,逐级记录的方式。一般
TraceID要放在整个交易报文的头部,或者HTTP的Header中。
不只是在远程调用过程中,在本地程序调用过程中也可以采用这种记录方式,从而形成一个调用树结构,每个节点的耗时都可以一目了然。
每个方法、每个服务的调用过程都可以构建成一棵调用链路树,每个方法或服务都是树上的一个节点,如图3-42所示,都可以分配一个
SpanID(S01,S02,…,S06)作为方法或服务的标识(代表一个运行区间),以ParentSpanID代表该父方法或服务(调用者)。
图3-42 调用链路树
例如,方法C或服务C的SpanID=S04,ParentSpanID=S02,父节点的SpanID=S02,描述的具体含义就是S04被S02调用。
在服务和方法的调用过程中,最容易被忽略的就是异步调用,一定要将TraceID、SpanID、ParentSpanID也传递进去,否则就会造成不知道异步程序是由谁调用的,处理的是哪一次业务请求,也无法跟踪具体的开始时间和结束时间。