什么是链路追踪?分布式系统如何实现链路追踪?

news2024/12/23 23:51:24

在分布式系统,尤其是微服务系统中,一次外部请求往往需要内部多个模块,多个中间件,多台机器的相互调用才能完成。在这一系列的调用中,可能有些是串行的,而有些是并行的。在这种情况下,我们如何才能确定这整个请求调用了哪些应用?哪些模块?哪些节点?以及它们的先后顺序和各部分的性能如何呢?

这就是涉及到链路追踪。

什么是链路追踪?

链路追踪是分布式系统下的一个概念,它的目的就是要解决上面所提出的问题,也就是将一次分布式请求还原成调用链路,将一次分布式请求的调用情况集中展示,比如,各个服务节点上的耗时、请求具体到达哪台机器上、每个服务节点的请求状态等等。
图片

链路追踪的原理

衡量一个接口,我们一般会看三个指标:

1、接口的 RT(Route-Target)你怎么知道?
2、接口是否有异常响应?
3、接口请求慢在哪里?

1、单体架构时代

在创业初期,我们的系统一般是单体架构,如下:

图片

对于单体架构,我们可以使用 AOP(切面编程)来统计这三个指标,如下:

图片

使用 AOP(切面编程),对原本的逻辑代码侵入更少,我们只需要在调用具体的业务逻辑前后分别打印一下时间即可计算出整体的调用时间。另外,使用 AOP(切面编程)来捕获异常也可知道是哪里的调用导致的异常。

2、微服务架构

随着业务的快速发展,单体架构越来越不能满足需要,我们的系统慢慢会朝微服务架构发展,如下:

图片

在微服务架构下,当有用户反馈某个页面很慢时,虽然我们知道这个请求可能的调用链是 A -----> C -----> B -----> D,但服务这么多,而且每个服务都有好几台机器,怎么知道问题具体出在哪个服务?哪台机器呢?

图片

这也是微服务这种架构下的几个痛点:

1、排查问题难度大,周期长
2、特定场景难复现
3、系统性能瓶颈分析较难

分布式调用链就是为了解决以上几个问题而生,它主要的作用如下:

1、自动采取数据
2、分析数据,产生完整调用链:有了请求的完整调用链,问题有很大概率可复现
3、数据可视化:每个组件的性能可视化,能帮助我们很好地定位系统的瓶颈,及时找出问题所在

通过分布式追踪系统,我们能很好地定位请求的每条具体请求链路,从而轻易地实现请求链路追踪,进而定位和分析每个模块的性能瓶颈。

图片

3、分布式调用链标准(OpenTracing)

OpenTracing 是一个轻量级的标准化层,它位于应用程序/类库和追踪或日志分析程序之间。它的出现是为了解决不同的分布式追踪系统 API 不兼容的问题。

图片

OpenTracing 通过提供与平台和厂商无关的 API,使得开发人员能够方便地添加追踪系统,就像单体架构下的AOP(切面编程)一样。

说到这里,大家是否想过 Java 中类似的实现?还记得 JDBC 吧?JDBC 就是通过提供一套标准的接口让各个厂商去实现,程序员即可面对接口编程,不用关心具体的实现。这里的接口其实就是标准。所以,制定一套标准非常重要,可以实现组件的可插拔。

图片

OpenTracing 的数据模型,主要有以下三个:

  • **Trace:**一个完整请求链路

  • **Span:**一次调用过程(需要有开始时间和结束时间)

  • **SpanContext:**Trace 的全局上下文信息,如里面有traceId

为了让大家更好地理解这三个概念,我特意画了一张图:

图片

如图所示,一次下单的完整请求就是一个 Trace。TraceId是这个请求的全局标识。内部的每一次调用就称为一个 Span,每个 Span 都要带上全局的 TraceId,这样才可把全局 TraceId 与每个调用关联起来。这个 TraceId 是通过 SpanContext 传输的,既然要传输,显然都要遵循协议来调用。如图所示,如果我们把传输协议比作车,把 SpanContext 比作货,把 Span 比作路应该会更好理解一些。

理解了这三个概念,接下来我们就看看分布式追踪系统是如何采集图中的微服务调用链。

图片

我们可以看到底层有一个 Collector 一直在默默无闻地收集数据,那么每一次调用 Collector 会收集哪些信息呢。

1、全局 trace_id:这是显然的,这样才能把每一个子调用与最初的请求关联起来
2、span_id: 图中的 0,1,1.1,2,这样就能标识是哪一个调用
3、parent_span_id:比如 b 调用 d 的 span_id 是 1.1,那么它的 parent_span_id 即为 a 调用 b 的 span_id 即 1,这样才能把两个紧邻的调用关联起来。

