分布式系统中的Dapper与Twitter Zipkin:链路追踪技术的实现与应用

目录

一、什么是链路追踪?

二、核心思想Dapper

(一)Dapper链路追踪基本概念概要

(二)Trace、Span、Annotations

Trace

Span

Annotation

案例说明

(三)带内数据与带外数据

带外数据

带内数据

数据的传递与集中

(四)采样

采样的目的

采样率的调整

采样机制的实现

(五)存储

为什么选择 BigTable

存储结构

查询和分析

三、Twitter的Zipkin

(一)架构概述

(二)Zipkin v2 版本的数据模型

Span 消息类型

Endpoint 消息类型

Annotation 消息类型

(三)Zipkin带内数据和带外数据

带内数据(b3-propagation)

带外数据

(四)Zipkin 采样

采样状态

采样决策

实现和应用

(五)数据埋点及上报过程

四、总结


干货分享,感谢您的阅读!

在当今的互联网时代,网络应用已经成为我们生活中不可或缺的一部分。从在线购物到社交媒体,再到银行交易和医疗服务,这些应用无不依赖于庞大而复杂的分布式系统。然而,当我们遇到网页加载缓慢或功能异常时,我们可能会感到沮丧,却很少去思考背后究竟发生了什么。

通过分布式链路追踪,我们不仅可以了解各个服务之间的调用关系,还可以获取每个请求在各个服务中的详细时间信息。接下来,我们将聊聊分布式链路追踪,揭开这项技术的神秘面纱,探索它如何在复杂的分布式系统中发挥至关重要的作用,确保我们的网络应用始终高效、可靠地为用户服务。

一、什么是链路追踪?

随着分布式系统变得日益复杂,越来越多的组件开始走向分布式化,例如微服务、分布式数据库和分布式缓存等,使得后台服务构成了一个庞大而复杂的网络。在提高服务能力的同时,这种复杂的网络结构也让问题定位变得更加困难。当一个请求在多个服务之间穿梭时,任何一个服务的调用失败都会引发问题。此时,查找具体的异常来源变得十分抓狂,问题定位和处理的效率也会非常低。

分布式链路追踪正是为了解决这个问题而生。它就像一位侦探,能够将一次分布式请求的全过程还原成一条详细的调用链路。通过分布式链路追踪,我们可以集中展示一次请求在各个服务节点上的详细情况,比如每个节点的响应时间、请求具体到达的机器,以及每个节点的请求状态等信息。

想象一下,分布式链路追踪就像是在复杂的公路系统中安装了GPS。每辆车的行驶路径、停靠站点和行驶时间都清晰可见。当某一段路出现拥堵时,GPS能迅速指示问题所在,帮助我们快速采取措施,恢复道路畅通。同样,分布式链路追踪让我们在面对分布式系统中的故障时,能够迅速定位问题所在,从而提高问题处理的效率,确保系统的稳定运行。

二、核心思想Dapper

目前业界的链路追踪系统,如Twitter的OpenZipkin、Uber的Jaegertracing、阿里的链路监控-鹰眼、蚂蚁金服的SOFATracer、美团的Mtrace等,基本上都受到了Google发表的Dapper的启发(针对Dapper的讲解见:大规模分布式系统跟踪基础设施Dapper)。

Dapper是Google提出的一套分布式链路追踪系统,它详细阐述了在分布式系统,特别是微服务架构中,如何实现链路追踪的概念、数据表示、埋点、传递、收集、存储与展示等技术细节。

(一)Dapper链路追踪基本概念概要

Dapper的核心思想是通过对分布式系统中各个服务的调用情况进行追踪和记录,生成一条完整的调用链路,从而帮助开发和运维人员快速定位和解决系统中的问题。它不仅定义了一套标准的数据模型来表示链路追踪信息,还提出了一系列的方法和工具,用于在分布式环境中收集和展示这些数据。

