背景介绍在微服务横行的时代,面向服务的思维逐渐成为程序员的基本思维模式。但是由于大部分项目只是盲目增加服务,没有做好管理,当接口出现问题时,很难从错综复杂的服务调用网络中找到问题的根源,从而错失了千载难逢的机会止损。链接跟踪的出现正是为了解决这个问题。可以在复杂的服务调用中定位问题,也可以让新人在加入后台后清楚的知道自己负责哪个环节的服务。另外,如果某个接口的耗时突然增加了,我们也不需要一个一个去查询每个服务的耗时。我们可以直观地分析出服务的性能瓶颈,便于在流量激增的情况下进行准确合理的扩容。LinkTracking“链接跟踪”一词是在2010年提出的,当时Google发表了一篇Dapper论文,介绍了Google自研的分布式链接跟踪的实现原理,以及他们是如何低成本实现的。对应用透明。其实Dapper一开始只是一个独立的调用链路跟踪系统,后来逐渐演变为一个监控平台,并基于监控平台诞生了很多工具,比如实时预警、过载保护、索引数据等询问。除了Google的Dapper,还有阿里的EagleEye、大众点评的CAT、Twitter的Zipkin、Naver(著名社交软件LINE的母公司)的pinpoint、国内开源的skywalking等知名产品。基本实现原理要想知道一个接口哪里出了问题,就必须知道这个接口调用了哪些服务,以及调用的顺序。如果将这些服务串在一起,它看起来就像一个链条。我们称之为调用链。.如果要实现调用链,就需要为每个调用做一个标识符,然后根据标识符的大小来排列服务,这样可以更清楚地看到调用顺序。我们暂时将标识符命名为spanid。在实际场景中,我们需要知道某个请求调用的情况,所以只有spanid是不够的,我们要为每个请求做一个唯一的标识,这样我们才能根据这个请求找出所有调用的服务到标识符,我们将此标识符命名为traceid。现在根据spanid可以很容易知道被调用服务的顺序,但是无法体现调用的层级关系。如下图所示,多个服务可能被逐级调用链,也可能同时被同一个服务调用。所以应该记录每次调用的是谁,我们用parentid作为这个标识的名称。到现在我们已经知道了调用顺序和层级关系,但是接口出现问题后,我们还是找不到问题的链接。如果某个服务出现问题,调用的服务肯定要耗费很长时间。如果要计算成本,这时候上面三个标识符是不够的,还需要时间戳。时间戳可以更精确,精确到微秒级别。只记录调用发起时的时间戳,并不耗时。需要记录服务返回时的时间戳,只能计算从开始到结束的时间差。由于返回也被记录下来,记下以上三个标记。否则,分不清是谁的时间戳。虽然可以计算出从服务调用到服务返回的总耗时,但这个时间包括服务执行时间和网络延迟。有时我们需要区分这两种类型的时间进行针对性的优化。那么如何计算网络延迟呢?我们可以将调用和返回的过程分为以下四个事件。ClientSent简称cs,客户端向服务端发起调用请求。ServerReceived简称sr,表示服务器已经收到客户端的调用请求。ServerSent简称ss,表示服务端处理完毕,准备返回信息给客户端。ClientReceived简称cr,表示客户端接收到服务器的返回信息。如果记录这四个事件发生时的时间戳,就可以轻松计算出耗时。比如sr减cs就是调用时的网络延时,ss减sr就是服务执行时间,cr减ss就是服务响应Delay,cr减cs就是整个服务调用的执行时间。其实span块除了记录这些参数外,还可以记录一些其他的信息,比如调用服务的名称,被调用服务的名称,返回结果,IP,调用服务的名称等.最后,我们把相同的spanid信息合成到一个大span块中,一个完整的调用链就完成了。有兴趣的同学可以详细了解链接跟踪。希望这篇文章对您有所帮助。
