English· Español· Deutsch· Nederlands· Français· 日本語· ქართული· 繁體中文· 简体中文· Português· Русский· العربية· हिन्दी· Italiano· 한국어· Polski· Svenska· Türkçe· Українська· Tiếng Việt· Bahasa Indonesia

un

访客
1 / ?
返回课程列表

欢迎

欢迎

Web 规模的集群包含大量机器。在任意时刻,部分机器运行正常,部分正在启动,部分正在排空流量,部分则已悄然故障。集群之所以能在这种状态下存活,是因为每台机器都能按需回答两个简单的问题:

- /health — 我当前是否能够处理真实请求?

- /version — 我正在运行什么代码?

外加一个指标端点(通常为 /metrics),用于暴露计数器(counters)和仪表值(gauges),供监控工具抓取。

本教程将教你如何设计这些端点,使其真正反映实际状态,解释在代理层中“四大黄金信号”的含义,以及观察到的数据如何驱动容量决策。

学完本教程后,你将能够:

- 设计一个 /health 端点,用于检测真实的路径故障,而不仅仅是进程存活状态

- 设计一个 /version 端点,以便验证部署是否已生效

- 在代理层应用四大黄金信号(延迟、流量、错误、饱和度)

- 将观察到的激增指标与容量决策联系起来:何时扩容、何时排空流量、何时触发告警

- 基于 SLO 和错误预算消耗率进行推理,将其作为“我们该有多在意?”背后的运营准则

两种健康检查

存活检查 vs 就绪检查

存活检查(Liveness):进程是否还活着?由编排器(如 Kubernetes、systemd)使用,以决定是否重启该进程。

就绪检查(Readiness):进程当前是否准备好处理真实流量?由负载均衡器使用,以决定是否向其发送请求。

这是两个不同的问题。一个无法连接数据库的进程是“存活”但“未就绪”的。一个正在启动中的进程是“存活”但“尚未就绪”的。

浅层 vs 深层健康检查

浅层检查:如果 HTTP 处理器能运行,则返回 {"status": "ok"}。非常基础。仅能检测进程宕机。

深层检查:实际执行真实的请求路径。检查数据库连接池能否返回连接、缓存是否可达、下游依赖是否响应。能够检测出浅层检查遗漏的功能性故障。

权衡:深度检查成本更高(每次检查本质上都是一个合成请求),且可能引发级联故障(如果每个副本的健康检查都猛烈冲击数据库,一个缓慢的数据库会使所有副本变为不健康状态,从而将它们从轮询中移除,进而移除所有容量)。

最佳实践:使用浅层检查用于存活状态(快速、低成本、无外部依赖),并使用更深层的检查用于就绪状态(缓存结果,限流以避免猛烈冲击下游服务)。

版本端点

/version 返回 git 提交哈希、构建时间和服务名称。部署后,你执行 curl https://service.example.com/version 并确认返回的提交哈希与你推送的一致。如果不一致,说明部署静默失败了。

如果没有 /version,一个过期的部署可能看起来是成功的,并隐藏数小时。

最小响应结构{"service": "my-api", "git_commit": "abc1234", "build_time": "2026-05-19T10:00:00Z"}

某团队的负载均衡器配置为在连续 3 次健康检查失败后将副本从轮询中移除。他们当前的 `/health` 端点立即返回 `{"status": "ok"}`。团队感到惊讶的是,在一次事故中,尽管没有任何副本能够连接到数据库,但所有副本仍显示为健康状态。请设计一个更好的就绪检查(readiness check),以便能够检测到数据库中断,并解释你的新设计引入的一个具体风险。

延迟、流量、错误、饱和度

四个数字覆盖大部分运维工作

源自《Google SRE 书籍》。在每一个服务层级上测量的四个信号。如果你能很好地对这些信号进行插桩(instrumentation),你就能在用户察觉之前发现大部分生产环境问题。

