蚂蚁金服分布式链路跟踪组件 SOFATracer 总览 | 剖析

SOFA Scalable Open Financial Architecture 是蚂蚁金服自主研发的金融级分布式中间件,包含了构建金融级云原生架构所需的各个组件,是在金融场景里锤炼出来的最佳实践。
SOFATracer 是一个用于分布式系统调用跟踪的组件,经过统一的 TraceId 将调用链路中的各类网络调用状况以日志的方式记录下来,以达到透视化网络调用的目的,这些链路数据可用于故障的快速发现,服务治理等。 SOFAT racer https://github.com/alipay/sofa-tracer

本文为《剖析 | SOFATracer 框架》第一篇。《剖析 | SOFASOFATracer 框架》系列由 SOFA 团队和源码爱好者们出品, 项目代号:<SOFA:TracerLab/>文章尾部有参与方式,欢迎一样对源码热情的你加入html


0、前言

在单体应用时代,咱们不须要花费时间去关心调用链路这个东西。可是链路跟踪不只仅是在分布式场景下才会有,即便是单体应用,一样也会存在调用链路。例如,咱们把应用中的每一个服务接口做为一个链路节点,那么从请求进来到返回响应,把这个过程当中多历经的全部的方法接口串联起来,就能组成一条完整的链路,以下图所示:git

image.png | center | 747x201
对于单体应用而言,若是访问一个资源没有成功,那么咱们能够很快的锁定是哪一台机器,而后经过查询这台机器上的日志就能定位问题。
可是在微服务体系架构下,这种方式会显得很是无力。对于一个稍具规模的应用来讲,一次请求可能会跨越至关多的服务节点,在这种状况下,若是一个请求没有获得成功的响应,就不能肯定究竟是哪一个节点出了问题。
image.png | center | 747x157
所以在面对这种复杂的大规模分布式集群来实现的服务体系来讲,就须要一些能够帮助理解各个应用的线上调用行为、并能够分析远程调用的组件。
基于上述背景,蚂蚁金服开源了基于 OpenTracing 规范 opentracing.io/documentati… )实现的 SOFATracer 分布式链路跟踪组件,为实施大规模服务化体系架构场景下提供了链路跟踪的解决方案。
在介绍 SOFATracer 以前,先来了解一下 Opentracing 规范。

一、Opentracing 简介

首先来解释下 OpenTracing 是什么 OpenTracing 致力于为分布式跟踪建立更标准化的API和工具,它由完整的API规范、实现该规范的框架、库以及项目文档组成。github

OpenTracing 提供了一套平台无关、厂商无关的 API ,这样不一样的组织或者开发人员就可以更加方便的添加或更换追踪系统的实现。 OpenTracingAPI 中的一些概念和术语,在不一样的语言环境下都是共享的。

1.一、数据模型

Opentracing 规范中,一条 trace 链路是由多个与之关联的 span 组成,一条链路总体能够看作是一张有向无环图,各个 span 之间的边缘关系被称之为“ References ”。下面是官方提供的示例:
image.png | center | 742x290
若是已时间轴维度来看的话,也能够表现为下面的形式(官方示例):
image.png | center | 763x162
root span : 当前链路中的第一个 span
ChildOfFollowFrom 是目前被定义的两种 References 类型 ChildOf : 父级 span某种程度上取决于子span (子span的结果可能会对父span产生影响)
FollowFrom : 父 Span不以任何方式依赖子 Span
可是为了简化 span 之间的这种依赖关系,在具体实现时一般会将具备嵌套关系的做为 ChildOf ,平行执行的做为 FollowFrom ,好比:
a、ChildOf 示例
methodA 中调用了 method B :


产生的 span 在时间维度上展示的视角以下:
image.png | left | 622x84
这种关系通常会 表示为 SpanBChildOfSpanA
b、FollowFrom 示例
method 方法中, methodA 执行以后 methodB 执行 :


产生的 span 在时间维度上展示的视角以下:
image.png | left | 622x64
这种关系通常会 表示为 SpanBFollowFromSpanA

1.二、API

