分布式应用全链路跟踪实现

2023-10-24 10:04

本文主要是介绍分布式应用全链路跟踪实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

随着分布式和微服务架构的发展,应用系统和服务组件之间的调用关系愈发复杂。如何精确的展示和快速定位服务单元之间的调用关系,实时观测应用系统整体链路情况,对应用系统的监控运维提出了挑战。本文简要介绍分布式应用链路跟踪的实现方式、OpenTracing规范以及对比不同全链路开源组件的实现。


1、全链路跟踪介绍
1.1 全链路跟踪背景

随着分布式和微服务技术的发展演进,越来越多的系统从单体应用向分布式微服务架构转型。在微服务架构下应用服务被拆分为不同的服务模块,这些服务模块之间的调用关系也变得错综复杂,客户端的连接请求可能需要在多个不同的服务单元之间进行流转。此时如果某个服务单元或者模块出现异常,很难快速直观的去定位到异常点,以及对整个系统的影响范围和影响程度、爆炸半径等。如下图所示为典型的微服务架构:

在这里插入图片描述

为了分析和解决分布式架构下故障的快速定位分析、故障影响的精确判断、服务模块之间的依赖关系和调用关系以及整个应用系统调用链路的整体观测性,引入了全链路跟踪技术。全链路跟踪技术可以将一次分布式请求还原成调用链路,将一次分布式请求的调用情况集中展示,比如各个服务节点上的耗时、请求具体到达哪台机器上、每个服务节点的请求状态等等。全链路跟踪的主要有以下功能点:

  • 故障快速定位:通过调用链结合业务日志可以快速定位错误信息,迅速发现和解决问题。
  • 链路性能可视化:各个阶段的链路耗时、服务依赖关系可以通过可视化界面展现出来,帮助开发人员更好地了解系统的运行状态和性能情况。
  • 链路分析:通过分析链路耗时、服务依赖关系可以得到用户的行为路径,汇总分析应用在很多业务场景下。

下图是一个简单的微服务架构下的完整调用链路视图:

在这里插入图片描述

1.2 全链路跟踪实现原理

链路跟踪最早由Google提出,并发表了一篇论文《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》,介绍Google自研的分布式链路跟踪系统Dapper的实现原理和设计实现。随后出现了一众开源产品如Zipkin、Jaeger等,但是各个开源的分布式链路跟踪方案互不兼容,为了统一标准接口,诞生了OpenTracing。OpenTracing于2016年10月加入CNCF基金会,它是一个中立的(厂商无关、平台无关)分布式追踪的 API 规范,提供统一接口,可方便开发者在自己的服务中集成一种或多种分布式追踪的实现。

OpenTracing是一个分布式跟踪系统,它提供了一个平台无关、厂商无关的API,使得开发人员能够方便地添加(或更换)追踪系统的实现。在全链路跟踪中,OpenTracing通过在HTTP头中注入唯一标识符(trace ID)来实现追踪。这个唯一标识符可以关联所有的HTTP请求,从而形成一个完整的调用链。

1.2.1 Tracing定义

在应用系统中,Tracing指的是使用特定的日志记录程序的执行信息,与之相近的还有metrics和logging两个概念。

  • Tracing:指使用特定的日志记录程序的执行信息,记录单个请求的处理流程,包括服务调用和处理时长等信息,用于诊断和优化分布式系统。
  • Metrics:可聚合的数据,通常包括计数器(Counter)、量表(Gauge)和直方图(Histogram)等,用于度量和观察系统的行为。Metrics可以用来衡量一个系统的性能,例如请求的数量、响应的时间等。
  • Logging:用于记录离散的事件,包含程序执行到某一点或某一阶段的详细信息。Logging可以用来记录程序的行为,帮助开发人员调试和解决问题。

在这里插入图片描述