具体来说,Dapper在以下几个方面对链路追踪进行了详细的说明:

  1. 数据表示:Dapper定义了一套标准的数据格式,用于表示一次请求在分布式系统中经过的所有节点和调用关系。这些数据通常包括Trace ID、Span ID、Parent ID、开始时间、结束时间等

  2. 埋点:Dapper提出了一种无侵入式的埋点方法,通过在应用代码中插入少量代码,即可实现对分布式调用的监控和记录。

  3. 数据传递:在分布式系统中,调用链路的上下游服务之间需要传递追踪信息。Dapper定义了一套传递机制,使得追踪信息可以在不同的服务之间传递和共享。

  4. 数据收集:Dapper设计了一套高效的数据收集机制,能够从分布式系统中的各个服务节点收集追踪数据,并将其集中存储起来。

  5. 数据存储与展示:Dapper使用分布式存储系统来存储追踪数据,并提供了一套查询和展示工具,使得开发和运维人员可以方便地查看和分析调用链路。

Dapper的这些创新和实践,为后续的链路追踪系统提供了宝贵的经验和参考,极大地推动了分布式链路追踪技术的发展,详细的介绍和说明见 大规模分布式系统跟踪基础设施Dapper。

(二)Trace、Span、Annotations

为了实现链路追踪,Dapper提出了三个核心概念:Trace、Span和Annotation。

Trace

Trace的含义比较直观,它表示一次请求经过后端所有服务的完整路径。可以将其想象成一棵树状的图形结构,展示了请求从开始到结束所经过的每一个节点。

每一条链路(即每一个Trace)都有一个全局唯一的Trace ID,用来标识这条链路。

Span

Span是Trace中的基本单元,表示一个具体的操作或调用。每个Span由一个唯一的Span ID标识,并且有一个Parent ID来表示它的父Span,从而形成父子关系。这种层级关系构建了Trace的树状结构。一个Span通常包含以下信息:

  • Span ID:唯一标识该Span的ID。
  • Parent ID:标识父Span的ID,如果没有父Span,则为空。
  • 操作名称:例如,HTTP请求的URL或数据库查询的名称。
  • 时间戳:操作开始和结束的时间,用于计算耗时。
  • 服务节点信息:包括服务名称、IP地址和端口等。

Annotation

Annotation是对Span的补充,用于记录特定时间点的事件或状态信息。

Dapper中定义了四种关键的Annotation:

  • cs(Client Send):客户端发送请求的时间。
  • sr(Server Receive):服务端接收请求的时间。
  • ss(Server Send):服务端发送响应的时间。
  • cr(Client Receive):客户端接收响应的时间。

这些Annotation帮助我们详细了解一次调用的全过程,尤其是客户端和服务端之间的交互。除此之外,用户还可以自定义Annotation,用于记录特定的业务事件或状态。

案例说明

让我们看一个具体的例子,假设一个前端服务(frontend.request)调用了一个后端服务(backend.dosomething),并且backend服务又调用了一个辅助服务(helper.call)。

这个过程中会产生如下的Span(为了加深理解,暂时忽略backend.call):

  • frontend.request:生成一个Trace ID和一个Span ID(称为root span),记录客户端发送请求(cs)和接收响应(cr)的时间。例如,Trace ID: trace1,Span ID: span1。
  • backend.dosomething:生成一个新的Span ID,并记录服务端接收请求(sr)和发送响应(ss)的时间。这个Span的Parent ID是frontend.request的Span ID。例如,Trace ID: trace1,Span ID: span2,Parent ID: span1。
  • helper.call:生成一个新的Span ID,记录辅助服务的开始和结束时间。这个Span的Parent ID是backend.dosomething的Span ID。例如,Trace ID: trace1,Span ID: span3,Parent ID: span2。

一个完整的Span由客户端和服务端两个部分的信息合并而成。按照时间顺序:

  • 客户端(Client):发送请求,产生“Client Send”(cs)事件。
  • 服务端(Server):接收请求,产生“Server Receive”(sr)事件。处理请求后发送响应,产生“Server Send”(ss)事件。
  • 客户端(Client):接收响应,产生“Client Receive”(cr)事件。

通过合并这些信息,一个Span不仅展示了客户端和服务端之间的交互过程,还记录了整个请求的详细时间和状态。这样就可以通过这些Span和它们的父子关系,清晰地看到整个调用链路,并快速定位和解决系统中的问题。

(三)带内数据与带外数据

在链路追踪过程中,链路信息的还原依赖于两种数据:带内数据和带外数据。这两种数据相辅相成,共同构成了完整的链路追踪信息。

