出现bug时,分布式链路追踪是最优解

来源 | moon聊技术

来源 | 下载于视觉中国

在现有的微服务体系架构下,随着服务数量的增多,服务与服务之间的关联关系错综复杂,一个请求下发后可能会经过N个服务处理后才返回响应,所以,当出现bug时,开发人员只能依靠日志一个个排查,效率低的可怕,于是,分布式链路追踪成为了你的最优解。

当然这只是其中一个因素,分布式链路追踪能够解决服务链路的问题,它还可以做到:

  • 1:查询每个应用的ip

  • 2:各个接口响应了多长时间,网络开销是多少

  • 3:应用的执行时间,是否执行成功

  • 4:总共消耗了多长时间

  • 5:每个接口返回了什么内容,请求的内容又是什么?

  • 6:每个应用调了多少次数据库?


trace_ID

那么怎么样才能判断一个请求发起到结束究竟经过了哪些服务呢?

大家肯定想到了一个唯一Id来实现,就是说,我的请求在发起时,创建一个全局的唯一Id,然后在后面的请求传递的时候都把这个Id带上,这样,就可以通过这个唯一Id来判断究竟经过了哪些服务。

如下图:

我们可以通过trace_ID清晰的发现一个从A开始的请求都经过了那些服务。

span_ID

现在我们知道了所有调用的服务,但是我们还会发现一个问题,我们发现A服务在调用B服务的时候,会B会调用两个服务,一个是服务C,一个是服务B,那么这个先后关系有要怎么判断呢?

没错,就是再引入一个span_ID来判断服务的先后调用顺序,如图,就可以判定调用链路为

服务A->服务B->服务C->服务D->服务E->服务F

parent_ID

当然,父子间的调用关系我们就可以用一个parent_ID去管理了

比如:我们看到服务C的parent_ID为2,那么我们就知道span_ID为2的服务调用了服务C,也就是服务B调用了服务C

以上都是基于我们的猜测,大概会有这些部分,来,让我们看下分布式链路追踪的规范是什么~

OpenTracing是什么

由于各种调用链监控产品层出不穷,各式各样,为了避免碎片化,促进互操作性,社区诞生了一个叫做OpenTracing的标准化组织,制定了一些链路跟踪的API规范,并且提供了一些框架和库,这些框架和库实现了它制定的那些API规范。而且它是一个独立开放的项目,现在已经是云原生基金会(Cloud Native Computing Foundation, CNCF)的项目了。任何组织和个人都可以贡献符合API规范的库/框架。

OpenTracing提供的框架和库需要重点说明的是,并不做分析,所以其并不是一个完备的链路系统.

OpenTracing旨在标准化Trace数据结构和格式,其目的是:

  • 不同语言开发的Trace客户端的互操作性,只要遵循OpenTracing标准,就都可以对接OpenTracing兼容的监控后端。

  • Tracing监控后端的互操作性,只要遵循OpenTracing标准,企业可以根据需要替换具体的Tracing监控后端产品,比如从Zipkin替换成Skywalking等后端。


分布式链路跟踪系统的数据模型

在OpenTracing规范中,有三个关键的,相关关联的类型:Tracer,Span和SpanContext。

Traces(一般翻译为链路):一起请求从发出,然后经过多个模块(这个模块可能是函数或者系统,或者都有),最终得到请求回复,整个请求按照调用时间和关系串起来就是一个trace。

Span则是组成trace的最基本单元,它一般代表分布式系统中一个独立的工作单元。一个Span包含如下几部分:

  • 操作名称:一般用于展示、过滤、聚合

  • 开始和结束时间戳:用于计算耗时 由key-value组成的Tags:用于添加一些时间无关的信息(可选) 由key-value组成并包含时间戳的Logs:用于添加一些时间相关的信息(可选)

  • SpanContext。一般包含两部分数据:

    • (1)span的状态数据,比如traceID和spanID

    • (2)Baggage Items。Baggage是链路跟踪提供的一个通用的跨进程/服务传递数据的方式,格式也是key-value形式的。

  • Trace就是由若干个span组成的有向无环图,图中的每个节点就是Span,连接节点的边称之为References。每个trace有一个唯一标识符traceID,每个span也有一个唯一标识符spanID。一个链路中的所有span的traceID是相同的,但spanID各不相同。一个链路中span典型的调用关系图如下:

对应的时间维度为:

一个trace的span间有两种可能的关系:

  • ChildOf:即父子关系,一个操作可以是另一个操作的子操作,在一个ChildOf引用中,父操作在一定程度上依赖于子操作,可以说,等子操作都完成之后父操作才会完成。

  • FollowsFrom:其实也是父子关系,子Span是由父Span调用产生的,但父Span是否完成不依赖于子Span,在这种场景下,子操作仅仅由父操作触发。符合这种关系的操作可以进一步分成很多子类型,。

最后需要介绍的一个概念就是“active span”。一个线程里面可以包含多个span,但同一时刻只能有一个span处于工作状态,这个span称之为ActiveSpan。Span可以有这么几个状态:

  • Started

  • Not Finished

  • Not "active"

  • Active Span的状态由ScopeManager管理,但是否实现由开发者决定。另外OpenTracing定义了Inject和Extract接口来简化SpanContext跨进程传递。

总结

1、分布式链路追踪就是将一次完整的请求链路还原,能够清晰的追踪到每个服务的信息。

2、由于分布式链路追踪实现方式多样,于是opentracing组织定制了一个规范,定义了一个标准,最重要的三个指标就是Tracer,Span和SpanContext。

参考链接:

https://niyanchun.com/opentracing-introduction.html 

你觉得这个方法怎么样?

欢迎来评论区聊聊~


CSDN协同行业大佬
打造13长热门知识图谱及IT成长路线
助力千万IT人成长,快速实现职场进阶!
更多精彩推荐
☞Kubernetes 和 Docker,到底什么关系?☞PassMark 更新排行,苹果 M1 杀疯了☞干货!Redis集群工作原理解析
点分享点收藏点点赞点在看
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于Java项目的更新,最优解取决于具体的需求和项目的规模。以下是一些常见的最佳实践,可以考虑在Java项目更新中采用: 1. 版本控制:使用版本控制系统如Git来管理代码的版本,可以轻松地回滚到之前的版本,并且多人协作更加高效。 2. 持续集成:使用持续集成工具如Jenkins或Travis CI,自动构建和测试代码,确保更新的代码与现有功能兼容。 3. 单元测试和集成测试:编写单元测试和集成测试来验证更新的代码是否按预期工作。这可以帮助捕获潜在的bug并确保代码质量。 4. 依赖管理:使用构建工具如Maven或Gradle来管理项目依赖。确保依赖库的版本与项目的要求匹配,并及更新依赖以获取最新的功能和修复bug。 5. 代码审查:定期进行代码审查,让其他开发人员检查和评估更新的代码。这有助于发现潜在的问题并提供改进建议。 6. 部署策略:采用适当的部署策略,例如蓝绿部署或滚动部署,以确保更新的代码在生产环境中顺利运行,同最小化用户的中断。 7. 监控和日志:确保在更新后对应用程序进行监控,并记录关键事件和错误日志。这可以帮助快速识别和解决潜在的问题。 总之,在Java项目更新中,关注代码质量、测试覆盖率、依赖管理、部署策略和监控日志是非常重要的。根据具体的项目需求和团队的实践,可以进一步定制适合项目的最优解
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值