延迟(Latency):请求需要多长时间?应报告分布情况,而不仅仅是平均值。p99(第 99 百分位延迟)比平均值更重要,因为尾部延迟才是用户感知到的“慢”。一个平均延迟为 50 毫秒但 p99 高达 5,000 毫秒的服务存在真实问题,大多数用户可能从未察觉,但受影响最严重的 1% 用户绝对能感受到。

流量(Traffic):每秒有多少请求?包括总请求数、按端点、按状态码、按区域统计。已知基线;对异常情况进行告警(突然下降 = 入口问题;突然激增 = 流量高峰或攻击)。

错误(Errors):失败请求的比率。区分 4xx(客户端错误,非你的责任)和 5xx(服务器错误,你的责任)。将错误率作为流量百分比来跟踪,而不是绝对计数,以便告警在不同负载水平下都能正常工作。

饱和度(Saturation):系统有多满?CPU 使用率、内存、连接池深度、队列长度。这是领先指标。饱和度会在延迟或错误恶化之前上升。一个处于 90% 饱和度的层级,只需糟糕的一分钟就会面临队列崩溃。

具体到代理层级

每个信号在边缘层都会亮起:

- 代理处的延迟:TLS 握手持续时间、上游连接时间、请求-响应总时间。由于它们位于路径的不同部分,因此分别测量。

- 代理处的流量:每秒总请求数、按后端分布(热门后端表明负载均衡倾斜)、按状态码细分。

- 代理层的错误:来自客户端的 4xx(您的用户访问了错误的端点),来自后端的 5xx(您的服务出现故障),以及代理内部错误(502 = 无法连接后端,504 = 后端超时)。

- 代理层的饱和度:TLS 会话数量、上游连接池深度、代理本身的 CPU 使用率(TLS 终止是 CPU 密集型操作)。

专业提示:如果 502 错误突然增加,但后端延迟很低,这意味着后端在响应之前断开了连接(连接重置、崩溃、内存溢出)。如果 504 错误增加,意味着后端响应缓慢但仍在应答。阅读错误代码;它会告诉您故障发生在哪里。

单一仪表板上的四个黄金信号:延迟、流量、错误、饱和度

解读信号

您的仪表板显示过去 10 分钟内的以下情况:

- 流量:大致平稳在 800 req/s(没有激增)

- 延迟:p50 稳定在 40ms,p99 在 5 分钟内从 200ms 攀升至 2,500ms 且仍在上升

- 错误:4xx 比率稳定在 0.3%(正常背景值);5xx 比率从 0.1% 上升至 1.2%(主要为 504 网关超时)

- 饱和度:后端 CPU 在同一 5 分钟内从 45% 上升至 78%;代理 CPU 稳定在 30%

诊断当前状况。最可能的故障模式是什么?哪一两项后续测量可以证实或反驳你的假设?如果趋势持续,你在接下来的 5 分钟内会采取什么行动?

何时扩容,何时排空,何时呼叫人工介入

容量决策需要触发条件

观察指标很容易。知道何时根据指标采取行动,才是其中的纪律所在。

在以下情况下扩容:饱和度持续超过阈值(例如,后端 CPU >70% 持续 5 分钟),或队列深度超过目标值,或 p99 延迟超过 SLO。触发条件应在系统崩溃之前触发,而不是在崩溃时触发。

在以下情况下排空副本:当某个副本持续缓慢或出错,而其他副本运行正常时(单个副本运行过热通常是主机级问题,而非应用问题),或在推出新版本时,或在优雅地退役副本时。

在以下情况下呼叫人工介入:当 SLO 的消耗速度超过错误预算所能承受的范围时,或当饱和度触发条件被触发但自动扩缩容未能吸收该负载时,或当出现级联模式时(错误率和重试率同时上升)。

在以下情况下不要呼叫人工介入:当单个异常分钟自行恢复时,或当后台批处理任务导致预期的周期性波动时,或当噪声超过阈值时(此时是阈值设置错误,而非系统故障)。