有了这些信息,Collector 收集的每次调用的信息如下:

图片

根据这些图表信息显然可以据此来画出调用链的可视化视图如下:

图片

于是一个完整的分布式追踪系统就实现了。

以上实现看起来确实简单,但有以下几个问题需要我们仔细思考一下:

1、怎么自动采集 span 数据:自动采集,对业务代码无侵入
2、如何跨进程传递 context
3、traceId 如何保证全局唯一
4、请求量这么多采集会不会影响性能

接下来,我们来看看链路追踪系统 SkyWalking 是如何解决以上四个问题的。

链路追踪系统SkyWalking的原理

1、怎么自动采集 span 数据

SkyWalking 采用了插件化 + javaagent 的形式来实现了 span 数据的自动采集,这样可以做到对代码的无侵入性。插件化意味着可插拔,扩展性好。如下图所示:

图片

2、如何跨进程传递 context

我们知道数据一般分为 header 和 body,就像 http 有 header 和 body,RocketMQ 也有 MessageHeader,Message Body。body 一般放着业务数据,所以不宜在 body 中传递 context,应该在 header 中传递 context,如图所示:

图片

dubbo 中的 attachment 就相当于 header,所以我们把 context 放在 attachment 中,这样就解决了 context 的传递问题。

图片

图片

3、traceId 如何保证全局唯一

要保证全局唯一 ,我们可以采用分布式或者本地生成的 ID。使用分布式的话,需要有一个发号器,每次请求都要先请求一下发号器,会有一次网络调用的开销。所以 SkyWalking 最终采用了本地生成 ID 的方式,它采用了大名鼎鼎的 snowflow 算法,性能很高。

图片

不过 snowflake 算法有一个众所周知的问题:时间回拨,这个问题可能会导致生成的 id 重复。那么 SkyWalking 是如何解决时间回拨问题的呢。

图片

每生成一个 id,都会记录一下生成 id 的时间(lastTimestamp),如果发现当前时间比上一次生成 id 的时间(lastTimestamp)还小,那说明发生了时间回拨,此时会生成一个随机数来作为 traceId。这里可能就有同学要较真了,可能会觉得生成的这个随机数也会和已生成的全局 id 重复,是否再加一层校验会好点。

这里要说一下系统设计上的方案取舍问题了,首先如果针对产生的这个随机数作唯一性校验无疑会多一层调用,会有一定的性能损耗,但其实时间回拨发生的概率很小(发生之后由于机器时间紊乱,业务会受到很大影响,所以机器时间的调整必然要慎之又慎),再加上生成的随机数重合的概率也很小,综合考虑这里确实没有必要再加一层全局唯一性校验。对于技术方案的选型,一定要避免过度设计,过犹不及。

4、请求量这么多,全部采集会不会影响性能?

如果对每个请求调用都采集,那毫无疑问数据量会非常大,但反过来想一下,是否真的有必要对每个请求都采集呢?其实没有必要,我们可以设置采样频率,只采样部分数据,SkyWalking 默认设置了 3 秒采样 3 次,其余请求不采样,如图所示:

图片

这样的采样频率其实足够我们分析组件的性能了,按 3 秒采样 3 次,这样的频率来采样数据会有啥问题呢。理想情况下,每个服务调用都在同一个时间点,这样的话每次都在同一时间点采样确实没问题。如下图所示:

图片

但在生产上,每次服务调用基本不可能都在同一时间点调用,因为期间有网络调用延时等,实际调用情况很可能是下图这样:

图片

这样的话就会导致某些调用在服务 A 上被采样了,在服务 B,C 上不被采样,也就没法分析调用链的性能。

那么 SkyWalking 是如何解决的呢?

它是这样解决的:如果上游有携带 Context 过来(说明上游采样了),则下游将强制采集数据,这样可以保证链路完整。

SkyWalking 的基础架构

SkyWalking 的基础如下架构,可以说几乎所有的的分布式调用都是由以下几个组件组成的。

图片

首先当然是节点数据的定时采样,采样后将数据定时上报,将其存储到 ES, MySQL 等持久化层,有了数据自然而然可根据数据做可视化分析。

[图片上传失败…(image-a9fec9-1673754852336)]

SkyWalking 的性能如何

[图片上传失败…(image-45d20d-1673754852336)]

如下是官方的测评数据:

图片

