2019新春支付宝红包技术大揭秘在线峰会将于03-07日开始,点击这里报名届时便可参与大牛互动。html
SOFA Scalable Open Financial Architecture
是蚂蚁金服自主研发的金融级分布式中间件,包含了构建金融级云原生架构所需的各个组件,是在金融场景里锤炼出来的最佳实践。 SOFATracer
是一个用于分布式系统调用跟踪的组件,经过统一的 TraceId
将调用链路中的各类网络调用状况以日志的方式记录下来,以达到透视化网络调用的目的,这些链路数据可用于故障的快速发现,服务治理等。 本文为《剖析
| SOFATracer 框架》第一篇。《剖析 | SOFATracer 框架》系列由 SOFA
团队和源码爱好者们出品,项目代号:<SOFA:TracerLab/>,文章尾部有参与方式,欢迎一样对源码热情的你加入。
在单体应用时代,咱们不须要花费时间去关心调用链路这个东西。git
可是链路跟踪不只仅是在分布式场景下才会有,即便是单体应用,一样也会存在调用链路。github
例如,咱们把应用中的每一个服务接口做为一个链路节点,那么从请求进来到返回响应,把这个过程当中多历经的全部的方法接口串联起来,就能组成一条完整的链路,以下图所示:web
对于单体应用而言,若是访问一个资源没有成功,那么咱们能够很快的锁定是哪一台机器,而后经过查询这台机器上的日志就能定位问题。编程
可是在微服务体系架构下,这种方式会显得很是无力。对于一个稍具规模的应用来讲,一次请求可能会跨越至关多的服务节点,在这种状况下,若是一个请求没有获得成功的响应,就不能肯定究竟是哪一个节点出了问题。api
所以在面对这种复杂的大规模分布式集群来实现的服务体系来讲,就须要一些能够帮助理解各个应用的线上调用行为、并能够分析远程调用的组件。网络
基于上述背景,蚂蚁金服开源了基于 OpenTracing 规范 (http://opentracing.io/documen...)实现的 SOFATracer 分布式链路跟踪组件,为实施大规模服务化体系架构场景下提供了链路跟踪的解决方案。架构
在介绍 SOFATracer 以前,先来了解一下 Opentracing 规范。框架
首先来解释下 OpenTracing 是什么OpenTracing 致力于为分布式跟踪建立更标准化的API和工具,它由完整的API规范、实现该规范的框架、库以及项目文档组成。异步
OpenTracing 提供了一套平台无关、厂商无关的 API,这样不一样的组织或者开发人员就可以更加方便的添加或更换追踪系统的实现。 OpenTracing API 中的一些概念和术语,在不一样的语言环境下都是共享的。
Opentracing 规范中,一条 trace 链路是由多个与之关联的 span 组成,一条链路总体能够看作是一张有向无环图,各个span之间的边缘关系被称之为“References”。下面是官方提供的示例:
若是以时间轴维度来看的话,也能够表现为下面的形式(官方示例):
类型 ChildOf : 父 Span 以某种身份依赖于子Span
FollowFrom : 父 Span 不以任何方式依赖子
Span
可是为了简化 span 之间的这种依赖关系,在具体实现时一般会将具备嵌套关系的做为 ChildOf,平行执行的做为FollowFrom,好比:
a. ChildOf 示例
在 methodA 中调用了 method B :
methodA(){ // spanA start methodB(); } // spanA finish methodB(){ // spanB start } // spanB finish
产生的 span 在时间维度上展示的视角以下:
这种关系通常会表示为 SpanB ChildOf SpanA 。
b. FollowFrom 示例
method 方法中,methodA 执行以后 methodB 执行 : method(){ methodA(); methodB(); }
产生的 span 在时间维度上展示的视角以下:
这种关系通常会表示为 SpanB FollowFrom SpanA 。
1.2 API
Opentracing API 是对分布式链路中涉及到的一些列操做的高度抽象集合。Opentracing 中将全部核心的组件都声明为接口,例如 Tracer、Span、SpanContext、Format(高版本中还包括 Scope 和 ScopeManager)等。SOFATracer 使用的版本是 0.22.0 ,主要是对 Tracer、Span、SpanContext 三个概念模型的实现。下面就针对这三个组件结合 SOFATracer 来分析。
1.3 SOFATracer 标准实现
下图为 SOFATracer 中对于这三个核心接口实现的类图结构:
因为篇幅缘由,下面的介绍过程当中一些点不会展开说明,有兴趣的同窗能够自行官网查看完整的 OpenTracing-api 规范 (https://opentracing.io/specif...)。
a. Tracer & SOFATracer
Tracer 是一个简单、广义的接口,它的做用就是构建 span 和传输 span 。核心接口列表以下:
SofaTracer 实现了 Tracer 接口,并扩展了采样、数据上报等能力。
b. Span & SOFATracerSpan
Span 是一个跨度单元,在实际的应用过程当中,Span 就是一个完整的数据包,其包含的就是当前节点所须要上报的数据。核心接口列表以下:
关于tags和log的解释:若是把从进入公司到离开公司这段时间做为一个 span,那么 tags
里面能够是你写的代码,你喝的水,甚至你讲过的话;log 则更关注某个时刻的事,好比在12:00 去吃了个饭,在15:00 开了个会。 若是说
tags 里面都是和公司有关的,那么 Baggage 里面则不只仅是局限于你在公司的事,好比你口袋里的手机。
SofaTracerSpan 在实现 Span 接口,并扩展了对 Reference、tags、线程异步处理以及插件扩展中所必须的 logType 和产生当前 span 的 Tracer 类型等处理的能力。
c. SpanContext & SOFATracerSpanContext
SpanContext 对于 OpenTracing 实现是相当重要的,经过 SpanContext 能够实现跨进程的链路透传,而且能够经过 SpanContext 中携带的信息将整个链路串联起来。
官方文档中有这样一句话:“在 OpenTracing 中,咱们强迫 SpanContext 实例成为不可变的,以免 Span
在finish 和 reference 操做时会有复杂的生命周期问题。” 这里是能够理解的,若是 SpanContext
在透传过程当中发生了变化,好比改了 tracerId,那么就可能致使链路出现断缺。
SpanContext 中只有一个接口:
SofaTracerSpanContext 实现了 SpanContext 接口,扩展了构建 SpanContext、序列化 baggageItems 以及SpanContext等新的能力,除此以外,SpanContext 在跨进行透传时携带的信息进行了规范:
为了知足在复杂场景下的链路跟踪需求,SOFATracer 在 Opentracing 规范基础上又提供了丰富的扩展能力。
SOFATracer 基于 OpenTracing 规范(https://opentracing.io/specif...)实现,而且经过 Disruptor (https://github.com/LMAX-Excha...。
应用在经过面向日志编程接口 SLF4J 打印应用日志时,能够只在对应的日志实现配置文件的 PatternLayout 中添加相应的参数便可,如添加 [%X{SOFA-TraceId},%X{SOFA-SpanId}] ,那么应用日志就能够在发生链路调用时打印出相应的 TraceId 和 SpanId ,而不管应用具体的日志实现是 Logback、Log4j2 或者 Log4j。关于这部分的实现原理,期待你们一块儿编写,领取方式见文末。
SOFATracer 目前仅提供了基于自身 API 埋点的方式。SOFATracer 中全部的插件均须要实现本身的 Tracer 实例,如 Mvc 的 SpringMvcTracer 、HttpClient 的 HttpClientTracer 等,以下图所示:
SOFATracer 将不一样的扩展组件分为 AbstractClientTracer 和 AbstractServerTracer,再经过AbstractClientTracer 和 AbstractServerTracer 衍生出具体的组件 Tracer 实现。这种方式的好处在于,全部的插件实现均有 SOFATracer 自己来管控,对于不一样的组件能够轻松的实现差别化和定制化。
可是为了可以拥抱社区,咱们在后续的版本中将会提供基于 Opentracing API 的埋点扩展实现,从而实现与 opentracing-contrib 的无缝对接。基于 Opentracing API 的插件埋点方案以下图所示:
关于 SOFATracer 基于特有 API 埋点的实现以及如何实现对接 OT-api 埋点,期待你们一块儿编写,领取方式见文末。
SOFATracer 中并无将不一样的 Reporter 设计成不一样的策略,而后根据不一样的策略来实现具体的上报操做,而是使用了一种相似组合的方式,而且在执行具体上报的流程中经过参数来调控是否执行具体的上报。
从流程图中能够看到,此过程当中涉及到了三个上报点,首先是上报到 zipkin,后面是落盘;在日志记录方面,SOFATracer 中为不一样的组件均提供了独立的日志空间,除此以外,SOFATracer 在链路数据采集时提供了两种不一样的日志记录模式:摘要日志和统计日志,这对于后续构建一些如故障的快速发现、服务治理等管控端提供了强大的数据支撑。关于数据上报,期待你们一块儿编写,领取方式见文末。
对于链路中的数据,并不是全部的数据都是值得关注的。一方面是能够节约磁盘空间,另外一方面能够将某些无关数据直接过滤掉。基于此,SOFATracer 提供了链路数据采样能力。目前咱们提供了两种策略,一种是基于固定比率的采样,另外一种是基于用户扩展实现的自定义采样;在自定义采样设计中,咱们将 SofaTracerSpan 实例做为采样计算的条件,用户能够基于此实现丰富的采样规则。关于采样机制,期待你们一块儿编写,领取方式见文末。
关于透传机制,咱们不只须要考虑线程内传递,还须要考虑跨线程以及异步线程场景,对于分布式链路来讲,最核心还有如何实现跨进程的数据透传。关于 SOFATracer 链路透传 以及 OpenTracing 新规范中对线程传递的支持,期待你们一块儿编写,领取方式见文末。
首先介绍下目前 SOFATracer 的现状和一些正在作的事情。
SOFATracer 版本说明:
点击阅读更多,查看更多详情