带外数据

带外数据是由各个节点产生的事件信息,例如Client Send(cs)、Server Send(ss)等。带外数据可以独立于链路的整体结构生成,并且需要集中上报到存储端进行分析和存储。这些数据通常包括:

  • 时间戳:记录事件发生的具体时间。
  • 事件类型:例如,cs(客户端发送)、sr(服务端接收)、ss(服务端发送)、cr(客户端接收)等。
  • 节点信息:包括服务名称、IP地址和端口等。

带外数据提供了详细的事件信息,帮助分析和理解每个节点的具体操作和状态。

带内数据

带内数据包括Trace ID、Span ID和Parent ID,用来标识Trace、Span,以及Span在一个Trace中的位置。带内数据需要从链路的起点一直传递到终点,通过带内数据的传递,可以将一个链路的所有过程串联起来。带内数据通常包括:

  • Trace ID:唯一标识一个请求的整个链路。
  • Span ID:唯一标识一个操作或调用。
  • Parent ID:标识当前Span的父Span。

带内数据确保了链路的连续性,使我们能够跟踪一次请求从起点到终点的完整路径。

数据的传递与集中

通过带内数据的传递,可以将一个链路的所有过程串联起来。例如,当一个前端服务(frontend.request)调用一个后端服务(backend.dosomething)时,前端服务会生成一个Trace ID和一个Span ID,并将这些带内数据传递给后端服务。后端服务在处理请求时,会生成新的Span ID和Parent ID(即前端服务的Span ID),并将这些信息传递给下一个服务,以此类推。

与此同时,各个节点会生成带外数据,并将这些数据上报到存储端。存储端通过带内数据,将所有的事件信息关联起来,从而还原出完整的调用链路。带外数据提供了详细的时间和事件信息,而带内数据提供了链路的结构和位置,两者结合使得链路追踪系统能够全面展示和分析分布式请求的过程和状态。

假设我们有一个前端服务调用后端服务,再调用数据库服务的场景:

  • 前端服务(frontend.request):生成Trace ID:trace1,生成Span ID:span1,记录Client Send(cs)事件,将Trace ID和Span ID传递给后端服务
  • 后端服务(backend.dosomething):,接收到Trace ID:trace1,接收到Parent ID:span1,生成新的Span ID:span2,记录Server Receive(sr)事件,将Trace ID、Span ID和Parent ID传递给数据库服务
  • 数据库服务(database.query):,接收到Trace ID:trace1,接收到Parent ID:span2,生成新的Span ID:span3,记录Server Receive(sr)事件

各个服务将产生的带外数据上报到存储端,带内数据则通过链路传递,使得存储端能够将所有数据关联起来,形成完整的调用链路。通过带内数据和带外数据的结合,链路追踪系统能够准确、详细地记录和还原分布式系统中每一次请求的全过程。

(四)采样

在分布式系统中,每个请求都会生成一个完整的调用链路。若将每一个请求的链路数据都上报和存储,不仅会导致性能消耗,还会浪费大量存储资源。因此,Dapper等链路追踪系统通常不会上报所有的Span数据,而是使用采样的方式来控制数据量。

采样的目的

采样的主要目的是在确保能够发现性能瓶颈和问题的同时,减少系统的性能开销和存储资源消耗。通过对请求进行抽样,仅上报一部分请求的链路数据,可以达到以下目的:

  1. 性能优化:避免因上报大量数据导致的系统性能下降。
  2. 存储节约:减少存储资源的占用,避免数据量过大带来的存储压力。
  3. 有效监控:通过合理的采样率,依然能够发现和分析系统中的主要问题和瓶颈。

采样率的调整

采样率是指在所有请求中选择进行链路追踪和上报的比例。例如,采样率为10%时,只有10%的请求会被上报其完整的链路数据。采样率的调整可以是静态的,也可以是自适应的。自适应采样通过实时监控系统的负载情况,动态调整采样率,以在高负载和低负载情况下都能保持合理的采样比例。

采样机制的实现

在Dapper和其他链路追踪系统(如Zipkin、Jaeger)中,采样机制通常由采集端(即各个服务节点)实现。每个服务节点在生成Span时,会根据设定的采样率决定是否上报该Span的数据。

