分布式 集群 系统组件架构
十年前,基本上只有认真思考分布式跟踪的人是学者和少数大型互联网公司。 如今,对于任何采用微服务的组织来说,它已经变成了赌注。 基本原理是公认的:微服务以令人惊讶且通常是惊人的方式失败,而分布式跟踪是描述和诊断这些失败的最佳方式。
就是说,如果您打算将分布式跟踪集成到您自己的应用程序中,您将很快意识到术语“分布式跟踪”对不同的人意味着不同的事物。 此外,跟踪生态系统挤满了具有类似章程的部分重叠项目。 本文介绍了分布式跟踪中的四个(可能)独立的组件,以及它们如何组合在一起。
分布式跟踪:一种心理模型
追踪的大多数思维模型源自Google的Dapper论文 。 OpenTracing使用类似的名词和动词,因此我们将从该项目中借用以下术语:
![追踪 Tracing](https://i-blog.csdnimg.cn/blog_migrate/55619c0a7575c426cc90a45dde4f4690.png)
- 跟踪:事务在分布式系统中移动时的描述。
- 跨度:表示工作流程的一部分的命名定时操作。 跨度接受key:value标记以及附加到特定跨度实例的细粒度,带时间戳的结构化日志。
- 跨度上下文:跟踪与分布式事务相关的信息,包括它何时通过网络或通过消息总线从一个服务传递到另一个服务。 范围上下文包含跟踪标识符,范围标识符以及跟踪系统需要传播到下游服务的任何其他数据。
如果您想深入了解此心理模型,请查看OpenTracing规范 。
四大块
从应用程序层分布式跟踪系统的角度来看,现代软件系统如下图所示:
![追踪 Tracing](https://i-blog.csdnimg.cn/blog_migrate/36a04e3341db739d6a8746f323c799c3.png)
现代软件系统中的组件可以分为三类:
- 应用程序和业务逻辑:您的代码。
- 广泛共享的库:其他人的代码。
- 广泛共享的服务:其他人的基础结构。
这三个组件具有不同的要求,并驱动着负责监视应用程序的分布式跟踪系统的设计。 最终的设计产生四个重要方面:
- 跟踪工具API:装饰应用程序代码的内容。
- 有线协议:在RPC请求中与应用程序数据一起发送的内容。
- 数据协议:异步(带外)发送到您的分析系统的内容。
- 分析系统:用于处理跟踪数据的数据库和交互式UI。
为了进一步解释这一点,我们将深入探讨驱动该设计的细节。 如果您只需要我的建议,请跳至底部的四个主要解决方案。
要求,详细信息和解释
应用程序代码,共享库和共享服务具有显着的操作差异,这严重影响了对其进行检测的要求。
检测应用程序代码和业务逻辑
在任何特定的微服务中,由微服务开发人员编写的大部分代码是应用程序或业务逻辑。 这是定义特定于域的操作的代码; 通常,它包含首先证明有必要创建新的微服务的任何特殊,独特的逻辑。 几乎按照定义, 此代码通常不共享或以其他方式存在于多个服务中。
也就是说,您仍然需要了解它,这意味着需要以某种方式对其进行检测。 一些监视和跟踪分析系统使用黑匣子代理自动执行代码,而另一些期望使用显式的“白匣子”工具。 对于后者,抽象跟踪API为特定于微服务的应用程序代码提供了许多实际的优势:
- 抽象的API使您可以交换新的监视工具,而无需重新编写检测代码。 您可能需要更改云提供商,供应商和监视技术,并且一大堆不可移植的检测代码将为该过程增加有意义的开销和麻烦。
- 事实证明,除了生产监视之外,仪表还有其他有趣的用途。 现有的项目使用相同的跟踪工具来进行电源测试工具,分布式调试器,“混乱工程”故障注入器以及其他元应用程序。
- 但是最重要的是,如果要将应用程序组件提取到共享库中怎么办? 这导致我们:
检测共享库
大多数应用程序中存在的实用程序代码(处理网络请求,数据库调用,磁盘写入,线程,队列,并发管理等的代码)通常是通用的,并不特定于任何特定的应用程序。 将此代码打包到库和框架中,然后将其安装在许多微服务中,并部署到许多不同的环境中。
这是真正的区别:使用共享代码,其他人就是用户。 大多数用户具有不同的依赖关系和操作样式。 如果您尝试使用此共享代码,则会注意到几个常见问题:
- 您需要一个API来编写检测。 但是,您的库不知道正在使用哪种分析系统。 有很多选择,并且在同一应用程序中运行的所有库都不能做出不兼容的选择。
- 从请求标头注入和提取范围上下文的任务通常落在RPC库上,因为这些程序包封装了所有网络处理代码。 但是,共享库不能不知道每个应用程序正在使用哪种跟踪协议。
- 最后,您不想强迫对用户的冲突。 大多数用户具有不同的依赖关系和操作样式。 即使他们使用gRPC,绑定的gRPC版本是否也会相同? 因此,您的库引入用于跟踪的任何监视API都必须没有依赖项。
因此,一个抽象的API(a)没有依赖关系,(b)与有线协议无关,并且(c)与流行的供应商合作,并且分析系统应该是检测共享库代码的要求。
检测共享服务
最后,有时整个服务(或一组微服务)具有通用性,足以被许多独立的应用程序使用。 这些共享服务通常由第三方托管和管理。 例如缓存服务器,消息队列和数据库。
从应用程序开发人员的角度来看 , 共享服务本质上是“黑匣子”,这一点很重要。 无法将应用程序的监视解决方案注入共享服务中。 而是,托管服务通常运行其自己的监视解决方案。
四大解决方案
因此,抽象的跟踪API将帮助库发出数据并注入/提取Span上下文。 标准的有线协议将帮助黑盒服务互连,而标准的数据格式将帮助单独的分析系统合并其数据。 让我们看一下解决这些问题的一些有前途的选择。
跟踪API:OpenTracing项目
如上所示,为了检测应用程序代码,需要跟踪API。 并且为了将该工具扩展到大多数Span Context注入和提取都在其中发生的共享库,必须以某些关键方式抽象该API。
OpenTracing项目旨在为图书馆开发人员解决此问题。 OpenTracing是与供应商无关的跟踪API,不附带任何依赖关系,并且正在Swift从大量监视系统中获得支持。 这意味着,越来越多地,如果库附带了内置的本机OpenTracing工具,则在应用程序启动时连接监视系统时将自动启用跟踪。
就个人而言,作为从事开源软件的开发,交付和运营已超过十年的人,对OpenTracing项目进行工作并最终克服这一可观察性之痒,是非常满足的。
除了API之外,OpenTracing项目还维护着越来越多的有用工具清单,其中一些可以在此处找到。 如果您想参与其中,或者通过提供一个检测插件,对您自己的OSS库进行本地检测,或者只是想问一个问题,请在Gitter上找到我们并打个招呼。
有线协议:跟踪上下文的HTTP标头
为了使监视系统能够互操作,并减轻从一个监视系统更改为另一个监视系统时的迁移问题,需要标准的有线协议来传播Span Context。
w3c分布式跟踪上下文社区小组正在努力定义此标准。 当前,重点是定义一组标准HTTP标头。 规范的最新草案可以在这里找到。 如果您对此小组有疑问,则邮件列表和Gitter聊天室是寻求答案的好地方。
数据协议(尚不存在!)
对于黑盒服务,在无法安装跟踪程序或无法与程序交互的情况下,需要使用数据协议从系统中导出数据。
目前,有关这种数据格式和协议的工作尚处于初期阶段,并且大多在w3c分布式跟踪上下文工作组的上下文中进行。 特别需要关注的是在标准数据模式中定义更高级的概念,例如RPC调用,数据库语句等。 这将使跟踪系统可以假定将使用哪种数据。 OpenTracing项目还通过开始定义一组标准标签来解决此问题。 该计划是为了使这两个努力相互配合。
请注意,目前有中间立场。 对于应用程序开发人员操作但不希望对其进行编译或对其进行代码修改的“网络设备”,动态链接可以提供帮助。 这方面的主要示例是服务网格和代理,例如Envoy或NGINX。 对于这种情况,可以将兼容OpenTracing的跟踪器编译为共享对象,然后在运行时动态链接到可执行文件中。 该选项当前由C ++ OpenTracing API提供 。 对于Java,OpenTracing Tracer Resolver也正在开发中。
这些解决方案适用于支持动态链接的服务,并由应用程序开发人员部署。 但是从长远来看,标准数据协议可以更广泛地解决此问题。
分析系统:从跟踪数据中提取见解的服务
最后但并非最不重要的一点是,现在有了跟踪和监视解决方案的聚宝盆。 可以在此处找到已知与OpenTracing兼容的监视系统列表,但是那里还有更多选择。 我鼓励您研究您的选择,并且希望您发现本文中提供的框架在比较选择时很有用。 除了根据其操作特性(更不用说您是否喜欢UI和功能)对监视系统进行评级之外,请确保您考虑了上述三个重要方面,它们对您的相对重要性以及您对跟踪系统的兴趣如何为他们提供解决方案。
结论
最后,每个部分的重要性在很大程度上取决于您是谁以及您要构建哪种系统。 例如,开源库作者对OpenTracing API非常感兴趣,而服务开发人员则对Trace-Context规范更感兴趣。 当某人说一件作品比另一件重要时,他们通常的意思是“一件对我来说比另一件重要。”
谢谢阅读! 希望现在,当您准备在自己的应用程序中实现跟踪时,您将获得一份指南,以了解他们在谈论哪些部分以及它们如何组合在一起。
想了解更多? 报名参加5月的KubeCon欧盟或12月的KubeCon北美 。
翻译自: https://opensource.com/article/18/5/distributed-tracing
分布式 集群 系统组件架构