1 服务追踪系统的意义
1.1 快速定位请求失败原因
微服务架构下,服务众多,如果一次上游请求失败,想查清楚到底是哪个应用导致,简直是梦魇!
倘若有一系统,可跟踪记录一次用户请求都发起了哪些调用,经过哪些服务处理,并且记录每一次调用所涉及的服务的详细信息,调用失败,不就可通过日志快速定位问题环节!
1.2 优化系统瓶颈
通过记录调用经过的每一条链路上的耗时,能快速定位整个系统的瓶颈点。比如你访问xxx网站首页发现很慢,可能是运营商网络延迟、网关系统异常、某服务异常、缓存或DB异常。通过服务追踪,可在上帝视角观得整个系统的瓶颈点,再针对性优化。
1.3 优化链路调用
分析调用所经过的路径,评估是否合理,是否每个依赖都是必要,是否可通过业务优化减少服务依赖。
一般业务都会在多个数据中心都部署服务,以实现异地容灾,这时经常会出现服务A调用另外一个数据中心的服务B,而没有调用同处于一个数据中心的服务B。
跨数据中心的调用视距离远近都会有一定网络延迟,对于有些业务不可接受。通过分析调用链路,可找出跨数据中心的服务调用,从而优化。
1.4 生成网络拓扑
通过记录的链路信息,可以生成一张系统的网络调用拓扑图,它可以反映系统都依赖了哪些服务,以及服务之间的调用关系是什么样的,可以一目了然。
在网络拓扑图上还可把服务调用的详细信息也标出来,也能起到服务监控的作用。
1.5 透明传输数据
业务上经常有一种需求,期望能把一些用户数据,从调用的开始一直往下传递,以便系统中的各个服务都能获取到这个信息。比如业务想做一些A/B测试,就想通过服务追踪系统,把A/B测试的开关逻辑一直往下传递,经过的每层服务都能获取到这个开关值,就能统一A/B测试。
2 服务追踪系统原理
服务追踪系统鼻祖:Google的论文Dapper, a Large-Scale Distributed Systems Tracing Infrastructure详细讲解了服务追踪系统的实现原理。
核心理念
调用链,通过一个全局唯一ID串联分布在各个服务节点上的同一次请求,还原调用关系,可追踪系统问题、分析调用数据并统计各种系统指标。
之后诞生的各种服务追踪系统都是基于Dapper,比如Twitter的Zipkin、阿里的鹰眼、美团的MTrace等。
2.1 核心概念
traceId
一次分布式调用的链路踪迹。全局唯一,64位整数,用于标识某次具体请求ID。
在RPC调用的网络链路中不断传递,串联某一次请求在系统中经过的所有路径。
spanId
一个方法(局部或远程)调用踪迹。用于标识一次RPC调用在分布式请求中的位置,区分系统不同服务之间调用的先后关系。
当用户的请求进入系统后,处在RPC调用网络的第一层A时spanId初始值是0,进入下一层RPC调用B的时候spanId是0.1,继续进入下一层RPC调用C时spanId是0.1.1,而与B处在同一层的RPC调用E的spanId是0.2,这样的话通过spanId就可以定位某一次RPC请求在系统调用中所处的位置,以及它的上下游依赖分别是谁。这类似哈夫曼编码。
annotation
附着在 Span 上的日志信息。用于业务自定义埋点数据,可以是业务感兴趣的想上传到后端的数据,比如一次请求的用户UID。
业务自定义一些自己感兴趣的数据,在上传traceId和spanId这些基本信息之外,添加一些自己感兴趣的信息。
Sampling
采样率。