OpentracingAPI 是对分布式链路中涉及到的一些列操做的高度抽象集合。 Opentracing 中将全部核心的组件都声明为接口,例如 Tracer Span SpanContext Format (高版本中还包括 Scope ScopeManager )等。 SOFATracer 使用的版本是 0.22.0 ,主要是对 Tracer Span SpanContext 三个概念模型的实现。下面就针对这三个组件结合 SOFATracer 来分析。

1.三、SOFATracer 标准实现

下图为 SOFATracer 中对于这三个核心接口实现的类图结构:
image.png | center | 566x310

因为篇幅缘由,下面的介绍过程当中一些点不会展开说明,有兴趣的同窗能够自行官网查看完整的 OpenTracing-api 规范opentracing.io/specificati…)。web

a、Tracer & SofaTracer
Tracer 是一个简单、广义的接口,它的做用就是构建 span 和传输 span 。核心接口列表以下:
接口 描述
SpanBuilder buildSpan(String operationName) 根据指定的operationName构建一个新的span
void inject(SpanContext spanContext, Formatformat, C carrier); 将 spanContext 以 format 的格式注入到 carrier 中
SpanContext extract(Format format, C carrier); 以 format 的格式从carrier中解析出 SpanContext
SofaTracer 实现了 Tracer 接口,并扩展了采样、数据上报等能力。
_b、Span & SofaTracerSpan _
Span 是一个跨度单元,在实际的应用过程当中, Span 就是一个完整的数据包,其包含的就是当前节点所须要上报的数据。核心接口列表以下:
接口 描述
SpanContext context() 从 span 中获取 SpanContext
void finish()/void finish(long finishMicros) 结束一个 span
void close() 关闭 span
Span setTag(String key, value) 设置 tags
Span log(long timestampMicroseconds, String event) 设置 log 事件
Span setOperationName(String operationName) 设置span的operationName
Span setBaggageItem(String key, String value) 设置 BaggageItem
String getBaggageItem(String key) 获取 BaggageItem

关于 tagslog的解释:若是把从进入公司到离开公司这段时间做为一个 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 实例成为不可变的,以免 Spanfinishreference 操做时会有复杂的生命周期问题。” 这里是能够理解的,若是 SpanContext 在透传过程当中发生了变化,好比改了 tracerId,那么就可能致使链路出现断缺。api

SpanContext 中只有一个接口:
接口 描述
Iterable> baggageItems(); 拿到全部的baggageItems 透传数据
SofaTracerSpanContext 实现了 SpanContext 接口,扩展了构建 SpanContext 、序列化 baggageItems 以及 SpanContext 等新的能力,除此以外, SpanContext 在跨进行透传时携带的信息进行了规范:
携带信息 描述
traceId 全链路惟一的标识信息
spanId spanId
parentId 父 spanId
isSampled 采样标记
sysBaggage 系统透传数据
bizBaggage 业务透传数据

二、SOFATracer 扩展

为了知足在复杂场景下的链路跟踪需求, SOFATracerOpentracing 规范基础上又提供了丰富的扩展能力。网络

2.一、SOFATracer 架构及功能扩展

