分布式链路追踪

本文涉及的产品
应用实时监控服务-可观测链路OpenTelemetry版,每月50GB免费额度
简介: 传统的单体服务通过日志和性能监控为我们的系统提供了良好的观测手段,随着服务之间的交互越来越多,越来越复杂,这种“各自为政”的策略将使我们看不到整体的关联性。为了提高系统的可见性观察,分布式链路追踪被提了出来,并迅速发展。

前言

传统的单体服务通过日志和性能监控为我们的系统提供了良好的观测手段,随着服务之间的交互越来越多,越来越复杂,这种“各自为政”的策略将使我们看不到整体的关联性。为了提高系统的可见性观察,分布式链路追踪被提了出来,并迅速发展。

背景

分布式体系的构建是以“拆”为核心,其目标是职责分明、高度自治。不同的模块甚至会由不同的团队负责,用不同的语言编写。当我们想要组合这些服务,对外提供统一功能时,我们还需要考虑它的一个可观察性。比如,请求里的服务依赖有哪些,各个节点的耗时是怎么样的,瓶颈在哪里等。

像这种涉及上下文请求、端到端的流向监控便是分布式链路追踪了。当我们的系统出现瓶颈或者故障时,就能根据收集到的信息快速定位问题、解决问题。这也是它的价值所在。

不过,在面对一个复杂的系统时,分布式链路追踪考虑的点就有很多了,主要有以下几点:

  • 透明性:各个模块可能是由不同语言编写,我们需要考虑接入成本,最好是无需改动什么,便可以完成接入。
  • 可靠性:上下文的数据收集是 24 小时持续进行的,分布式链路追踪需要考虑稳定性及规模拓展。
  • 独立性:监控是辅助行为,即使链路追踪繁忙或失败,也不当影响业务的运行。

当然,最核心的设计还是在于如何将各个节点的统计信息串联起来,并进行分析展示。

解决方案

从大的层面来讲,分布式追踪其实跟日志收集优点类似。比如需要在每个节点记录性能数据,然后由专门的收集组件将数据发送到核心组件。核心组件将数据进行存储并进行一个关联关系的添加,毕竟一条完整的链路数据是来源于各个服务的。当数据分析完后,我们就可以在 Dashboard 里搜索结果了。

像现在主流的分布式链路追踪产品:Jaeger 就是这么设计的。不过,Jaeger 也是受 Google 的 Dapper 启发设计的。Dapper 是最早的跟分布式链路有关的实施产品,并有一篇论文: Dapper, a Large-Scale Distributed Systems Tracing Infrastructure ,算是分布式链路追踪系统的鼻祖了,有兴趣的小伙伴们可以自行搜索查看。

当分布式链路的产品越来越多时,统一标准便成了很多人的心声,毕竟兼容处理也是很麻烦的。后面 CNCF(云原生计算基金会)推出了 OpenTracing 项目。OpenTracing 是与平台厂商无关的链路解决方案。它并不提供具体的实现代码,仅仅只是制定规范,让接入它的人能有个一致的协议。

当前根据这个标准实现的产品比较多,像刚刚提及的 Jaeger,还有 Apache 的 Skywalking 等。今天我们来详细看下 OpenTracing 的总体设计,以及它的实现产品:Jaeger。或许以后我们也可以根据 OpenTracing 标准来实现一款属于自己的分布式链路追踪产品。

概念

Trace & Span

在广义上来讲,我们将某一次请求的完整链路抽象成了 Trace 概念。一个 Trace 就代表了一次流程的执行过程。它实际上就是一个有向无环图:

Trace

为了能清晰的描述链路里的上下文请求,我们将这些关键路径抽象为了一个个的 Span,每个 Span 是一个基本单元,具有操作名称、操作的开始、持续时间。通过各个 Span 的嵌套和排序,我们就可以建立起因果关系模型了。

Span

这种模型能让我们更好的理解服务的层次关系、执行的上下文时间等,有助于我们快速的发现系统的调用情况。

Trace&Span

