关键要点
● 大多数可观察性数据都位于未处理的磁盘上,提供的洞察力和价值都很少。
● 尽管有所有可观察性工具,调试仍然非常困难。
● 可观察性的三大支柱:指标、日志和跟踪,虽然必要,但还不够。
● 想法 1:要求用户构建他们的可视化是不够的;我们必须像分析器一样思考,并创建开箱即用的火焰图等细致入微、巧妙的视图。
● 想法 2:通过与代码紧密集成的选择性深度跟踪为故障排除者创建反馈循环
随着越来越多的企业采用微服务架构,他们很快发现构成其应用程序的服务分散在许多机器上。在这样一个高度分布式的环境中,了解这些系统以及它们的运行方式就像大海捞针一样。幸运的是,我们可以转向可观察性来使我们的系统可见。
为什么我们需要对系统的可见性?答案主要有三个:系统可靠性、合规性和对增长驱动力的洞察。虽然理论上这三种方法都是可能的,但到目前为止,可观察性主要用于站点可靠性,因为合规性和增长驱动工具都有自己的数据收集方式,很少利用可观察性数据。一旦数据收集规范有了更广泛的标准化,所有三种类型的工具很可能都将使用可观察性数据。
在本文中,我们将重点关注站点可靠性。可观察性通过提供快速排除和修复问题甚至主动阻止问题发生所需的数据和见解来帮助站点可靠性团队。
01目前的可观察性技术水平还不够
迄今为止,我们在可观察性数据收集方面取得了相当大的成功,但数据经常以行的形式(例如跨度)存储在磁盘中。不幸的是,这些数据几乎没有什么用处,而且很少有洞察力被派生出来。因此,只交付了承诺价值的一小部分。
尽管有所有可用于站点可靠性的可观察性工具,但调试仍然非常困难,许多站点可靠性工程师 (SRE) 都同意他们的调试过程仅略有改进。
可观察性仍处于相对初期,正如 Bogomil Balkansky [1] 所指出的,它可能会经历更多的重新设计浪潮,在每一波浪潮中创造更多的价值。
从广义上讲,可观察性包含三个要素:收集正确的数据,向用户展示正确的数据,然后通过让工程师深入研究问题来关闭循环。这些由可观察性的三个支柱支持:指标、日志和跟踪。然而,虽然这些支柱是必要的,但还不够。
本文试图从用户的角度描述故障排除的可观察性可以并且应该如何实现。
02收集正确的数据
当我们谈论可观察性时,有两组工具:特定的可观察性工具,例如 Zipkin 和 Jaeger,以及更广泛的应用程序性能监控 (APM) 工具,例如 DataDog 和 AppDynamics。
在监控系统时,我们需要从方法和操作系统级别跟踪到数据库、服务器、API 调用、线程和锁数据跟踪的各个级别的信息。要求开发人员添加工具以获取这些统计数据既昂贵又耗时,应尽可能避免。相反,开发人员应该能够使用插件、拦截和代码注入来尽可能多地收集数据。
APM 工具在这方面做得很好。通常,他们在程序语言中内置了工具(例如 Java 代理)来收集方法级别的跟踪数据,并且他们添加了自定义过滤器逻辑,以通过查看方法跟踪来检测数据库、服务器、API 调用、线程和锁定数据跟踪。此外,他们还在常用的中间件工具中添加了插件来收集和发送检测数据。这种方法的一个缺点是仪器需求将随着编程语言和中间件的发展而变化。
使用微服务,大多数处理跨越多个服务,因此跨越多台机器。因此,到目前为止我们讨论的数据是在许多机器上收集的,为了理解端到端的处理,我们必须通过所有调用传播上下文,甚至是异步调用。
例如,当系统接收到一个请求时,应该创建一个标识符并将其传递给该请求触发的所有调用。系统的不同部分应在所有指标、跟踪和日志中包含该标识符,这使我们能够稍后连接与调用相关的所有处理。还有其他方法可以达到相同的结果。例如,开放遥测在每个父进程和客户端进程之间共享一个标识符,但使用这种方法,端到端跟踪请求会产生更多开销。
收集数据会增加开销,如果系统处理大量负载,通常不可能测量所有内容。通常,日志量已经针对大型工作负载进行了很好的调整,因此易于管理。由于我们定期收集指标,系统上的较大负载通常不会显著增加指标收集开销。相比之下,跟踪开销与请求的数量直接相关,并且在面对大负载时通常无法完全跟踪。甚至Google 的 Dapper 系统也只跟踪每 1000 个请求中的 1 个。
所以我们必须通过只跟踪少数请求进行采样,例如每 100 个请求中的 1 个。通过采样,我们可以减少开销,但是当发生错误时,我们有可能在收集的数据中没有相关的可观察性数据。这导致了我们需要准备应对的挑战。
首先,如果每个服务都独立挑选样本,我们将只对给定请求进行一些跟踪。这可能导致我们只有每个用户请求的一小部分,从而使可观察性变得无用。为避免在采样时出现这种情况,我们应该挑选一些用户请求并完整详细地端到端跟踪它们。
第二个挑战是,对于每秒处理 5,000 个请求的服务来说,100 分之一的采样率非常好,但对于每天只有 50 条消息的服务来说就不行了。更具适应性的采样策略(例如每秒最多 100 个样本)会更好地工作。
需要做更多的工作来智能地选择要采样的请求。例如,一种提议的方法查看最近的数据并预测哪些请求最有可能出错。然后它会跟踪这些请求。
03向疑难解答人员提供正确的数据
工程师不能一直查看日志或图表并等待问题发生。当潜在问题出现时,我们需要向他们发送警报。警报可以有多种形式,例如电子邮件、SMS 或PagerDuty警报。
当警报到达时,使用可观察性数据进行故障排除的工程师不应遍历所有数据。这根本不是有效利用他们的时间。相反,我们首先需要一种方法来检测性能异常并将开发人员或工程师的注意力引导到相应的数据上。一旦用户收到警报并签到,我们应该以最容易理解并指出潜在异常的形式呈现数据。
可观察性系统可以通过用户定义的规则或结合统计分析和机器学习来实现异常检测。尽管我们在这两种方法中都使用了这些解决方案,如故障草图示例所示,但后者仍有显著改进的空间。
大多数当前工具通过让用户创建自己的视图和图表来解决数据表示问题。然后,工程师可以决定要呈现的有用的关键绩效指标 (KPI) 并创建自己的相应图表,他们可以使用这些图表进行调试和故障排除。
这样的图表对于检测系统的当前状态和注意常见的重复问题很有用。但是,它们不适用于故障排除过程,在这些过程中,工程师为问题的原因创建假设,然后反复向下钻取、验证——如果需要,改进或更改假设。
相反,我们可以向分析器学习,例如 Java Flight recorder。Profilers 既不提供仪表板工具,也不要求用户创建自己的图表来理解问题。相反,它们提供了一些精心设计的视图,例如帮助工程师排除故障的调用树、热点视图或内存视图。可观察性工具也可以做到这一点。
本节的其余部分描述了几个有效的可观察性视图。他们深受 Cindy Sridharan [2] 提出的建议以及我自己在性能故障排除和数据科学方面的经验的影响。
当工程师知道存在潜在问题并使用可观察性系统进行调查时,他们需要快速跳转到可能发生潜在问题的时间,并在上下文中显示指标、日志和跟踪。
例如,以下视图以有意义的方式显示了沿时间线排列的日志和指标。用户可以在单个视图中查看发生了什么以及指标的行为方式。通常,人眼卓越的模式检测能力有助于将当前情况与过去的经验联系起来。
我们可以通过将通过人工智能 (AI) 识别的潜在异常直接注释到视图中来进一步帮助工程师。
我们可以通过将其与其他视图进行对比来理解上述视图的价值。许多可观察性工具使用替代视图,用户可以在其中绘制多个图并根据分析时间同时在所有图中移动光标。虽然更容易实现,但该视图对视觉模式识别 [3] 的帮助不如上述视图,因为多个时间序列是分散的,不能自然地融入单个视图。另一方面,提议的视图在同一屏幕上显示所有相关数据,使人眼更容易比较和对比。
如果有与问题相关的明显变化点,前一种观点将对工程师有很大帮助。但是,可能问题比较分散,在特定的时间点很难识别。在这种情况下,为了找到问题,我们查看聚合数据而不是特定跟踪。
例如,下面的火焰图显示了延迟是如何在跨多个请求聚合的不同函数之间分布的。
(图片来源:MediaWiki)
该视图将瓶颈呈现为山谷,如果需要,用户可以随时间比较此视图并创建差异图表,显示当前轨迹与正常行为的不同之处。
在其他一些情况下,问题起源于某一点并在整个系统中表现出来。然后,为了找到罪魁祸首,我们需要一个拓扑视图来显示促成请求的组件之间的依赖关系。
例如,如果数据库变慢了,我们将看到所有下游服务都显示出高延迟,甚至是连接堆叠。只有了解错误如何通过拓扑传播,我们才能找到根本原因。
为了使分析变得简单和集中,动态生成的拓扑结构非常有用,它只显示相关的服务和服务器或 API。
当我们找到潜在原因时,我们会切换到与有问题的执行相关的跟踪,并逐步通过它们来查找问题。此时,与源代码编辑器集成很有帮助,用户可以在单步执行跟踪时查看源代码。
这些视图是详细的、连接的和细化的,让工程师可以过滤、向下钻取和放大问题。最终用户很难自己构建这种丰富细致的用户体验。相反,可观察性工具应该构建在这些视图中,并让工程师通过选择视图下的数据馈送来定制它们。例如,通常根据延迟绘制上面的视图,但该工具可以让用户更改视图以选择不同的度量,例如锁定等待时间,以放大特定问题。
另一个相关且有趣的见解是在特定问题发生之前整个系统发生了什么变化。错误通常是由系统中的某些更改引起的,例如代码更新、配置更改、依赖项更新,甚至是部署更改。正如 Bogomil Balkansky [1] 所讨论的,从持续集成和持续交付 (CI/CD) 管道和主动部署中提取数据的能力也可以极大地改进故障排除过程。例如,如果组织已经在使用 GitOps,这就是显示两种部署之间的差异的问题。
最后,可观察性系统本身可以通过查明潜在的根本原因并解释证据来帮助工程师。大多数现有工具至少有一个用例,但它们仅适用于有限类型的问题。可解释的人工智能,可以解释它们如何得出预测的人工智能模型已经取得了一些进展。然而,这仍然是一个不断发展的领域。
04关闭循环
故障排除是一个迭代过程,工程师深入研究故障周围的数据,创建假设,设计实验并进行测试。如果假设失败,新的数据将使他们能够形成新的假设,循环重复。
对于复杂、分散的微服务应用程序,这个过程需要与可观察性系统一起工作。一旦形成假设,工程师就会开始调试过程,其中包括检查运行时状态以获取更多信息或尝试修复。
可观察性方法的深度集成将显着简化流程。以下是这种深度集成的潜在用途。
首先,为了简化调试过程,工程师通常需要更详细的指标或跟踪。因此,可观察性系统应该让这些用户选择某些代码区域进行深度跟踪,或者将监视语句发送到正在运行的代码,这会将结果循环回可观察性视图。
与开发环境的紧密集成将让工程师一键打开源代码并查看覆盖在代码上的选定指标。他们可以进行更改并将其推送到暂存区域或一小部分流量,以从代码覆盖或可观察性视图中获取反馈。
05结论
微服务架构将应用程序分散在多台机器上,使故障排除更加困难。可观察性工具旨在揭开面纱,向用户提供有关系统执行的详细信息,并帮助他们放大任何问题。虽然它们今天提供了一些帮助,但如果可观察性工具要成为有效的、主流的微服务架构故障排除解决方案,那么提高收集和呈现正确数据的能力将是至关重要的。
有疑问加站长微信联系(非本文作者)