SLO 与错误预算消耗

SLO(服务级别目标)定义了可接受的性能标准:“28 天窗口内的成功率 >= 99.9%”。其补集(0.1%)即为错误预算。

消耗速率(Burn rate):指你消耗错误预算的速度。如果你在 1 小时内消耗了 10% 的预算,那么消耗速率是可持续速率的 240 倍(1 小时是 28 天窗口的 1/672;在该窗口内消耗 10% = 10% × 672 = 整个窗口预计消耗 6720%,而允许的最大值为 100%)。

多窗口消耗速率告警:当短窗口(5 分钟,14.4 倍速率)和长窗口(1 小时,6 倍速率)的消耗速率均超过可持续速率时触发页面告警。这能同时捕捉快速故障和缓慢的性能退化。

这对容量的重要性:一个运行在 99.9% SLO 且拥有 1% 余量的服务可以吸收轻微的性能波动。而一个处于 99.93%(勉强达到 SLO)的服务,只需一个糟糕的日子就会违反 SLO。容量决策应针对舒适的 SLO 余量,而非仅仅达到最低标准。

观察下的容量决策

你的服务 SLO 为 28 天内 99.9% 的请求成功。过去一小时的监控当前状态如下:

- 成功率:99.5%(持续 30 分钟)

- 后端 CPU:整个集群平均使用率为 82%(目标值 70%)

- p99 延迟:800 毫秒(SLO 目标:<500 毫秒)

- 流量:1,400 请求/秒,高于基线 1,000 请求/秒(比正常水平高 40%;且趋势仍在上升)

- 自动扩缩容:配置为当 CPU 持续 5 分钟超过 80% 时增加副本;目前正处于扩容过程中,将在约 90 秒内增加 3 个副本

请做出三项决策:(1) 这是否属于需要立即呼叫人工介入(Paging)的事故?(2) 除了等待自动扩缩容完成外,是否应采取其他即时行动?(3) 如果流量趋势是平稳的而非上升的,你的决策会有什么不同?请为每项决策提供理由。

设计一个发布可观测性计划

综合

你现在可以设计一个能捕获真实故障的 /health 端点,一个用于验证部署的 /version 端点,代理层级的四黄金信号仪表盘,以及与 SLO 消耗率绑定的容量触发器。

应用全部四项。

你的团队正在发布 search.example.com(来自故障模式课程中的搜索服务)。团队希望推出可观测性,以便在用户之前发现问题,并配备清晰的“是否告警”决策矩阵。SLO:99.9% 的请求成功,p99 延迟 < 300 毫秒,统计窗口为 28 天。

设计发布可观测性计划。需涵盖:(1) 每个后端副本及每个代理的 `/health` 与 `/version` 接口返回什么,(2) 在代理层和后端层需要哪些“四黄金信号”仪表盘,(3) 自动扩缩容在什么阈值下触发扩容,以及 (4) 在什么阈值下触发人工告警(在适用情况下使用 SLO 燃烧率)。

课程结束

课程结束

你已完成全部五个课程:

- 代理与源站:几乎每个公共 Web 服务都在边缘层使用的架构形态

- 无状态水平扩展:为什么无状态层可以低成本地倍增,以及如何确定其规模

- 入站与出站分离:为什么一台机器会变成两台,以及迫使这种分离的故障模式

- 故障模式与爆炸半径:单点故障(SPOF)、级联故障、事后复盘(Postmortems)、无责行动项

- 可观测性与容量(本课重点):测量什么指标,以便在用户察觉之前让问题浮出水面

核心主线:Web 规模的分布式系统并非魔法。它是一组小规模的模式(反向代理、无状态副本、入站/出站分离、舱壁与熔断器、四大黄金信号)经过深思熟虑的组合。一旦你识别出这些模式,就能在每一个生产级架构中看到它们。

配套课程:五节“几何之*”课程将同样的内容重新表述为图论与几何。无论以何种顺序学习都很合适。

干得漂亮。