图中蓝色代表未使用 SkyWalking 的表现,橙色代表使用了 SkyWalking 的表现,以上是在 TPS 为 5000 的情况下测出的数据,可以看出,不论是 CPU,内存,还是响应时间,使用 SkyWalking 带来的性能损耗几乎可以忽略不计。

接下来我们再来看 SkyWalking 与另一款业界比较知名的分布式追踪工具 Zipkin、Pinpoint 的对比(在采样率为 1 秒 1 个,线程数 500,请求总数为 5000 的情况下做的对比)。

可以看到在关键的响应时间上, Zipkin(117ms),PinPoint(201ms)远逊于 SkyWalking(22ms)!从性能损耗这个指标上看,SkyWalking 完胜!

图片

再看下另一个指标:对代码的侵入性如何。

ZipKin 是需要在应用程序中埋点的,对代码的侵入强,而 SkyWalking 采用 javaagent + 插件化这种修改字节码的方式可以做到对代码无任何侵入。除了性能和对代码的侵入性上 SkyWaking 表现不错外,它还有以下优势几个优势:

  • **对多语言的支持,组件丰富:**目前其支持 Java、 .Net Core、PHP、NodeJS、Golang、LUA 语言,组件上也支持dubbo, mysql 等常见组件,大部分能满足我们的需求。

  • **扩展性:**对于不满足的插件,我们按照 SkyWalking 的规则手动写一个即可,新实现的插件对代码无入侵。

以上虽然主要以SkyWalking为例来介绍链路追踪系统,但是并不是说其他链路追踪系统一点不适用。具体选择什么样的,大家可按实际场景灵活选择。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/164936.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PANNs:用于音频模式识别的大规模预训练音频神经网络

摘要 音频模式识别是机器学习领域的一个重要研究课题,它包括音频标注、声音场景分类、音乐分类、语音情感分类和声音事件检测等任务。近年来,神经网络已被应用于解决音频模式识别问题。然而,以前的系统是建立在特定数据集上的,数…

商业化广告--体系学习-- 17 -- 业务实战篇 --平台建设:如何从0到1建立一个完整的广告产品平台?

这是一个非常完整的广告产品平台,它包括广告投放平台(代理型和自助型)、销售类平台、运营类平台、数据类平台以及流量合作类平台五个部分。我们之前提到过程序化交易的一系列平台,但那些对于一个头部的媒体平台来说并不完整。一个…

结构分析软件:2D Frame Analysis 7.2.6 Crack

结构分析软件:2D Frame Analysis 7.2.6 用于在静态、动态、线性和非线性载荷下对框架、梁和桁架进行结构分析的软件工具。它包括静态版和桁架版的所有功能 2D 框架分析软件套件以及处理动态负载的能力。自动计算结构的动态模态,并以图形方式表示相应的模…

Java图形化界面---

目录 一、JColorChooser (1)JColorChooser的介绍 (2)JColorChooser案列 二、JFileChooser (1)JFileChooser的介绍 (2)JFileChooser使用步骤 (3)JFileChooser案例 …

【云原生进阶之容器】第四章Operator原理4.4节--Operator深入实践

1 Operator 深入实践 在本节中,我们将重点关注 etcd-cluster-operator,用于管理 Kubernetes 内部的 etcd。简单地说,etcd 是一个分布式键值数据存储系统,它有能力管理自己的稳定性,只要: 每个 etcd 实例都有一个用于计算、网络和存储的独立故障域。每个 etcd 实例都有一个…

读 | Software Architecture Patterns

个人博客 Software Architecture Patterns》是 Mark Richards 2015 年出的一本小册子,对常用的架构模式进行了一个简单梳理,书中列了 5 种: 分层(Layered)事件驱动(Event-Driven)微内核&#…

HTML的常见标签

什么是 HTML? HTML 是英文 Hyper Text Markup Language(超文本标记语言)的缩写,是一种用于创建网页的标准标记语言。 什么是HTML 标签? HTML 文档和 HTML 元素是通过 HTML 标签进行标记的 HTML 标签是由尖括号包围的关键词&am…

【阶段四】Python深度学习07篇:深度学习项目实战:循环神经网络的原理和结构

本篇的思维导图: 循环神经网络 循环神经网络,就是专门用于处理语言、文字、时序这类特征之间存在“次序”的问题。这是一种循环的、带“记忆”功能的神经网络,这种网络针对序列性问题有其优势。 循环神经网络的原理和结构 序列数据的概念 序列数据,是其特征的先后…

电路方案分析(十六)高效备用电源设计方案