Tracing、Metrics和Logging这三种监控类型交集的情况比较常见:

  • Logging&Metrics:Metrics提供系统层面的统计数据,如系统总请求量、响应时间等;logging则提供系统的详细行为,比如统计某段时间SQL各类请求访问的总数等;
  • Metrics&Tracing:Metrics可以看做是宏观层面的tracing,tracing更关注微观层面某个请求的处理流程、处理时间等,比如单个请求中SQL执行时长、gpc调用次数等;
  • Tracing&Logging:Logging记录的是一些离散的事件、tracing则是记录的这些请求的处理过程,比如在请求过程中详细的处理记录日志等信息。

在分布式系统中,Tracing、Metrics和Logging作为三种不同类型的监控方式,侧重点不同,并且有不同的工具来实现:Tracing基于OpenTracing规范实现请求流程的链路分析、Metrics基于Prometheus实现应用系统指标的监控分析、Logging基于ELK或EFK实现日志数据的采集和分析。

1.2.2 OpenTracing规范

OpenTracing的出现主要是为了解决不同的分布式链路追踪平台的API兼容问题,通过提供与平台和厂商无关API的方式,使得开发人员能够很方便地切换追踪系统。在OpenTracing中有几个基本概念:

在这里插入图片描述

1)Span

Span是分布式跟踪的主要构建块,表示分布式系统中完成的单个工作单元。Span之间通过嵌套或者顺序排列建立逻辑因果关系。在OpenTracing中的一条Trace被认为是一个由多个Span组成的有向无环图(DAG)。每个Span根据OpenTracing规范封装了以下状态:

  • 一个操作名称
  • 开始时间戳和结束时间戳
  • Span Tag:一组键值对构成的Span标签集合,其中键必须为字符串类型,值可以是字符串、bool值或者数字;
  • Span Log:一组Span的日志集合;
  • SpanContext:Trace的全局上下文信息;
  • References:Span之间的引用关系;

在OpenTracing的一条Trace中,一个Span可以和多个Span之间存在因果关系,在OpenTracing中定义了ChildOf和FollowsFrom两种引用关系,如下所示:

  • ChildOf关系:一个Span可能是一个父级Span的孩子,即为ChildOf关系。比如在一个http请求中调用服务端产生的span和发起调用的客户端的span,就构成ChildOf关系。
  • FollowsFrom关系:在分布式系统中,一些上游系统不依赖于下游系统的执行结果,比如上游系统通过消息队列异步方式向下游系统发送消息,这样下游系统对应的子Span和上游系统对应的父Span之间就是FollowsFrom关系。
Causal relationships between Spans in a single Trace[Span A]  ←←←(the root span)|+------+------+|             |[Span B]      [Span C] ←←←(Span C is a `ChildOf` Span A)|             |[Span D]      +---+-------+|           |[Span E]    [Span F] >>> [Span G] >>> [Span H]↑(Span G `FollowsFrom` Span F)

2)Tags

每个Span可以有多个键值对形式的Tags,Tags是没有时间戳的,只是为Span添加一些简单解释和补充信息。

3)Logs

每个Span可以进行多次Logs操作,每一次Logs操作,都需要带一个时间戳,以及一个可选的附加信息。

4)SpanContext

SpanContext表示进程边界,在跨进调用时需要将一些全局信息,例如TraceId、当前SpanId等信息封装到Baggage中传递到另一个进程中。

备注:在OpenTracing官网上看到OpenTracing相关的技术已经迁移到OpenTelemetry上。OpenTelemetry是OpenTracing和OpenCensus两个项目的合并,是一个更加强大的监控解决方案。它可以收集所有类型的遥测数据,如日志、指标和调用链,并且是一个开箱即用的API、SDK和库的合集。其中一条trace如下所示:

{"name": "hello-greetings","context": {"trace_id": "0x5b8aa5a2d2c872e8321cf37308d69df2","span_id": "0x5fb397be34d26b51"},"parent_id": "0x051581bf3cb55c13","start_time": "2022-04-29T18:52:58.114304Z","end_time": "2022-04-29T22:52:58.114561Z","attributes": {"http.route": "some_route2"},"events": [{"name": "hey there!","timestamp": "2022-04-29T18:52:58.114561Z","attributes": {"event_attributes": 1}},{"name": "bye now!","timestamp": "2022-04-29T18:52:58.114585Z","attributes": {"event_attributes": 1}}]
}