例如,在Zipkin中,采样机制可以通过配置采样策略来实现:

  • 固定采样率:设定一个固定的采样比例,对所有请求进行统一的采样。
  • 自适应采样:根据实时负载情况,动态调整采样率。
  • 基于请求类型的采样:根据请求的不同类型(如关键请求和普通请求)设定不同的采样率。

假设一个系统设定了10%的采样率:

  1. 前端服务(frontend.request)接收到请求,生成一个Trace ID,并随机决定是否上报该请求的链路数据。
  2. 若决定上报,则生成Span ID,并将采样决定传递给后端服务。
  3. 后端服务(backend.dosomething)接收到前端服务的请求,并继承前端服务的采样决定,继续生成和上报Span数据。
  4. 数据库服务(database.query)同样接收到后端服务的请求,继承采样决定,生成并上报Span数据。

通过这种机制,整个链路中的所有服务节点都会统一按照采样决定上报数据,确保采样的一致性。

采样是分布式链路追踪系统中的重要机制,通过控制上报的数据量,实现了性能优化和存储节约。在实际应用中,采样率的合理设定和调整,可以帮助系统在高效监控的同时,避免因大量数据上报导致的性能和存储问题。

(五)存储

分布式链路追踪系统中的 Span 数据在经过收集和上报之后,需要集中存储在一个地方,以便后续的查询和分析。Dapper选择了使用 Google 的 BigTable 数据仓库来存储这些数据。

为什么选择 BigTable

BigTable 是一种分布式存储系统,具有高可扩展性和高性能的特点,特别适合用于存储大规模的结构化数据。由于分布式链路追踪数据的特性,各种 Trace 的 Span 数量不尽相同,BigTable 的稀疏表格布局非常适合这一场景。

  • 稀疏表格布局:每个 Trace 中的 Span 数量不同,BigTable 的设计允许这些 Span 数据分散存储,而不会造成存储空间的浪费。
  • 按 TraceID 和 SpanID 存储:Span 数据按照 TraceID 和 SpanID 进行存储,使得查询和检索特定 Trace 及其相关的所有 Span 变得非常高效。
  • 无状态收集程序:由于 Span 数据的分散存储方式,收集程序无需进行复杂的计算和状态维护,只需按照 TraceID 和 SpanID 插入数据即可。

存储结构

在 BigTable 中,Span 数据以稀疏表的形式存储,每行对应一个 Trace,行内的列则对应该 Trace 下的各个 Span。如下图所示:

这种存储结构具有以下优点:

  • 高效查询:通过 TraceID,可以快速查询到一个 Trace 及其所有相关的 Span 数据。
  • 灵活存储:不同 Trace 可以有不同数量的 Span,BigTable 的稀疏表格布局能很好地适应这种变化。
  • 易于扩展:BigTable 的分布式架构使其可以轻松扩展以应对数据量的增加。

查询和分析

使用 BigTable 存储 Span 数据后,查询和分析变得非常方便。可以通过简单的行查询,快速获取一个 Trace 的完整调用链数据,从而进行性能分析、故障定位等操作。具体而言,查询一个 Trace 的步骤如下:

  1. 获取 TraceID:确定需要查询的 TraceID。
  2. 查询 TraceID 对应的所有 Span:在 BigTable 中,按照 TraceID 查询该 Trace 下的所有 Span。
  3. 数据解析:将查询到的 Span 数据按照时间顺序和层级关系进行解析,还原出完整的调用链。

通过这种方式,可以高效地进行链路数据的查询和分析,快速定位和解决分布式系统中的问题。

三、Twitter的Zipkin

Zipkin 最初由 Twitter 开发并开源,后来成为了一个 Apache 认可的开源项目。它提供了一种方式来收集、存储、可视化和查询服务之间的分布式追踪数据。Zipkin 的设计依旧受到了 Google 的 Dapper 论文启发,致力于解决微服务架构下的调用链路跟踪问题。可以理解Zipkin是Dapper的一种开源实现,也是业界做链路追踪系统的一个重要参考,其系统也可以即插即用。

(一)架构概述