高效备用电源设计方案 备用电源: 备用电源是一种在主电源发生故障时为负载提供紧急电源的电气系统。适当的备用电源通过提供存储在备用电容器或电池中的能量,提供即时保护,防止主电源中断而产生故障。这种备份电源通常用于保护硬件&#xf…

表单<form>

创建表单 <form> 标签用于创建供用户输入的 HTML 表单。 <form>标签的action属性的值指定了表单提交到服务器的地址。 <form> 元素包含一个或多个如下的表单元素&#xff1a; <input> <textarea> <button> <select> <option&g…

JAVA设计模式--行为型模式--职责链模式

1.责任链模式&#xff08;Chain of Responsibility Pattern&#xff09; 1.1介绍 为请求创建了一个接收者对象的链。这种模式给予请求的类型&#xff0c;对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。在这种模式中&#xff0c;通常每个接收者都包含对…

C语言文件操作(一文带你吃透文件各种操作)

文章目录 一、为什么要使用文件 二、什么是文件 2、1 程序文件 2、2 数据文件 2、3 文件名 三、文件的打开关闭及读写操作 3、1 文件指针 3、2 文件的打开和关闭操作 3、3 文件的读写函数详解 3、3、1 fgetc、fputc函数详解 3、3、2 fgets、fputs函数详解 3、3、3 fscanf、fpri…

神经网络介绍-激活函数、参数初始化、模型的搭建

目录1、深度学习了解1.1 深度学习简介1.2 神经网络2、神经网络的工作流程2.1 激活函数2.1.1 Sigmoid/Logistics函数2.1.2 tanh&#xff08;双曲正切曲线&#xff09;2.1.3 RELU2.1.4 Leaky Relu2.1.5 SoftMax2.1.6 其他激活函数2.2 参数初始化2.2.1 随机初始化2.2.2 标准初始化…

【博客585】ipvs场景下dummy网卡的作用

linux ipvs模式下dummy网卡的作用 1、场景&#xff1a; 在使用ipvs来实现vip的负载均衡的时候&#xff0c;有时我们会在linux中创建一块dummy网卡&#xff0c;并在网卡上绑上vip 2、场景示例&#xff1a;k8s kube-proxy组件的ipvs模式 kube-proxy在ipvs模式下生成了一块kub…

iperf工具源码下载、编译、编译报错解决、以及测试网络带宽

1、iperf源码下载 (1)源码下载地址&#xff1a;https://iperf.fr/iperf-download.php; (2)有的版本源码下载下来并不能直接编译成功&#xff0c;可能会报缺少头文件或者编译选项的错误&#xff0c;要么去解决这些错误&#xff0c;要么换个版本再试一下&#xff1b; (3)在我的环…

Linux学习【教程+实操】【超基础】

链接:资料提取码&#xff1a;6klp 今日内容Linux简介Linux安装网卡设置安装SSH连接工具Linux和Windows目录结构对比Linux常用命令Linux命令初体验文件目录操作命令拷贝移动命令打包压缩命令文本编辑命令查找命令Linux软件安装软件安装方式安装jdk&#xff08;采用二进制发布包…

mysql索引字段设计

表字段数量与row大小限制可以参考官方文档 https://dev.mysql.com/doc/refman/8.0/en/column-count-limit.html#column-count-limits 复合索引 参考&#xff1a;https://dev.mysql.com/doc/refman/8.0/en/innodb-limits.html 数量限制 一个复合索引最多可以包含16个列&…

微信小程序--自定义组件

组件的创建与引用 1.创建组件 在项目的根目录中&#xff0c;鼠标右键&#xff0c;创建 components -> test 文件夹 在新建的components -> test文件夹上&#xff0c;鼠标右键&#xff0c;点击“新建Component" 键入组件的名称之后回车&#xff0c;会自动生成组件对…

C语言进阶(9)——C语言文件操作

本章重点 为什么使用文件什么是文件文件的打开和关闭文件的顺序读写文件的随机读写文本文件和二进制文件文件读取结束的判定文件缓冲区 文章目录本章重点1.为什么使用文件2.什么是文件2.1程序文件2.2数据文件2.3文件名3.文件打开和关闭3.1 文件指针3.2文件的打开和关闭4. 文件…

【蓝桥杯嵌入式】第十一届蓝桥杯嵌入式省赛(第二场)程序设计试题及其题解

题目再现 题目分析 通过阅读本届试题可知&#xff0c;其功能比较单一&#xff0c;除了试题中常客——LED、LCD、按键三巨头外&#xff0c;还包含了定时器的PWM以及ADC读取这两个部分&#xff0c;考察的重点在于对定时器产生PWM的应用以及如何修改PWM的占空比&#xff0c;完全消…