其中包括span_id和parent_id、traceid、start_time和end_time、attributes和events等信息。

1.2.3 全链路Trace示例

回到1.1中微服务架构下的完整调用链路视图,在服务调用的时候加上spanid、traceid和parentid,其中traceid为链路请求全局唯一id。如下所示:

在这里插入图片描述

  • 节点Service1:SpanID=AAA1,ParentID=null,接收到客户端请求并发送请求到Service 2
  • 节点Service2:SpanID=BBB1,ParentID=AAA1,接收到Service 1的请求并发送请求到下一步
  • 节点缓存服务:SpanID=CCC1,ParentID=BBB1,接收到Service2的请求并返回结果
  • 节点Service3:SpanID=DDD1,ParentID=BBB1,接收到Service2的请求并发送请求到下一步
  • 节点Service4:SpanID=EEE1,ParentID=BBB1,接收到Service2的请求并发送请求到下一步
  • 节点数据库服务:SpanID=FFF1,ParentID=DDD1,接收到Service3的请求并返回结果;SpanID=GGG1,ParentID=EEE1,接收到Service4的请求并返回结果

通过ParentID找到父节点,并通过全局唯一的traceID实现链路跟踪。

1.3 全链路跟踪开源组件

自Google Dapper系统开放以来,出现很多分布式链路跟踪的产品,如Pinpoint、Zipkin、Skywalking、Jaeger等,接下去将简要介绍对比。

1)Pinpoint

Pinpoint是由一个韩国团队实现并开源,针对Java编写的大规模分布式系统设计,通过JavaAgent的机制做字节代码植入,实现加入traceid和获取性能数据的目的,对应用代码零侵入。

在这里插入图片描述

官方网站:https://github.com/pinpoint-apm/pinpoint

2)SkyWalking

SkyWalking是一款国产的开源框架,专为微服务、云原生架构和基于容器(Docker、K8s、Mesos)架构而设计的分布式系统的应用程序性能监视工具,包括了分布式追踪、服务网格遥测分析、度量聚合和可视化一体化解决方案。SkyWalking支持Java、.Net Core、PHP、NodeJS、Golang等多种语言探针,支持Envoy + Istio构建的Service Mesh。

SkyWalking的客户端通过HTTP或gRPC方式向SkyWalking收集器发送链路调用数据。SkyWalking收集器对接收到的链路信息进行分析和聚合,并存储到服务端数据库,支持的存储组件有ES、H2、MySQL、TiDB和Sharding Sphere等。SkyWalking UI则提供了链路调用信息的可视化和检索。以下为Skywalking架构图:

在这里插入图片描述

官方网站:http://skywalking.apache.org/

3)Zipkin

Zipkin是由Twitter开源,是分布式链路调用监控系统,聚合各业务系统调用延迟数据,达到链路调用监控跟踪。Zipkin基于Google的Dapper论文实现,主要完成数据的收集、存储、搜索与界面展示。Zipkin组件如下图所示,包括Collector、Storage、Search和Web UI:

  • Collector:Zipkin的一个常驻进程组件,主要负责提供对外部系统的接口,以收集、校验、存储以及索引追踪数据。
  • Storage:存储模块,真正服务于Zipkin收集到的追踪数据的存储。默认情况下,Zipkin将这些信息存储在内存中,也可以修改存储策略,通过使用其他存储组件将追踪信息存储到数据库或ElasticSearch中。
  • Zipkin Query Service(API):通过这个API组件提供外部访问接口,用于查找和检索链路调用信息。
  • Web UI:Zipkin查询链路追踪的界面,用户可以通过简洁直观的web UI来检索数据和查看调用链路。

在这里插入图片描述

官方网站:https://zipkin.io/

