译者 | 布加迪
审校 | 孙淑娟
运行云原生应用程序时,可观测性(observability)很关键。在云原生领域,应用程序功能来自在多个位置运行的众多微服务之间的交互。微服务应用程序具有松散耦合性,可能意味着每个微服务都以各自的方式报告其活动。如果没有一种工具来汇总和关联这些遥测数据,自始至终跟踪请求的处理就算并非没有可能,也是非常困难的。

这种细粒度、循序渐进的跟踪对于故障排除和性能调优而言至关重要。在物色一种多功能的可观测性工具时,NGINX现代应用程序参考架构(MARA)项目背后的团队选择了OpenTelemetry。这篇博文解释了为什么OpenTelemetry对微服务架构而言如此重要,以及它在如何改变云原生应用程序格局。
OpenTelemetry在2019年巴塞罗那KubeCon大会上首次宣布,此后就吸引了一批狂热的贡献者。今天,它仍然是云原生计算基金会(CNCF)的一个高人气项目。越来越多的贡献者表明OpenTelemetry已趋成熟,开始跨越愿意尝新的早期采用者和渴望成熟产品的实用主义者之间的这条鸿沟。
OpenTelemetry专注于数据,具体说来是最有效地了解、检测和改进应用程序所需要的数据和数据流(遥测)。数据只有在可以大规模聚合、分析和可视化后才有用。虽然OpenTelemetry并不提供可视化数据方面的指导,但它让我们从此不必操心我们获得什么数据,而是专注于我们可以用数据做什么。
OpenTelemetry简化了跨数据源和应用程序关联事件的工作。这由此带来了可观测性2.0,这是用于测量云端应用程序活动的新基准。由于数据自动关联,我们不再局限于仅仅知道应用程序是否在运行。现在我们可以了解任何请求通过我们的应用程序所经过的确切数据路径。
为了实现这一点,OpenTelemetry的两个功能方面非常关键:分布式跟踪和应用程序智能。
虽然分布式跟踪已经存在多年了(可以追溯到Solaris中的DTrace),但过去十年发生的许多变化加大了用户对它的需求。使用Cynefin框架,我们可以着重表明如今在现代应用程序方面面临的一些变化和挑战:
Cynefin框架表明了从简单向复杂变化时,我们的实践或做法会发生怎样的变化。面临的挑战是,我们沿两条不同的路径前进,每条路径有其特点;从简单变成复杂后,试图直接抄捷径常常会造成混乱和不完整的进展。
不妨看看哪些要素构建了现代应用程序和云原生旅程中的路径。在第一条路径(Cynefin图中的Y轴)中,我们有现代应用程序,它们通常是微服务架构,每个应用程序都做特定的工作。在第二条路径(X轴)中,复杂的环境是短暂的,因为微服务实例根据需求来创建和关闭,并根据网络问题移动到不同的主机上。
我们还必须考虑云环境的出现和迅猛增长,比如亚马逊网络服务(AWS)、微软Azure和谷歌云平台(GCP)等云环境。这种云的一个优点是弹性响应——可以灵活扩展或收缩资源,以匹配当前的需求量。加上容器编排(最常使用Kubernetes)的影响,随着资源的数量和位置在一段时间后出现变化,我们开始看到混乱的行为。(连这种相对受限的视图也很混乱,而无服务器函数等要素可能也会使其更混乱。)
在现代架构中,有许多独立的部分生成我们监控和维护应用程序所需的遥测数据,数据负载庞大而复杂。由于我们无法完全控制基础设施和通信路径,问题可能不会可靠地重复或容易引发。我们需要能够让我们一直跟踪所有活动和相关要素的技术,这样我们可以理解和分析不断变化的环境,不仅可以识别反复出现的问题,还可以识别异常情况以及相关的应用程序和网络情况。
这时候OpenTelemetry应运而生。
分布式跟踪支持跟踪许多类型的新指标,但最常见的指标是与每个时间单位的请求数量、每个时间单位的错误数量以及聚合请求在该时间单位中占多长时间有关的指标。
在OpenTelemetry中,所有生成指标的应用程序都可以通过遥测(传输)层将它们发送到一个通用收集点,这有助于对齐和关联来自生成数据的松散耦合服务的数据。这包括与底层基础设施保持一致。简而言之,有了OpenTelemetry,获取和发送高度详细的指标变得更轻松了。
OpenTelemetry还有助于解决时间戳漂移和倾斜问题,这个问题使事件关联起来变得很难。OpenTelemetry为每个请求分配一个跟踪编号(TraceId),但数据仍然可能受到漂移和倾斜的影响,这个问题常常出现在云原生架构中。漂移和倾斜可能是持续时间不一的报告路径或各个主机上时钟之间缺乏紧密同步造成的。通过在流量处理期间跟踪组件之间的通信,分布式跟踪允许OpenTelemetry测量单个跨度(跟踪的工作单位和基本模块),不需要对相关应用程序进行深入的检测。
结合这三种信号(遥测的类别),我们就可以纠正问题,让应用程序恢复到生产级质量:
这时候我们又回到了可观测性2.0。能够获得跟踪并立即查看哪些指标对应哪些跟踪为我们赋予了强大的功能。比如说,当指标表明有问题时,分布式跟踪让您可以一路追溯到导致初始问题的那个特定请求,并跟踪请求实现的每个步骤的进度。由于我们的跟踪是由跨度按照它们发生的顺序组成的,所以我们可以在请求旅程的每一步跟踪请求。了解发生了什么,以什么顺序发生(从初始事件到表明的问题,直到最终结果),让我们能够聚焦于应用程序中具体的部位,集中注意力。
尽管听起来很简单,OpenTelemetry的分布式跟踪方面可以让我们深入了解用户所遇到的一切,作为请求成功和执行时间的代理。作为用户,我关心我的请求。作为站点可靠性工程师(SRE),我关心聚合的请求。作为应用程序所有者,我还关心尾部延迟:在某些条件下,对于少量重要的用户群体而言,尾部延迟可能演变成糟糕的性能。OpenTelemetry为我提供了这三个功能,以及从聚合内容中提炼细节的能力,因为它本身旨在让所有应用程序上的所有数据能够为用户所用。
来自OpenTelemetry的这种新数据流还让我们在开发和操作响应方面可以实现自适应和自动化。有了所有这些积累的数据,我们可以使应用程序更加智能和自适应。而自适应应用程序恰如其名:自动智能地调整其行为以应对环境变化的应用程序。
通过实现遥测数据的可访问性和标准化,OpenTelemetry使通向自适应应用程序的旅程变得更顺坦。随着不同类型的产品开始输出类似的指标,如果利用OpenTelemetry中已确立的语义约定,我们更容易在请求处理期间将它们的操作关联起来,并将这些信息馈送给人工智能(AI)和机器学习(ML)算法,从而使应用程序和基础设施能够动态适应。
对OpenTelemetry的用户和使用它作为遥测通道的应用程序来说,规范遥测是明显的举措。可以从多个数据源收集数据,并转发给任何兼容的聚合和分析工具。此外,OpenTelemetry Collector使供应商不必自行实施收集器。相反,它们可以致力于改善代码,以执行有意义的分析,并采取明智的操作,可以构建新的工具来帮助理解这个复杂而混乱的新世界。实际上,OpenTelemetry Collector(基于开源创新)在让这项技术顺应未来的同时,能够处理几乎所有的现有格式。
OpenTelemetry专注于我们理解应用程序所需的主要数据类别,使我们的应用程序可以为复杂的现代应用程序环境的性能和问题提供更深入的见解。通过关联我们的数据、遵守语义和标准惯例,OpenTelemetry使通向现代应用程序的旅程变得更顺坦。
随着OpenTelemetry项目不断成熟,采用率不断提高,它显然是我们加深了解的方法。我们还希望OpenTelemetry有助于运用AI和ML技术来解决复杂问题、实现自动化补救,并表明如何使云原生应用程序变得更具适应性、性能更好。
原文标题:Why OpenTelemetry Is Taking Cloud Native to New Heights,作者:Dave McAllister
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返
它不等于主线程的binding,这个toplevel作用域是什么?此作用域与主线程中的binding有何不同?>ruby-e'putsTOPLEVEL_BINDING===binding'false 最佳答案 事实是,TOPLEVEL_BINDING始终引用Binding的预定义全局实例,而Kernel#binding创建的新实例>Binding每次封装当前执行上下文。在顶层,它们都包含相同的绑定(bind),但它们不是同一个对象,您无法使用==或===测试它们的绑定(bind)相等性。putsTOPLEVEL_BINDINGput
我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?