image.png | left | 747x279
SOFATracer 基于 OpenTracing 规范 opentracing.io/specificati… )实现,而且经过 Disruptor github.com/LMAX-Exchan… )组件实现了日志的无锁异步打印能力。
基于 SLF4J 的 MDC 扩展能力
应用在经过面向日志编程接口 SLF4J 打印应用日志时,能够只在对应的日志实现配置文件的 PatternLayout 中添加相应的参数便可,如添加 [%X{SOFA-TraceId},%X{SOFA-SpanId}] ,那么应用日志就能够在发生链路调用时打印出相应的 TraceId SpanId ,而不管应用具体的日志实现是 Logback Log4j2 或者 Log4j 。关于这部分的实现原理,期待你们一块儿编写,领取方式见文末。
SOFATracer 的埋点机制
SOFATracer 目前仅提供了基于自身 API 埋点的方式。 SOFATracer 中全部的插件均须要实现本身的 Tracer 实例,如 Mvc SpringMvcTracer HttpClient HttpClientTracer 等,以下图所示:
image.png | center | 607x272
SOFATracer 将不一样的扩展组件分为 AbstractClientTracer AbstractServerTracer ,再经过 AbstractClientTracer AbstractServerTracer 衍生出具体的组件 Tracer 实现。这种方式的好处在于,全部的插件实现均有 SOFATracer 自己来管控,对于不一样的组件能够轻松的实现差别化和定制化。
可是为了可以拥抱社区,咱们在后续的版本中将会提供基于 OpentracingAPI 的埋点扩展实现,从而实现与 opentracing-contrib 的无缝对接。基于 OpentracingAPI 的插件埋点方案以下图所示:
image.png | center | 663x225
关于 SOFATracer 基于特有 API 埋点的实现以及如何实现对接 OT-api 埋点,期待你们一块儿编写,领取方式见文末。
SOFATracer 的数据上报机制
SOFATracer 中并无将不一样的 Reporter 设计成不一样的策略,而后根据不一样的策略来实现具体的上报操做,而是使用了一种相似组合的方式,而且在执行具体上报的流程中经过参数来调控是否执行具体的上报。
image.png | center | 306x514
从流程图中能够看到,此过程当中涉及到了三个上报点,首先是上报到 zipkin ,后面是落盘;在日志记录方面, SOFATracer 中为不一样的组件均提供了独立的日志空间,除此以外, SOFATracer 在链路数据采集时提供了两种不一样的日志记录模式:摘要日志和统计日志,这对于后续构建一些如故障的快速发现、服务治理等管控端提供了强大的数据支撑。关于数据上报,期待你们一块儿编写,领取方式见文末。
SOFATracer 的采样机制
对于链路中的数据,并不是全部的数据都是值得关注的。一方面是能够节约磁盘空间,另外一方面能够将某些无关数据直接过滤掉。基于此, SOFATracer 提供了链路数据采样能力。目前咱们提供了两种策略,一种是基于固定比率的采样,另外一种是基于用户扩展实现的自定义采样;在自定义采样设计中,咱们将 SofaTracerSpan 实例做为采样计算的条件,用户能够基于此实现丰富的采样规则。关于采样机制,期待你们一块儿编写,领取方式见文末。
SOFATracer 链路透传机制
关于透传机制,咱们不只须要考虑线程内传递,还须要考虑跨线程以及异步线程场景,对于分布式链路来讲,最核心还有如何实现跨进程的数据透传。关于 SOFATracer 链路透传 以及 OpenTracing 新规范中对线程传递的支持,期待你们一块儿编写,领取方式见文末。

2.二、SOFATracer RoadMap

首先介绍下目前 SOFATracer 的现状和一些正在作的事情。
image.png | left | 747x260
SOFATracer 版本说明:
3.x 版本支持 webflux 等,基于分支发布。
2.x 版本基于 master 发布,目前版本是 2.3.0 。
欢迎对相关功能和 feature 有兴趣的同窗,一块儿参与开发~

三、欢迎加入 ,参与 SOFATracer 源码解析

本文做为《剖析 | SOFATracer 组件系列》第一篇,主要仍是但愿你们对 SOFATracer 组件有一个认识和了解,以后,咱们会逐步详细介绍每部分的代码设计和实现,预计会按照以下的目录进行:架构

  • 分布式链路跟踪组件 SOFATracer 概述【已完成】
  • SOFATracer 数据上报机制和源码分析【待领取】
  • SOFATracerAPI组件埋点机制和源码分析【待领取】
  • SOFATracer链路透传原理与 SLF4J MDC 的扩展能力分析【待领取】
  • SOFATracer 的采样策略和源码分析【待领取】
若是有同窗对以上某个主题特别感兴趣的,能够留言讨论,咱们会适当根据你们的反馈调整文章的顺序,谢谢你们关注 SOFA ,关注 SOFATracer ,咱们会一直与你们一块儿成长的。
领取方式: 扫码关注公众号,后台回复想认领的文章名称,咱们将会主动联系你,确认资质后,便可加入 ,It's your show time!

除了源码解析,也欢迎提交 issue 和 PR: SOFATracerhttps://github.com/alipay/sofa-tracer框架

长按关注,获取分布式架构干货异步

欢迎你们共同打造 SOFAStack https://github.com/alipay

相关文章
相关标签/搜索