- 监控使用预定义的指标和警报来监视已知问题。
- 可观察性 是指您从系统的输出了解系统内部状态的程度。
- 日志、指标和跟踪是常见信号,但收集它们并不能保证洞察力。
- 它们协同工作:监控发出警报,可观察性帮助您找到原因。
仪表板是绿色的,但顾客却抱怨结账系统坏了。如果您处于这个位置,您已经了解监控与可观察性之间的区别。你的监控只检查了你想检查的内容,而这次失败是新的。
本指南在没有营销语言的情况下解释了这两种想法,并跟踪一个虚构事件从警报到根本原因。日志、痕迹和数字是为了说明该过程而发明的。您还应该知道,供应商和从业者以不同的方式划定这条线,有些人认为这在一定程度上是营销上的区别。我们专注于实践部分。
简短的回答
监控是一项活动。您可以提前决定要监视的内容,例如 CPU、错误率或磁盘空间,并设置触发警报的阈值。它回答:“我担心的事情发生了吗?”
可观察性 是系统的一个属性。该术语来自控制理论,它描述了从外部输出推断系统内部状态的能力。在实践中,它回答:“正在发生什么以及为什么发生,包括我从未预料到的问题?”
想想一辆车。仪表盘上的警示灯正在监控。它们涵盖了一系列已知问题。机械师的完整诊断端口可以让人们提出有关发动机任何部分的新问题,更接近于可观察性。
监控与可观察性并存
| 方面 | 监控 | 可观察性 |
|---|---|---|
| 主要问题 | 有什么问题吗? | 为什么错了? |
| 最适合 | 已知的故障模式 | 未知和新颖的失败 |
| 方法 | 预定义的检查和仪表板 | 丰富数据的开放探索 |
| 典型输出 | 警报和状态图 | 新问题的答案 |
| 数据详情 | 经常聚合 | 详细,尽可能根据要求 |
| 设置 | 配置来自外部的检查 | 需要检测您的代码 |
| 使用者 | 运营、值班人员 | 开发人员和值班人员 |
这不是两者之间的选择。您仍然需要警报来告诉您何时查看。
为什么仅仅监控还不够
对于一台服务器上的一个应用程序,可能出现问题的列表相当短,因此您可以全部查看。现代系统可能拥有数十个服务、队列和第三方 API,以及来来去去的容器。失败会变成无人预料到的组合:一个地区、一种客户类型、特定的应用程序版本和单一的缓慢依赖项。
你不能为一个你没有想到的问题提前写一个仪表板。您需要数据以便您事后询问。
日志、指标和跟踪
这三种类型的遥测通常被称为可观测性的支柱。每个人都回答不同的问题:
| 信号 | 它是什么 | 答案 | 弱点 |
|---|---|---|---|
| 指标 | 随时间变化的数字 | 多少钱?情况变得更糟了吗? | 单个事件的一些细节 |
| 日志 | 个别事件记录 | 究竟发生了什么? | 可能成本高昂且噪音大 |
| 痕迹 | 请求通过服务的路径 | 时间都去哪儿了? | 需要仪器并经常采样 |
指标
http_requests_total{service="checkout", status="500"} 1832
http_request_duration_seconds{service="checkout", quantile="0.95"} 2.4
指标的存储成本低且查询速度快,这使得它们非常适合仪表板和警报。在许多度量系统中要警惕高基数标签,例如用户 ID,因为它们会急剧增加成本。
痕迹
跟踪跟踪跨服务的一个请求。每个步骤都是一个 span,具有开始时间和持续时间:
POST /checkout 2410 ms
├─ auth-service: verify token 18 ms
├─ cart-service: load cart 42 ms
├─ pricing-service: calculate 2290 ms <-- slow
│ └─ SELECT coupons ... 2265 ms
└─ payment-service: not reached
跟踪使缓慢的步骤变得明显,这在来自不同服务的单独日志中很难看到。
日志
日志提供某一时刻所发生事件的详细信息。我们稍后会研究如何使它们变得有用。
事件演练
以下是一个虚构的例子,这些部分是如何组合在一起的。
| 步骤 | 信号 | 我们学到了什么 |
|---|---|---|
| 1. 火灾警报 | 公制 | 检查 p95 延迟已超过 1 秒目标 |
| 2. 分解 | 公制 | 仅移动应用程序受到影响,网络不受影响 |
| 3. 检查请求 | 踪迹 | 时间是在定价服务、优惠券查询上 |
| 4.阅读详情 | 日志 | 缓慢的请求全部使用今天活动中的优惠券 |
| 5.确认原因 | 查询计划 | 优惠券查找没有合适的索引 |
| 6.修复它 | 部署 | 添加索引,观察延迟恢复 |
监控处理了第 1 步。之后的一切都是可观察性的。请注意每个问题是如何从前一个答案中得出的。没有人可以提前为“今天活动的移动应用优惠券查询”构建仪表板。对于修复本身,我们的 SQL 查询优化指南 展示了如何阅读此类计划。
更好的日志
纯文本日志是为人眼而制作的,很难查询。 结构化日志使用机器可以过滤的字段:
# Hard to search
ERROR Payment failed for user 42 after 3 tries
# Easy to search
{"level":"error","event":"payment_failed","user_id":"42",
"attempts":3,"provider":"acme","trace_id":"a1b2c3","duration_ms":2410}
使用第二种形式,您可以立即询问“过去一小时内每个提供商有多少次失败?” trace_id 字段特别有价值,因为它将日志行链接到整个请求,跨越它所涉及的每个服务。
切勿记录密码、令牌或卡号,并妥善保管个人数据。正如我们的指南所解释的,JWT 可以被从日志中读取它们的任何人重复使用。
提示: 添加您在事件期间需要的上下文,例如版本、区域、客户等级和功能标志状态。能够说“一个地区只有 2.14 版本”通常可以自行解决问题。
黄金信号
不确定要监控什么? Google 的《站点可靠性工程》一书为面向用户的系统提出了四个信号:
| 信号 | 问题 | 示例 |
|---|---|---|
| 延迟 | 请求需要多长时间? | p95 和 p99 响应时间 |
| 交通 | 有多少需求? | 每秒请求数 |
| 错误 | 有多少请求失败? | 5xx 回复率 |
| 饱和度 | 系统有多满? | CPU、内存、连接池使用 |
使用百分位数表示延迟,因为平均值隐藏了缓慢的请求,如我们在负载测试与压力测试中所示。
提醒人们信任
如果警报一直发出,人们就会停止阅读它们。好的人遵循一些规则:
- 针对用户感受到的症状发出警报。“结帐错误超过 2%”胜过“CPU 为 85%”。不伤害任何人的高 CPU 不应该唤醒任何人。
- 使每个警报都可操作。如果没有人需要执行任何操作,请将其设为仪表板项目或将其删除。
- 运行手册链接。 告诉响应者在哪里查看以及尝试什么。
- 定期查看它们。删除或修复上个月被忽略的所有警报。
服务水平目标
SLO 将“网站应该快速且可靠”转变为可衡量的目标,例如“99.9% 的结帐请求在 30 天内成功”。这允许大约 0.1% 的失败,称为错误预算。如果你还有足够的,你可以更快地发货,如果快用完了,你可以优先考虑可靠性。这是解决交付速度和稳定性之间争论的有用方法。
OpenTelemetry 和工具
OpenTelemetry 是一种开源、供应商中立的标准,用于生成和导出遥测数据。它是云原生计算基金会的一个项目。使用它意味着您可以稍后更改后端而无需重写代码。它本身不是存储或仪表板产品,因此您可以将其与以下产品配对:
| 目的 | 开源示例 | 商业实例 |
|---|---|---|
| 指标 | 普罗米修斯 | 数据狗,新遗物 |
| 仪表板 | 格拉法纳 | 数据狗、Dynatrace |
| 日志 | 洛基,开放搜索 | Splunk,弹性 |
| 痕迹 | 耶格,节奏 | 蜂窝,数据狗 |
请自行检查当前功能和定价,因为这些产品经常变化。成本会随着数据量的增加而快速增长,因此请使用采样并设置保留限制。
如何开始
- 从黄金信号开始为您提供最重要的服务。
- 针对用户注意到的症状添加一两个警报。
- 切换到结构化日志, 每行都有一个请求 ID。
- 添加追踪到您使用 OpenTelemetry 的主要用户旅程,因为自动检测可以涵盖许多常见框架。
- 将部署链接到您的图表,以便您可以查看 CI/CD 管道中的发布是否导致了更改。
- 从每个事件中学习。 在每个事件之后,询问哪些数据可以让问题更快地得到解决,然后添加该数据。
只提供一项服务的小团队不需要庞大的平台。基本指标、良好的日志和一些警报可能就足够了。随着服务数量的增加,追踪也能获得收入。
常见错误
- 购买一个工具并将其称为可观察性。价值来自良好的仪器以及如何使用数据。
- 将三个支柱视为清单。 单独的数据无法链接,这会让您在选项卡中寻找。共享 ID 很重要。
- 收集所有内容。未经过滤的遥测数据成本高昂,而且会增加噪音。
- 仪表板太多。 一些受信任的视图胜过了一百个没有人打开的视图。
- 认为它取代了测试。 在发布之前你仍然需要测试。不过,金丝雀发布与这些信号很好地搭配。
最后的话
监控会告诉您出现了问题,而可观察性则为您提供了找出原因的方法。实际测试很简单:当出现不熟悉的问题时,你能在不发布新代码的情况下找到原因吗?下次遇到事故时,写下您无法回答的每个问题。该列表就是您的路线图。
常见问题
监控和可观察性有什么区别?
监控跟踪预定义的指标并针对已知问题发出警报。可观察性是指从系统输出中了解系统状态的能力,包括意外问题的能力。
可观察性的三大支柱是什么?
它们是日志、指标和跟踪。日志记录事件,指标测量一段时间内的值,跟踪跟踪跨服务的单个请求。
如果我有监控,我还需要可观察性吗?
对于一个小型、简单的系统,良好的监控和日志可能就足够了。随着系统变得分布式并且故障变得越来越难以预测,可观察性变得更有价值。
什么是开放遥测?
它是一个开源标准和一组用于生成和导出日志、指标和跟踪的工具,因此您不必依赖于单个供应商的代理。
四个黄金信号是什么?
它们是延迟、流量、错误和饱和度。 Google 的 SRE 指南建议将这些作为监控面向用户的系统的起点。
继续学习
需要测试、WordPress 或 SEO 方面的帮助?
我们帮助团队交付更好的软件并发展他们的网站。告诉我们您正在做什么,我们将建议明确的下一步。
更多指南 测试、人工智能和现代开发
喜欢这篇文章吗?选择一个主题并直接跳至我们最新的教程。
人工智能幻觉解释:语言模型为何会产生幻觉以及如何减少它
人工智能幻觉解释:它们是什么,为什么语言模型产生它们,常见类型,如何通过基础和提示来减少它们,以及我们进行的简单检查。
阅读文章 →DevOps环境变量解释:.env 文件、秘密和配置正确完成
使用我们运行的 Python 示例解释环境变量:读取和设置它们、为什么每个值都是字符串、.env 文件、进程继承、秘密和验证。
阅读文章 →软件开发API 速率限制解释:算法、标头和处理 429 错误
API 速率限制通过我们运行的模拟进行了解释:令牌桶、固定窗口、滑动窗口、429 响应、速率限制标头、带回退的重试和测试限制。
阅读文章 →测试自动化Python 中的模拟:unittest.mock、补丁以及导致测试谎言的错误
使用unittest.mock 在Python 中进行模拟,经过测试:模拟和return_value、side_effect、修补使用名称的位置、spec 和autospec、模拟日期以及常见错误。
阅读文章 →软件测试代码覆盖率解释:行覆盖率与分支覆盖率以及 100% 的真正含义
用真实的coverage.py运行来解释代码覆盖率:行、分支和条件覆盖率,阅读报告,为什么100%覆盖率仍然会错过错误,以及合理的目标。
阅读文章 →数据库与 SQLSQL 中的 DELETE、TRUNCATE 和 DROP:差异、回滚以及何时使用它们
DELETE、TRUNCATE 和 DROP 通过经过测试的 SQL 进行了解释:各自删除什么、回滚、触发器、身份重置、速度,以及 PostgreSQL、MySQL、SQL Server 和 SQLite 有何不同。
阅读文章 →数据库与 SQLSQL 视图解释:创建、使用和避免陷阱(附示例)
SQL 视图通过我们运行的查询进行解释:创建视图、实时结果、隐藏列、性能、可更新和物化视图、破坏的依赖关系和最佳实践。
阅读文章 →软件开发TypeScript 接口与类型:真正的差异,使用编译器进行测试
TypeScript 接口与类型,使用真实编译器进行检查:两者都可以做什么,只有一个可以做什么,声明合并,扩展与交集以及要遵循的简单规则。
阅读文章 →软件开发Python *args 和 **kwargs 解释:灵活的函数和清晰的示例
Python *args 和 **kwargs 用我们运行的代码进行了解释:打包和解包、参数顺序、仅关键字和仅位置参数、装饰器和常见错误。
阅读文章 →软件开发Python Lambda 函数:语法、实际用途以及何时不使用它们
Python lambda 函数用我们运行的代码进行了解释:语法、使用键排序、映射和过滤器、闭包、后期绑定陷阱,以及何时普通 def 是更好的选择。
阅读文章 →人工智能什么是人工智能代理?它们是如何工作的,只需运行一个简单的代理循环
什么是人工智能代理?关于代理循环、工具、内存和护栏的简单指南,以及我们运行的一个小型 Python 循环、真正的风险以及何时简单的聊天机器人是更好的选择。
阅读文章 →DevOps监控与可观察性:真正的区别,包括日志、指标和跟踪
监控与可观察性解释:已知和未知的故障、日志、指标和跟踪、检查事件演练、黄金信号、OpenTelemetry 和有用的警报。
阅读文章 →DevOpsDocker Volumes 与 Bind Mounts:以正确的方式保留容器数据
Docker 卷与绑定挂载解释:为什么容器数据消失、命名卷、绑定挂载、tmpfs、Compose 示例、备份、权限以及何时使用它们。
阅读文章 →测试自动化TDD 与 BDD:主要区别、以两种方式构建的一个功能以及何时使用每种方式
TDD 与 BDD 的解释是通过一种双向构建的折扣功能:使用我们运行的代码进行红绿重构、Given-When-Then 场景、工具、权衡以及何时使用每种方案。
阅读文章 →软件开发Git merge 与 rebase 的区别:示例及如何选择
用真实的 log 输出、对比表、rebase 黄金法则和安全的团队工作流,讲清 Git merge 与 rebase 的区别。
阅读文章 →软件开发Python 列表推导式:语法、示例与何时避免使用
Python 列表推导式详解:语法、过滤、if-else、嵌套循环、实测耗时,以及何时普通 for 循环更合适。
阅读文章 →数据库与 SQLSQL JOIN 详解:附示例(INNER、LEFT、RIGHT、FULL)
通过示例表和查询,一步步讲解 SQL JOIN:INNER、LEFT、RIGHT、FULL、CROSS 和 SELF,并介绍常见错误与性能技巧。
阅读文章 →