Zipkin 的整体架构包括以下核心组件:

  • Collector(收集器):负责接收来自各个微服务的跟踪数据,并将其存储到后端存储系统中。
  • Storage(存储):用于持久化存储跟踪数据,支持多种后端存储系统,提供高效的数据查询和检索功能。适配底层的存储系统,zipkin提供默认的in-memory存储,并支持Mysql、Cassandra、ElasticSearch存储系统。
  • Query(查询服务):提供查询接口和用户界面,用于用户查看和分析存储在 Zipkin 中的跟踪数据,接口的定义见zipkin-api。
  • Web UI(用户界面):提供可视化的界面,让用户能够直观地查看和分析调用链路数据。

Zipkin 将 Collector、Storage、API、UI 打包为一个可执行的 JAR 包,用户可以直接下载并运行。

(二)Zipkin v2 版本的数据模型

Zipkin v2 版本的数据模型定义了跟踪数据的结构,主要包括 Span、Endpoint 和 Annotation 这三个消息类型。

Span 消息类型

Span 用于表示一次请求的跟踪信息,包括请求的起始时间、持续时间、节点信息、事件列表等。

  • trace_id: 跟踪标识符,通常为 16 或 32 位的十六进制字符串,唯一标识整个请求链路。
  • parent_id: 父 Span 的标识符,如果没有父 Span,则为空。
  • id: 当前 Span 的标识符。
  • kind: Span 的类型,可以是客户端、服务器、生产者或消费者等几种类型。
  • name: Span 的名称,例如 RPC 调用的名称。
  • timestamp: Span 的开始时间戳,以微秒为单位。
  • duration: Span 的持续时间,即从客户端发送请求到服务器返回响应的时间,以微秒为单位。
  • local_endpoint: 本地节点的信息,包括服务名称、IP 地址和端口号。
  • remote_endpoint: 远端节点的信息,用于标识被调用服务的信息。
  • annotations: 事件列表,每个事件包含一个时间戳和描述该事件的名称。
  • tags: 用户自定义的键值对信息,例如 {“user-id”:”lidawn”}
  • debug: 表示是否为调试模式,如果设置为 true,则会忽略采样率限制,强制上报该 Span。
  • shared: 暂时未理解其具体含义。

Endpoint 消息类型

Endpoint 用于描述节点的基本信息。

  • service_name: 节点所属的服务名称。
  • ipv4: 节点的 IPv4 地址。
  • ipv6: 节点的 IPv6 地址。
  • port: 节点的端口号。

Annotation 消息类型

Annotation 用于表示事件的时间戳和事件的名称。

  • timestamp: 事件发生的时间戳,以微秒为单位。
  • value: 描述事件的名称。

这些消息类型构成了 Zipkin v2 版本的数据模型,用于存储和表示分布式系统中请求的跟踪信息。

(三)Zipkin带内数据和带外数据

在 Zipkin 中,带内数据和带外数据扮演着不同但互补的角色,对于全面的链路追踪和系统监控至关重要。

带内数据(b3-propagation)

带内数据主要指的是通过请求传递的关键信息,通常包括以下几个核心字段:

  1. TraceId: 标识一条完整请求链路的唯一 ID,通常是一个 16 或 32 位的十六进制字符串。
  2. SpanId: 表示当前 span 的 ID,用于唯一标识一个请求中的某个操作或调用。
  3. ParentSpanId: 表示当前 span 的父 span 的 ID,用于构建请求的调用关系树。
  4. Sampled: 标记当前请求是否被采样,决定是否上报这个 span 的数据。

带内数据通过请求头或者请求体中的特定字段传递,例如使用 HTTP 头部的自定义字段(如 X-B3-TraceId、X-B3-SpanId)或者在 RPC 框架中使用特定的上下文传递机制(如 gRPC 的 Context)。这些数据在请求传递过程中串联了整个分布式系统中各个服务节点的调用链路,使得整个请求的执行路径可以被还原和跟踪。

带内数据主要用于链路追踪和性能优化。通过分析带内数据,可以还原和可视化每个请求的完整调用链路,诊断性能瓶颈和请求异常。

带外数据

带外数据则是指每个服务节点独立产生的事件和度量数据,通常包括:

  1. 性能指标: 如响应时间、吞吐量、请求成功率、错误率等。
  2. 系统状态: 如 CPU 使用率、内存使用量、磁盘 I/O 等。
  3. 异常信息: 如超时事件、异常堆栈信息等。