其中,Span 除了上面的基本属性,还拥有其他关联的特性字段:

  • Span Tag,Span 标签集合。
  • Span Log,属于一组 Span 的日志集合
  • SpanContext:Span 上下文对象,用来描述与其他 Span 的关系,有 ChildOf(父子) 和 FollowsFrom(跟随)。SpanContext 的信息添加和获取分别是通过 Injected 和 Extracted 某个 Carrier (载体)来实现的。

功能模块

当数据模型出来后,我们就可以定义接口了。当然,由于 OpenTracing 并不负责具体的实现,所以这里的接口更多是一种功能模块的描述,然后通过类似伪代码的形式来公开。此处并不具体描述这些接口的传参、返回格式,主要来看看有哪些功能模块。

首先是跨进程的边界信息传递。在这里,我们会涉及到 Span 的创建,SpanContext 的 carrier(载体)注入(Inject),以及从 carrier(载体)的提取(Extract)。关于边界的信息传递,我们可以通过埋点来统一处理,比如 Request 和 Response 的拦截器机制。

接着是 Span 生命周期的管理,上面创建出 Span 后,我们就需要有一个明确的完成时间来结束 Span。当然,如果 Span 需要有什么特性标注,那么我们也可以在这个功能模块里实现,比如 Span 的 Tag 设置。

最后是 SpanContext,由于 SpanContext 关联了上下文,所以它比较关键,在 OpenTracing 里它更多的是一个概念,具体需要哪些功能可以由开发者自己实现一套。只要包含了上面的 Inject(注入)和 Extract(提取)即可。

Jaeger

上面的标准为我们定义了功能模块及模型接口。那么我们围绕这些结构和 API 也就能实现具体的产品了。Uber 出品的 Jaeger 就是其中的一个。它主要实现了 OpenTracing 并提供以下功能:

  • 分布式上下文传播
  • 分布式事务监控
  • 结构化的根本原因分析
  • 服务依赖关系分析
  • 性能分析、延迟分析

在进行具体实现的时候,Jaeger 为了能提供更好的拓展性,进行了组件的拆分,每个组件都支持单独部署,这也符合了微服务的设计理念。主要的组件如下:

  • jaeger-client:Jaeger 客户端,根据 OpenTracing 的标准实现了对应的 API。例如当发生 RPC 等跨服务调用时,此时会触发 client 的 span 创建,并确定好 SpanContext 关系。
  • jaeger-agent:本地存储 client 的 Span 信息,随后会将数据批量的上传到 Jaeger Collector。
  • jaeger-collector:存储 agent 传来的数据,会为其建立索引并转换。
  • jaeger-query:jaeger 的 dashboard 数据展示。

它的总体架构图如下:
jaeger 架构

最终,我们将看到如下的查询 UI:

Traces

Traces Detail

可以看到,服务依赖、耗时分析等 Jaeger 都帮我们通过 web UI 呈现出来了!

总结

本文主要介绍了分布式链路追踪的标准规范:OpenTracing 以及它的实现:Jaeger。事实证明,在越复杂的系统里,我们越要尽可能的利用这些出色的组件,对其监控起来。只有提高系统的可见性,我们才不至于在问题出现的时候手忙脚乱。

参考


感兴趣的朋友可以搜一搜公众号「 阅新技术 」,关注更多的推送文章。
可以的话,就顺便点个赞、留个言、分享下,感谢各位支持!
阅新技术,阅读更多的新知识。