4)云原生链路监控组件Jaeger

Jaeger是CNCF云原生项目之一,由Uber开源的分布式追踪系统,兼容Open Tracing API。Jaeger主要用于微服务的监控和请求追踪,支持分布式上下文传播、请求报错分析、服务的调用网络分析以及性能/延迟优化。Jaeger在架构上支持分布式追踪和性能监控,包括多个组件和模块,以实现数据收集、存储、查询和可视化等功能。如下图所示:

  • jaeger-client:Client是应用程序的一部分,它负责在每个服务或应用中注入追踪代码。这个代码收集有关请求的元数据,例如开始时间、结束时间、服务名称等,并将其发送到Jaeger Agent。Client库有不同的版本,针对不同的编程语言,如Java、Python、Go等。
  • jaeger-agent:Agent是一个运行在每个服务实例中的代理程序,它负责接收并转发从Client发送来的追踪数据。Agent通过UDP将收集到的追踪信息批量发送给Collector。
  • jaeger-collector:Collector是Jaeger的核心组件之一,它负责接收从Agent发送来的追踪数据,并进行处理。这些数据首先会被验证和索引,然后被转换并存储在DB中。
  • DB:Jaeger中用于存储追踪数据的组件。Jaeger支持多种存储后端,例如Kafka、Elasticsearch和Cassandra。数据在DB中以trace ID为单位进行存储,每个trace ID下都会保存该请求的完整调用链路信息。
  • jaeger-query:用于检索链路调用信息,通过这个接口查询和展示存储在DB中的追踪数据。

在这里插入图片描述

官方网站:https://www.jaegertracing.io/

5)各种全链路跟踪方案对比

在这里插入图片描述

对比上述四种组件,Zipkin本身实现相对简单,指标的分析和展示需求需要二次开发工作;Jaeger是对Zipkin的优化,在WebUI和传输协议上进行了改进,但也无告警功能;Pinpoint不支持OpenTracing规范,并且不支持查询单个调用链,二次开发难度较高;SkyWalking功能较为齐全,探针性能损耗低,同时也支持多种语言的客户端,并且中文社区非常活跃。

接下去将重点介绍基于Skywalking的全链路跟踪实现。


参考资料:

  1. https://opentelemetry.io/docs/concepts/signals/traces/
  2. https://www.cnblogs.com/dalianpai/p/12853683.html
  3. https://blog.csdn.net/fegus/article/details/126498887
  4. https://blog.csdn.net/eight_eyes/article/details/117330608
  5. https://segmentfault.com/a/1190000040364737

这篇关于分布式应用全链路跟踪实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/274406

相关文章

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略 1. 特权模式限制2. 宿主机资源隔离3. 用户和组管理4. 权限提升控制5. SELinux配置 💖The Begin💖点点关注,收藏不迷路💖 Kubernetes的PodSecurityPolicy(PSP)是一个关键的安全特性,它在Pod创建之前实施安全策略,确保P

工厂ERP管理系统实现源码(JAVA)

工厂进销存管理系统是一个集采购管理、仓库管理、生产管理和销售管理于一体的综合解决方案。该系统旨在帮助企业优化流程、提高效率、降低成本,并实时掌握各环节的运营状况。 在采购管理方面,系统能够处理采购订单、供应商管理和采购入库等流程,确保采购过程的透明和高效。仓库管理方面,实现库存的精准管理,包括入库、出库、盘点等操作,确保库存数据的准确性和实时性。 生产管理模块则涵盖了生产计划制定、物料需求计划、

C++——stack、queue的实现及deque的介绍

目录 1.stack与queue的实现 1.1stack的实现  1.2 queue的实现 2.重温vector、list、stack、queue的介绍 2.1 STL标准库中stack和queue的底层结构  3.deque的简单介绍 3.1为什么选择deque作为stack和queue的底层默认容器  3.2 STL中对stack与queue的模拟实现 ①stack模拟实现

基于51单片机的自动转向修复系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机