这些数据通常由每个服务节点的监控代理或者自定义的度量代码生成,并通过日志系统、监控系统或者专门的度量收集器(如 Prometheus、StatsD 等)进行收集和存储。带外数据的收集和分析能够帮助监控系统的健康状况和性能表现,并在出现问题时提供实时的告警和诊断支持。

带外数据主要用于系统监控和运维通过分析带外数据,可以监控系统的实时运行状态,预测和预防潜在的故障,并进行容量规划和资源优化。

(四)Zipkin 采样

在 Zipkin 中,采样是控制哪些分布式跟踪数据应该被收集和上报的重要机制。它通过设置 sampled 字段来决定每个 span 是否应该被记录和报告。

采样状态

Zipkin 的 sampled 字段有四种可能的状态:

  1. Defer: 表示采样状态尚未确定。这种状态通常在下游服务收到请求时,根据自身的采样策略决定是否重新确定采样状态。

  2. Deny: 表示该 span 不应该被采样和上报。如果一个 span 被标记为 Deny,它将不会生成或者传播给下游服务。

  3. Accept: 表示该 span 需要被采样和上报。如果一个 span 被标记为 Accept,它将被记录和传递给下游服务。

  4. Debug: 通常用于开发环境中,强制性地标记 span 为采样状态。无视真实的采样率,所有的 span 都会被标记为 Debug。

采样决策

采样决策在整个请求链路中是逐层传递和遵循的。通常情况下,根 span 的 sampled 字段由系统的全局采样率决定。例如,如果全局采样率设为 50%,则只有大约一半的根 span 会被标记为 Accept,其余的会被标记为 Deny。

对于非根 span,它们的 sampled 字段通常依赖于父 span 的 sampled 字段决定。如果父 span 被采样(Accept),则其子 span 通常也会被采样,除非在中间的某个节点上出现了特定的采样策略(如 Defer)。

实现和应用

在实际应用中,Zipkin 的客户端和中间件库通常会根据配置和运行环境自动处理采样逻辑。例如,在 HTTP 或 gRPC 请求中,可以通过传递特定的请求头(如 X-B3-Sampled)来标记和传递 sampled 字段,以确保整个分布式系统中的一致性采样策略。

(五)数据埋点及上报过程

根据zipkin的span定义,模拟一个简单的调用过程,分析数据埋点和上报过程。

  1. server-1发起对server-2的调用,生成一个root_span, 生成trace_id,id,parent_id为空,并记录kind为CLIENT,name,timestamp,local_endpoint(server-1)信息,并将trace_id,id,parent_id,sampled信息传递给server-2。
  2. server-2收到server-1的请求,并收到trace_id,id,parent_id,sampled信息,生成一个相同的span,并记录kind为SERVER,name,timestamp,local_endpoint(server-2)信息。
  3. server-2发起对server-3的调用,生成一个新的span,该span为root_span的子span。 并记录kind为CLIENT,name,timestamp,local_endpoint(server-2)信息,并将trace_id,id,parent_id,sampled信息传递给server-3。
  4. server-3收到server-2的请求,并收到trace_id,id,parent_id,sampled信息,生成一个相同的span,并记录kind为SERVER,name,timestamp,local_endpoint(server-3)信息。
  5. server-3回复server-2的调用,记录duration,并上报span。
  6. server-2收到server-3的回复,记录duration,并上报span。
  7. server-2回复server-1的调用,记录duration,并上报span。
  8. server-1收到server-2的回复,记录duration,并上报span。

整个过程中上报4个临时的span,最终在zipkin中被合并和存储为两个span。

四、总结

分布式链路追踪技术通过跟踪和记录分布式系统中各个服务之间的调用关系和时间信息,为系统监控、故障排查和性能优化提供了强大的支持。在现代复杂的微服务架构中,每个请求往往会经过多个服务节点的处理,这使得问题定位和性能分析变得异常复杂。分布式链路追踪系统的出现,特别是Google的Dapper和其开源实现如Zipkin、Jaeger等,极大地简化了这一挑战。