相关实践学习
基于OpenTelemetry构建全链路追踪与监控
本实验将带领您快速上手可观测链路OpenTelemetry版,包括部署并接入多语言应用、体验TraceId自动注入至日志以实现调用链与日志的关联查询、以及切换调用链透传协议以满足全链路打通的需求。
分布式链路追踪Skywalking
Skywalking是一个基于分布式跟踪的应用程序性能监控系统,用于从服务和云原生等基础设施中收集、分析、聚合以及可视化数据,提供了一种简便的方式来清晰地观测分布式系统,具有分布式追踪、性能指标分析、应用和服务依赖分析等功能。 分布式追踪系统发展很快,种类繁多,给我们带来很大的方便。但在数据采集过程中,有时需要侵入用户代码,并且不同系统的 API 并不兼容,这就导致了如果希望切换追踪系统,往往会带来较大改动。OpenTracing为了解决不同的分布式追踪系统 API 不兼容的问题,诞生了 OpenTracing 规范。OpenTracing 是一个轻量级的标准化层,它位于应用程序/类库和追踪或日志分析程序之间。Skywalking基于OpenTracing规范开发,具有性能好,支持多语言探针,无侵入性等优势,可以帮助我们准确快速的定位到线上故障和性能瓶颈。 在本套课程中,我们将全面的讲解Skywalking相关的知识。从APM系统、分布式调用链等基础概念的学习加深对Skywalking的理解,从0开始搭建一套完整的Skywalking环境,学会对各类应用进行监控,学习Skywalking常用插件。Skywalking原理章节中,将会对Skywalking使用的agent探针技术进行深度剖析,除此之外还会对OpenTracing规范作整体上的介绍。通过对本套课程的学习,不止能学会如何使用Skywalking,还将对其底层原理和分布式架构有更深的理解。本课程由黑马程序员提供。
相关文章
|
4月前
|
存储 监控 开发者
分布式链路监控系统问题之系统拆分后链路追踪技术的问题如何解决
分布式链路监控系统问题之系统拆分后链路追踪技术的问题如何解决
|
7月前
|
消息中间件 SpringCloudAlibaba Java
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(八)Config服务配置+bus消息总线+stream消息驱动+Sleuth链路追踪
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(八)Config服务配置+bus消息总线+stream消息驱动+Sleuth链路追踪
1033 0
|
存储 监控 数据可视化
Golang链路追踪:实现高效可靠的分布式系统监控
Golang链路追踪:实现高效可靠的分布式系统监控
|
消息中间件 监控 安全
RocketMQ x OpenTelemetry 分布式全链路追踪最佳实践(3)
RocketMQ x OpenTelemetry 分布式全链路追踪最佳实践
155 0
RocketMQ x OpenTelemetry 分布式全链路追踪最佳实践(3)
|
消息中间件 Java Kafka
RocketMQ x OpenTelemetry 分布式全链路追踪最佳实践(2)
RocketMQ x OpenTelemetry 分布式全链路追踪最佳实践(2)
158 0
RocketMQ x OpenTelemetry 分布式全链路追踪最佳实践(2)
|
消息中间件 Cloud Native Apache
RocketMQ x OpenTelemetry 分布式全链路追踪最佳实践(1)
RocketMQ x OpenTelemetry 分布式全链路追踪最佳实践
96 0
RocketMQ x OpenTelemetry 分布式全链路追踪最佳实践(1)
|
SpringCloudAlibaba 算法 Java
Spring Boot项目如何实现分布式日志链路追踪
作为一名后端开发工程师,排查系统问题用得最多的手段之一就是查看系统日志,在当下主要的分布式集群环境中一般使用ELK(Elasticsearch , Logstash, Kibana)来统一收集日志,以便后续查看日志定位追踪相关问题。但是在并发情况下,大量的系统用户即多线程并发访问后端服务导致同一个请求的日志记录不再是连续相邻的,此时多个请求的日志是一起串行输出到文件中,所以我们筛选出指定请求的全部相关日志还是比较麻烦的,同时当后端异步处理功能逻辑以及微服务的下游服务调用日志追踪也有着相同的问题。
|
监控 网络协议 Java
分布式链路追踪- SkyWalking使用手册
分布式链路追踪- SkyWalking使用手册
1258 0
分布式链路追踪- SkyWalking使用手册
|
消息中间件 数据可视化 JavaScript
什么是链路追踪?分布式系统如何实现链路追踪?
什么是链路追踪?分布式系统如何实现链路追踪?
|
存储 监控 NoSQL
【微服务】分布式如何利用Skywalking实现链路追踪与监控?
微服务下的分布式如何实现链路追踪和监控。
1004 1
【微服务】分布式如何利用Skywalking实现链路追踪与监控?
下一篇
DataWorks