当前位置: 首页 > 科技观察

分布式跟踪系统的四个功能构建块如何协同工作

时间:2023-03-13 18:44:16 科技观察

了解分布式跟踪中的主要架构决策以及各个部分如何组合在一起。早在十年前,认真研究分布式追踪的基本上只是学术界和少数大型互联网公司的人员。它现在是任何采用微服务的组织的讨价还价筹码。理由很明确:微服务经常出乎意料地出错,而分布式跟踪是描述和诊断这些错误的最佳方式。也就是说,一旦您准备好将分布式跟踪集成到您自己的应用程序中,您很快就会意识到术语“分布式跟踪”对不同的人有不同的含义。此外,跟踪生态系统中充斥着内容相似的重叠项目。本文介绍了分布式跟踪系统中四个(可能)独立的功能模块,并描述了它们将如何协同工作。分布式跟踪:一种心智模型大多数用于跟踪的心智模型都来自Google的Dapper论文。OpenTracing使用类似的术语,因此我们从该项目中借用了以下术语:TracingTrace:对事物如何在分布式系统中运行的描述。跨度:代表工作流一部分的命名计时操作。跨度接受键值对标签以及附加到特定跨度实例的细粒度、带时间戳的结构化日志。Span上下文:承载分布式事务的跟踪信息,包括它何时通过网络或消息总线将服务传递到服务。跨度上下文包含跟踪标识符、跨度标识符以及跟踪系统需要传播到下游服务的任何其他数据。如果您想深入了解这种思维方式的细节,请仔细参考OpenTracing规范。四大功能模块从应用层分布式追踪系统来看,现代软件系统架构如下图所示:Tracing现代软件系统的组件可以分为三类:应用和业务逻辑:你的代码.广泛共享的库:其他人的代码广泛共享的服务:其他人的基础设施这三类组件具有不同的要求,它们推动了用于监控应用程序的分布式跟踪系统的设计。最终的设计有四个重要部分:TracingdetectionAPIAtracinginstrumentationAPI:装饰应用程序代码Wireprotocol:指定的数据协议(在RPC请求中与应用程序数据一起发送)发送到您的分析系统。分析系统:用于处理跟踪数据的数据库和交互式用户界面。为了更深入地解释这个概念,我们将深入研究驱动这个设计的细节。如果您只需要我的一些建议,请跳到下面的前四个解决方案。要求、细节和解释应用程序代码、共享库和共享服务的运行存在显着差异,这些差异严重影响了它们所针对的请求操作。检测应用程序代码和业务逻辑在任何特定的微服务中,微服务开发人员编写的大部分代码都是应用程序或业务逻辑。这部分代码指定了特定区域的操作。通常,它包括任何特殊的、独特的逻辑判断,这些判断首先证明了创建新型微服务的合理性。基本上根据定义,此代码通常不会在多个服务之间共享或以其他方式存在。这意味着您仍然需要了解它,这意味着您需要以某种方式检测它。一些监控和跟踪分析系统使用黑盒代理自动检测代码,其他人更喜欢使用显式白盒检测工具。对于后者,抽象跟踪API提供了许多对微服务应用程序代码更实用的优势:抽象API允许您切换到新的监控工具,而无需重写检测代码。您可能想要更改云服务提供商、供应商和监控技术,并且一大堆不可移植的检测代码会给流程增加有意义的开销和麻烦。事实证明,除了生产监控之外,该工具还有其他有趣的用途。现有项目使用相同的跟踪工具来驱动测试工具、分布式调试器、“混沌工程”故障注入器和其他元应用程序。但更重要的是,如果将应用程序组件提取到共享库中会怎样?从以上可以得出结论,大多数应用程序中出现的用于检测共享库的实用程序代码(处理网络请求、数据库调用、磁盘写入操作、线程、并发管理等)通常是通用的,而不是特定于应用程序的特定的应用。这些代码将被打包成库和框架,然后可以加载到许多微服务中并部署在许多不同的环境中。真正的区别在于:对于共享代码,其他人成为消费者。大多数用户具有不同的依赖性和操作风格。如果您尝试使用此共享代码,您会注意到几个常见问题:您需要一个API来编写检测。但是,您的图书馆不知道您使用的是哪种分析系统。有多种选择,运行在同一个应用下的所有库不能做出不兼容的选择。由于这些包封装了所有网络处理代码,因此从请求标头中注入和提取跨度上下文的任务往往指向RPC库。但是,共享库必须知道每个应用程序正在使用哪种跟踪协议。最后,您不想强迫用户使用相互冲突的依赖项。大多数用户具有不同的依赖性和操作风格。即使他们使用gRPC,gRPC版本是否绑定相同?因此,您的库附带的任何用于跟踪的监控API都必须没有依赖性。因此,(a)没有依赖性,(b)与有线协议无关,(c)使用流行的供应商和分析系统的抽象API应该是检测共享库代码的要求。检测共享服务最后,有时整个服务(或微服务的聚合)足够通用,以至于许多独立的应用程序都可以使用它们。此类共享服务通常由第三方托管和管理,例如缓存服务器、消息队列和数据库。从应用程序开发人员的角度来看,了解共享服务本质上是黑盒子是极其重要的。不可能将您的应用程序监控注入共享服务。恰恰相反,托管服务通常运行自己的监控解决方案。四管齐下的解决方案因此,抽象跟踪API将帮助库发出数据并注入/提取跨度上下文。标准有线协议将帮助黑盒服务相互连接,而标准数据格式将帮助单独的分析系统组合数据。让我们看看这些问题的一些有前途的解决方案。跟踪API:OpenTracing项目如您所见,我们需要一个跟踪API来检测应用程序代码。为了将此功能扩展到大多数跨越上下文注入和提取的共享库,必须以某种关键方式抽象API。OpenTracing项目主要旨在解决库开发人员的问题。OpenTracing是一种供应商中立的跟踪API,它没有依赖性,并且正在迅速获得许多监控系统的支持。这意味着,如果该库带有内置的原生OpenTracing工具,则在应用程序启动时连接监控系统时,跟踪将自动启动。就个人而言,作为一个已经编写、发布和运营开源软件十多年的人,从事OpenTracing项目并最终解决这个观察难题让我感到非常满足。除了API之外,OpenTracing项目还维护着一个不断增加的工具列表,其中一些可以在此处找到。如果您想参与其中,无论是贡献一个检测插件,在本地测试您自己的OSS库,还是只是想问一个问题,请在Gitter上向我们问好。有线协议:HTTPheadertrace-context为了使监控系统在从一个监控系统切换到另一个监控系统时能够互操作并缓解迁移问题,需要一个标准的有线协议来传播span上下文。w3c分布式跟踪上下文社区组正在制定此标准。当前的重点是开发一组标准的HTTP标头。可以在此处找到最新的规范草案。如果您对小组有任何疑问,邮件列表和Gitter聊天室是提问的好地方。(LCTT译注:本文原文发表于2018年5月,现在社区可能有不同的进展)数据协议(尚未出现!!)对于黑盒服务,当跟踪程序无法安装或交互时该程序,需要使用数据协议从系统中导出数据。此数据格式和协议的开发工作目前处于起步阶段,并且主要是在w3c分布式跟踪上下文工作组的上下文中完成的。特别值得关注的是在标准数据模式中定义更高级别的概念,例如RPC调用、数据库语句等。这将允许跟踪系统对可用数据的类型做出假设。OpenTracing项目还通过定义一组标准标签来解决这个问题。该计划旨在使这两项努力的结果保持一致。请注意,目前存在中间立场。对于由应用程序开发人员操作但不想编译或以其他方式执行代码修改的“网络设备”,动态链接可以帮助避免这种情况。主要示例是服务网格和代理,例如Envoy或NGINX。对于这种情况,可以将兼容OpenTracing的跟踪器编译为共享对象,然后在运行时动态链接到可执行文件中。目前C++OpenTracingAPI提供了这个选项。JAVA的OpenTracing跟踪器解析器也在开发中。这些解决方案适用于支持动态链接并由应用程序开发人员部署的服务。但从长远来看,标准数据协议可以更广泛地解决问题。分析系统:从跟踪数据中提取有洞察力的服务最后但并非最不重要的是,有足够多的跟踪监控解决方案。可以在此处找到已知与OpenTracing兼容的监控系统列表,但还有更多选项。我进一步鼓励您研究您的解决方案,并希望您发现本文提供的框架在比较解决方案时有用。除了根据其操作特征(更不用说您是否喜欢UI及其功能)对监控系统进行评级外,请确保您考虑了上述三个重要方面,它们对您的相对重要性以及跟踪系统的有趣程度是给你的。为他们提供解决方案。结论最后,每个部分的重要性在很大程度上取决于你是谁以及你正在构建什么样的系统。例如,开源库的作者对OpenTracingAPI非常感兴趣,而服务开发人员则对trace-context规范更感兴趣。当有人说一个部分比另一个更重要时,他们通常的意思是“一个部分对我来说比另一个更重要”。然而,事情是这样的:分布式跟踪已经成为监控现代系统的必要条件。在为这些系统构建块时,旧的“尽可能解耦”方法仍然适用。在构建分布式监控系统等跨系统系统时,干净地解耦组件是保持灵活性和前向兼容性的最佳方式。谢谢阅读!现在,当您准备好在自己的应用程序中实施跟踪服务时,您将获得一份指南,了解它们所讨论的部分以及它们如何协同工作。