关键概念如Trace、Span和Annotation定义了分布式链路追踪数据的基本模型,帮助开发人员和运维团队快速定位和解决问题。通过Trace ID和Span ID的唯一标识,以及Annotation的时间戳记录,我们能够清晰地了解每次请求的全过程。采样机制则有效控制了数据量,避免了对系统性能和存储资源的过度消耗。

存储方面,使用像Google的BigTable这样的高扩展性和性能的存储系统,能够有效地存储和查询大规模的跟踪数据。结合查询服务和用户界面,例如Zipkin提供的UI,用户可以轻松地查看和分析复杂的调用链路,从而优化系统性能和用户体验。

总之,分布式链路追踪技术在当今互联网时代的分布式系统中具有不可替代的重要性。它不仅提升了系统的可观察能力和稳定性,还为开发人员和运维团队提供了强大的工具和数据支持,使得我们能够更加高效地管理和优化复杂的分布式应用。

希望本文对分布式链路追踪技术有所启发,并能为您在实际应用中提供有价值的参考和指导。

参考文章和链接

大规模分布式系统跟踪基础设施Dapper

OpenZipkin · A distributed tracing system

Jaeger: open source, distributed tracing platform

打造立体化监控体系的最佳实践_分布式应用服务_链路监控_鹰眼_业务监控_实时监控_分布式系统-阿里云

分布式会话跟踪系统架构设计与实践 - 美团技术团队

https://static.googleusercontent.com/media/research.google.com/zh-CN//pubs/archive/36356.pdf

Swagger UI

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【深度学习基础】一篇入门模型评估指标(分类篇)

🌈 个人主页:十二月的猫-CSDN博客 🔥 系列专栏: 🏀深度学习_十二月的猫的博客-CSDN博客 💪🏻 十二月的寒冬阻挡不了春天的脚步,十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前言 2. 模…

零拷贝相关知识点(一)

前言 大家好,我是程序员田螺。 零拷贝是老生常谈的问题啦,大厂非常喜欢问。比如Kafka为什么快,RocketMQ为什么快等,都涉及到零拷贝知识点。最近技术讨论群几个伙伴分享了阿里、虾皮的面试真题,也都涉及到零拷贝。因此…

React+TS+css in js 练习

今天分享的内容是动态规划的经典问题--0-1 背包问题 0-1背包问题的描述如下:给定一组物品,每种物品都有自己的重量和价值,背包的总容量是固定的。我们需要从这些物品中挑选一部分,使得背包内物品的总价值最大,同时不超过背包的总容量。 举个例子:假设这组物品的质量…

【人工智能基础03】机器学习(练习题)

文章目录 课本习题监督学习的例子过拟合和欠拟合常见损失函数,判断一个损失函数的好坏无监督分类:kmeans无监督分类,Kmeans 三分类问题变换距离函数选择不同的起始点 重点回顾1. 监督学习、半监督学习和无监督学习的定义2. 判断学习场景3. 监…

【数据结构计数排序】计数排序

非比较排序概念 非比较排序是一种排序算法,它不是通过比较元素大小进行排序的,而是基于元素的特征和属性排序。这种排序方法在特定情况下,可以做到比元素比较排序(快排,归并)更有效率。尤其是在处理大量数…

JavaEE-经典多线程样例

文章目录 单例模式设计模式初步引入为何存在单例模式饿汉式单例模式饿汉式缺陷以及是否线程安全懒汉式单例模式基础懒汉式缺陷以及是否线程安全懒汉式单例模式的改进完整代码(变量volatile) 阻塞队列生产者消费者模型生产者消费者模型的案例以及优点请求与响应案例解耦合 单例模…

【数据结构与算法】排序算法(上)——插入排序与选择排序

文章目录 一、常见的排序算法二、插入排序2.1、直接插入排序2.2、希尔排序( 缩小增量排序 ) 三、选择排序3.1、直接选择排序3.2、堆排序3.2.1、堆排序的代码实现 一、常见的排序算法 常见排序算法中有四大排序算法,第一是插入排序,二是选择排序&#xff…

qml项目创建的区别

在Qt框架中,你可以使用不同的模板来创建应用程序。你提到的这几个项目类型主要针对的是Qt的不同模块和用户界面技术。下面我将分别解释这些项目类型的区别: 根据你提供的信息,以下是每个项目模板的详细描述和适用场景: Qt Widgets…

【热门主题】000077 物联网智能项目:开启智能未来的钥匙

前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 【热…

时序约束进阶六:Set_Clock_Groups详解

目录 一、前言 二、时钟间关系 2.1 时钟关系分类 2.2 时钟关系查看 三、set_clock_groups设置 3.1 使用格式 3.2 优先级 3.3 约束设置示例 3.4 约束效果查看 四、Exclusive差异说明 4.1 Asynchronous 4.2 Logically_exclusive与Physically_exclusive 4.3 logical…

智慧银行反欺诈大数据管控平台方案(一)

智慧银行反欺诈大数据管控平台建设方案的核心在于通过整合先进的大数据技术和深度学习算法,打造一个全面、智能且实时的反欺诈系统,以有效识别、预防和应对各类金融欺诈行为。该方案涵盖数据采集、存储、处理和分析的全流程,利用多元化的数据…

系统架构:MVVM

引言 MVVM 全称 Model-View-ViewModel,是在 MVP(Model-View-Presenter)架构模式基础上的进一步演进与优化。MVVM 与 MVP 的基本架构相似,但 MVVM 独特地引入了数据双向绑定机制。这一创新机制有效解决了 MVP 模式中 Model 与 Vie…

ARM CCA机密计算安全模型之硬件强制安全

安全之安全(security)博客目录导读 [要求 R0004] Arm 强烈建议所有 CCA 实现都使用硬件强制的安全(CCA HES)。本文件其余部分假设系统启用了 CCA HES。 CCA HES 是一个可信子系统的租户——一个 CCA HES 主机(Host),见下图所示。它将以下监控安全域服务从应用处理元件(P…

【电子通识】失效分析的流程和方法

在文章:【电子通识】失效分析的基本概念-CSDN博客 中我们讲到失效分析是是指产品失效后,根据失效的现象/模式,通过分析和验证,模拟重现失效的现象,找出失效的原因,挖掘出失效的机理的活动。 同时还讲到失效模式和失效机理,并且以LED和贴片电阻做为举例。 失效模式是失效…

Flutter:页面滚动

1、单一页面,没有列表没分页的,推荐使用:SingleChildScrollView() return Scaffold(backgroundColor: Color(0xffF6F6F6),body: SingleChildScrollView(child: _buildView()) );2、列表没分页,如购物车页,每个item之间…

facebook欧洲户开户条件有哪些又有何优势?

在当今数字营销时代,Facebook广告已成为企业推广产品和服务的重要渠道。而为了更好地利用这一平台,广告主们需要理解不同类型的Facebook广告账户。Facebook广告账户根据其属性可分为多种类型,包括个人广告账户、企业管理(BM&#…

WEB攻防-通用漏洞CSRFSSRF协议玩法内网探针漏洞利用

CSRF构造工具,也可以用bp构造 选中要保存的请求,点击Generate HTML,生成带有添加用户请求的html文件,然后将构造的html放在网站上,生成访问地址,诱导管理员点击链接,就会添加用户 start Recording之后就会…

C#面向对象之访问限制,类基础,继承

文章目录 1 访问限制1.1 简介 2 类基础讲解2.1 类定义2.2 构造函数2.2.1 构造函数2.2.2 静态构造函数2.2.3 初始化顺序2.2.4 对象初始化器 2.3 析构函数2.4 类的静态成员2.5 匿名对象2.5.1 定义2.5.2 匿名对象的创建 3 继承3.1 基类和派生类3.2 基类初始化3.3 Partial类3.3.1 定…

代码之丑第一期-缩进

各位小伙伴们,大家好!咱今天就算是正式开张了。实不相瞒,第一期的内容早已写好,但唯独这开篇方式,笔者想了好些时间,包括但不限于如下风格: 斗破苍穹式(已经三刷)&#…

JVM 性能调优 -- JVM常用调优工具【jps、jstack、jmap、jstats 命令】

前言: 前面我们分析怎么去预估系统资源,怎么去设置 JVM 参数以及怎么去看 GC 日志,本篇我们分享一些常用的 JVM 调优工具,我们在进行 JVM 调优的时候,通常需要借助一些工具来对系统的进行相关分析,从而确定…