Skip to content

本模块聚焦可观测性体系建设,涵盖监控、日志、链路追踪、告警、服务质量和混沌工程等核心主题,从三大支柱到 SRE 方法论,全面考察候选人的可观测性视野和实战经验。

Q1: 什么是可观测性?三大支柱是什么? 「🟡 中级」

考察点:考察可观测性基础概念,筛掉对可观测性理解片面、只知道监控不知道日志和追踪的人。

参考答案

  • 可观测性(Observability) 是指通过系统的外部输出来推断其内部状态的能力。在软件系统中,可观测性是衡量我们能否通过系统产生的数据来理解和排查系统行为的能力。
  • 可观测性不是监控的同义词,监控是可观测性的一部分。监控关注的是"已知的未知"(你知道要监控什么指标),而可观测性关注的是"未知的未知"(帮助你理解从未预料到的问题)。

三大支柱(Three Pillars)

  1. 指标(Metrics)

    • 可聚合的数值型数据,用于衡量系统的状态和趋势。
    • 特点:数值化、可聚合、时间序列、低存储开销。
    • 常见指标:QPS、错误率、延迟、CPU 使用率、内存使用量。
    • 工具:Prometheus、Graphite、InfluxDB、Datadog。
    • 用途:告警、趋势分析、容量规划、SLO 衡量。
  2. 日志(Logs)

    • 系统运行时产生的离散事件记录,是不可变的时间戳文本。
    • 特点:信息丰富、包含上下文、非结构化或结构化、数据量大。
    • 常见日志:应用日志、访问日志、错误日志、审计日志。
    • 工具:ELK/EFK、Loki、Splunk、Graylog。
    • 用途:错误排查、问题定位、审计追踪、行为分析。
  3. 链路追踪(Tracing)

    • 记录单个请求在分布式系统中的完整调用路径和耗时分布。
    • 特点:端到端视角、跨服务、可视化调用链、性能瓶颈定位。
    • 核心概念:Trace(整个请求链路)、Span(单个服务/操作)、Annotation(事件标记)。
    • 工具:Jaeger、Zipkin、SkyWalking、OpenTelemetry。
    • 用途:性能瓶颈分析、跨服务故障定位、依赖关系梳理。

三者关系

  • 指标告诉你"哪里出了问题"(系统是否健康)。
  • 日志告诉你"问题是什么"(具体错误信息)。
  • 追踪告诉你"问题在哪条路径上"(调用链中的哪个环节)。
  • 三者互相补充,配合使用才能构建完整的可观测性体系。
可观测性三大支柱的关系:
指标发现异常 → 追踪定位瓶颈 → 日志查找根因
  (where)        (which path)     (why)

现代可观测性的发展趋势

  • 统一可观测性:指标、日志、追踪数据打通,关联分析(如从指标异常点跳转到相关日志和追踪)。
  • OpenTelemetry:统一的数据采集标准和 SDK,避免厂商锁定。
  • eBPF 无侵入采集:无需修改代码即可采集网络、系统级数据。
  • AIOps:利用 AI 辅助告警降噪、根因分析、异常检测。

追问延伸

  • 可观测性和监控有什么区别和联系?
  • 三大支柱是不是缺一不可?小团队应该先从哪个入手?
  • 什么是 OpenTelemetry?它和 OpenTracing、OpenCensus 是什么关系?
  • 你怎么理解"未知的未知"?举个例子。

Q2: Prometheus的架构和原理是什么? 「🟡 中级」

考察点:考察 Prometheus 监控系统的理解深度,筛掉只会用 Grafana 看图、不了解 Prometheus 原理和架构的人。

参考答案

  • Prometheus 是一个开源的监控和告警系统,基于时间序列数据库(TSDB),以 Pull 模式采集指标,是云原生监控的事实标准,CNCF 毕业项目。

核心架构组件

  • Prometheus Server
    • 核心组件,负责指标抓取、存储和查询。
    • 包含三个模块:Retrieval(抓取)、TSDB(存储)、HTTP Server(查询接口)。
  • TSDB(时序数据库)
    • 本地时序数据库,高效存储时间序列数据。
    • 数据模型:Metric Name + Labels → 时间序列。
    • 存储结构:按时间分片的 block,每个 block 内有索引和样本数据。
    • 支持远程存储对接(Thanos、VictoriaMetrics、M3DB)。
  • Exporter
    • 指标采集代理,将各类系统的指标转换为 Prometheus 格式供抓取。
    • 常见 Exporter:Node Exporter(主机指标)、Blackbox Exporter(黑盒探测)、Redis/Mysql Exporter 等。
  • Pushgateway
    • 支持 Push 模式的中间组件,用于短生命周期任务的指标上报。
    • 任务将指标推送到 Pushgateway,Prometheus 从 Pushgateway 拉取。
  • Alertmanager
    • 告警管理组件,接收 Prometheus 的告警。
    • 功能:分组、抑制(Inhibition)、静默(Silence)、路由、通知。
    • 支持多种通知渠道:邮件、Webhook、企业微信、Slack、PagerDuty 等。
  • 服务发现(Service Discovery)
    • 动态发现监控目标,无需静态配置。
    • 支持 K8s、Consul、DNS、EC2、文件等多种服务发现方式。
  • Grafana
    • 可视化面板工具,通过 PromQL 查询 Prometheus 数据并展示图表。
    • 不是 Prometheus 自带组件,但是最常用的可视化搭配。
Prometheus 架构图:
┌──────────┐  ┌──────────┐  ┌──────────┐
│ Exporter │  │ Exporter │  │ Pushgateway│
└────┬─────┘  └────┬─────┘  └─────┬─────┘
     │ Pull        │ Pull         │ Pull
     ▼             ▼              ▼
┌──────────────────────────────────────┐
│          Prometheus Server           │
│  Retrieval  →   TSDB   →  HTTP API  │
└───────┬──────────────────┬──────────┘
        │                  │
        ▼                  ▼
  ┌──────────┐       ┌─────────┐
  │Alertmanager│       │ Grafana │
  └─────┬────┘       └─────────┘


    通知渠道

核心特点

  • Pull 模式:主动拉取指标,相比 Push 模式更易控制采集频率、便于服务发现。
  • 多维数据模型:通过 Label 实现灵活的维度聚合和过滤。
  • PromQL:强大的查询语言,支持聚合、计算、预测等。
  • 联邦集群(Federation):支持层级化部署,上层 Prometheus 拉取下层 Prometheus 的指标。
  • 单机性能强:单机可处理百万级时间序列。

追问延伸

  • Pull 模式和 Push 模式各有什么优缺点?
  • Prometheus 的数据模型是什么?Label 有什么作用?
  • Prometheus 的本地存储有什么限制?大规模场景怎么解决?(远程存储、联邦、Thanos)
  • 什么是 PromQL?能写几个常用的 PromQL 查询吗?(rate、increase、topk、histogram_quantile)

Q3: 常用的监控指标有哪些?RED方法和USE方法 「🟡 中级」

考察点:考察指标设计的方法论,筛掉只会堆砌指标、没有系统性指标设计思路的人。

参考答案

  • 好的监控指标体系不是越多越好,而是要能快速发现问题、定位问题。业界有两种经典的指标设计方法论。

RED 方法(面向服务)

  • RED 方法由 Tom Wilkie 提出,主要适用于微服务/请求驱动型服务的监控。
  • R - Rate(速率)
    • 每秒处理的请求数,即 QPS/RPS。
    • 衡量服务的负载和流量大小。
    • 示例:rate(http_requests_total[5m])
  • E - Errors(错误率)
    • 失败请求的比例,即错误率。
    • 衡量服务的健康度和质量。
    • 示例:rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m])
  • D - Duration(延迟)
    • 请求处理的耗时分布。
    • 衡量服务的性能和用户体验。
    • 通常关注百分位(P50、P95、P99)而非平均值。
    • 示例:histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))

USE 方法(面向资源)

  • USE 方法由 Brendan Gregg 提出,主要适用于资源/系统层面的监控。
  • U - Utilization(利用率)
    • 资源繁忙的时间比例,如 CPU 使用率、磁盘使用率。
    • 衡量资源被使用了多少。
    • 高利用率通常是性能瓶颈的前兆。
  • S - Saturation(饱和度)
    • 资源排队/过载的程度,如 CPU 平均负载、磁盘队列长度。
    • 衡量资源有多"满",超出容量的部分需要排队。
    • 利用率达到 100% 之前,饱和度可能已经开始上升。
  • E - Errors(错误数)
    • 资源发生错误的事件计数,如网卡丢包、磁盘 IO 错误。
    • 衡量资源的健康状况。
RED vs USE 适用场景:
服务层(应用、API、微服务) → RED 方法
资源层(CPU、内存、磁盘、网络) → USE 方法

监控体系应该自上而下:
用户体验 → 服务指标(RED) → 资源指标(USE)

Google SRE 四大黄金信号(Four Golden Signals)

  • Google SRE 书中提出的监控四大黄金信号,与 RED 类似但更完整:
    1. 延迟(Latency):处理请求的时间。
    2. 流量(Traffic):系统承受的负载。
    3. 错误(Errors):失败的请求率。
    4. 饱和度(Saturation):服务离满负荷还有多远。

指标设计最佳实践

  • 自上而下设计:先业务指标,再应用指标,最后基础设施指标。
  • 关注用户视角:从用户体验出发设计指标,而不是从系统内部视角。
  • 百分位而非平均值:平均值会掩盖长尾问题,P95/P99 更能反映真实用户体验。
  • 标签维度:合理设计标签维度(服务、环境、实例、接口等),便于聚合和下钻。
  • 避免指标爆炸:不要采集无意义的指标,控制高基维度标签的使用。

追问延伸

  • 为什么 P99 比平均值更重要?举个实际场景说明。
  • RED 方法和四大黄金信号有什么异同?
  • 业务指标(如订单量、用户数)应该怎么监控?
  • 什么是高基维度(High Cardinality)?为什么会导致指标爆炸?

Q4: 日志系统怎么设计?ELK/EFK栈 「🟡 中级」

考察点:考察日志体系设计能力,筛掉只会 grep 本地日志、对集中式日志架构没有概念的人。

参考答案

  • 集中式日志系统是可观测性的基础组成部分,用于收集、存储、检索和分析分布式系统中各节点的日志。

ELK/EFK 技术栈

  • ELK:Elasticsearch + Logstash + Kibana
  • EFK:Elasticsearch + Fluentd + Kibana(Fluentd 替代 Logstash,更轻量)

各组件职责

  1. Elasticsearch

    • 分布式搜索引擎,用于日志的存储和检索。
    • 基于 Lucene,支持全文搜索、聚合分析、倒排索引。
    • 水平扩展能力强,通过分片(Shard)和副本(Replica)实现高可用。
    • 索引管理:按日期滚动索引(如 logs-2024.01.01),便于生命周期管理。
  2. Logstash

    • 数据收集和处理管道,负责日志的采集、过滤、转换和输出。
    • 三阶段 Pipeline:Input → Filter → Output。
    • 插件丰富,支持多种输入源(file、beats、kafka)和输出(es、s3、stdout)。
    • 缺点:Java 编写,资源消耗较大,性能一般。
  3. Fluentd

    • 另一个日志收集器,CNCF 毕业项目。
    • C/Ruby 编写,更轻量,内存占用低。
    • 插件生态丰富,支持多种输入输出。
    • 统一 JSON 格式,结构化日志友好。
    • K8s 环境下更常用(Fluent Bit 更轻量)。
  4. Kibana

    • Elasticsearch 的可视化界面。
    • 功能:日志搜索查询、仪表盘、可视化图表、Dev Tools、告警。
    • Discover 页面用于日志检索和分析。
  5. Filebeat / Fluent Bit(轻量采集端)

    • 部署在每台机器上的轻量日志采集 Agent。
    • 负责收集本地日志文件,发送到 Logstash/Fluentd 或直接到 Elasticsearch。
    • 资源占用极低,适合大规模部署。

日志系统架构

应用节点1 ──Filebeat──┐
应用节点2 ──Filebeat──┼──► Kafka/RabbitMQ ──► Logstash/Fluentd ──► Elasticsearch ──► Kibana
应用节点3 ──Filebeat──┘     (缓冲队列)       (处理转换)         (存储检索)       (可视化)

日志设计最佳实践

  • 结构化日志:使用 JSON 格式输出日志,而不是纯文本,便于检索和分析。
  • 日志级别:合理使用 DEBUG/INFO/WARN/ERROR/FATAL 级别,生产环境默认 INFO。
  • 关键信息齐全:每条日志包含 trace_id、user_id、请求路径、耗时、错误码等上下文。
  • 日志轮转:配置合理的日志轮转策略,避免单个日志文件过大。
  • 敏感信息脱敏:日志中不记录密码、密钥、身份证号等敏感数据。
  • 采样策略:高流量场景下对 INFO 级别日志采样,降低存储成本。
  • 索引生命周期管理(ILM):热温冷架构,不同时期的日志存储在不同性能的节点上,过期自动删除。

追问延伸

  • 为什么日志系统中间要加 Kafka?直接写 Elasticsearch 不行吗?(削峰填谷、解耦、缓冲)
  • ELK 栈性能瓶颈通常在哪?怎么优化?(Elasticsearch 分片设计、mapping 优化、硬件)
  • 什么是日志采样?怎么实现不失真的采样?
  • 除了 ELK,还有哪些日志方案?(Loki + Grafana、Splunk、ClickHouse + 日志)

Q5: 什么是链路追踪?Jaeger/Zipkin的原理? 「🔴 高级」

考察点:考察分布式追踪的原理和实践经验,筛掉对链路追踪只有概念、不懂原理和落地的人。

参考答案

  • 链路追踪(Distributed Tracing) 是一种用于分析和监控分布式系统的技术,通过追踪单个请求在多个服务间的完整调用路径,帮助开发者理解系统行为、定位性能瓶颈和故障。

核心概念

  • Trace:一次完整的请求链路,从入口到结束的整个过程。一个 Trace 由多个 Span 组成,用 TraceID 唯一标识。
  • Span:Trace 中的一个操作单元,代表一次具体的调用(如一次 HTTP 请求、一次数据库查询)。每个 Span 有 SpanID,包含开始时间、结束时间、操作名称、标签等信息。
  • Span 关系:父子关系(Parent-Child)、兄弟关系(Follows From),构成调用树。
  • Annotation/Event:Span 中的关键事件标记,如请求开始、响应返回。
  • Baggage:跨服务传递的键值对,用于在整个链路上传递业务上下文。

工作原理

  1. 埋点(Instrumentation):在应用代码中集成追踪 SDK,在请求入口生成 TraceID 和 Span,在调用下游时通过 HTTP Header 或消息队列传递 Trace 上下文。
  2. 上下文传播(Context Propagation):通过 HTTP Header(如 traceparent)或消息属性将 TraceID、SpanID 传递给下游服务,下游服务继续创建子 Span。
  3. 数据上报:各服务将 Span 数据异步发送到追踪系统的 Collector。
  4. 存储与查询:Collector 接收并处理 Span 数据,存入后端存储,前端提供查询和可视化界面。

Jaeger vs Zipkin

  • Zipkin
    • Twitter 开源,是最早的分布式追踪系统之一。
    • Java 编写,架构相对简单。
    • 支持多种存储(ES、MySQL、Cassandra)。
    • 社区成熟,生态完善,但功能相对基础。
  • Jaeger
    • Uber 开源,CNCF 毕业项目。
    • Go 编写,性能更好,云原生友好。
    • 功能更丰富:依赖图、自适应采样、Service Topology。
    • 支持 OpenTelemetry,UI 更现代。
    • 架构:Agent → Collector → Query → UI / 存储。

OpenTelemetry(OTel)

  • CNCF 项目,统一了追踪、指标、日志的采集标准和 SDK。
  • 由 OpenTracing 和 OpenCensus 合并而来。
  • 提供各语言的统一 SDK,厂商中立,避免厂商锁定。
  • 支持自动埋点(Instrumentation),减少代码侵入。

采样策略

  • 全量采样:采集所有 Trace,数据完整但存储和性能开销大。
  • 概率采样:按一定比例采样(如 1%),平衡数据量和信息量。
  • 尾部采样:根据 Trace 结果决定是否采样(如只保留错误的 Trace),更精准但实现复杂。
  • 自适应采样:根据服务流量动态调整采样率。
链路追踪数据流向:
Service A → Service B → Service C
   ↓            ↓            ↓
  Span A      Span B       Span C
   └────── Trace ──────────┘

       Collector → Storage → UI

追问延伸

  • 链路追踪的埋点方式有哪些?各有什么优缺点?(手动埋点、自动埋点、字节码注入、eBPF)
  • Trace 上下文是怎么跨服务传递的?HTTP Header 里有什么字段?
  • 什么是 W3C Trace Context 标准?
  • 高并发场景下链路追踪会不会影响性能?怎么平衡?

Q6: 如何设计告警体系?有哪些最佳实践? 「🔴 高级」

考察点:考察告警设计能力和运维理念,筛掉只会加告警、不考虑告警质量和运维效率的人。

参考答案

  • 好的告警体系不在于告警数量多,而在于有效、精准、可行动。告警风暴会导致"狼来了"效应,真正重要的告警被淹没。

告警分级体系

  • P0(紧急 / Critical)
    • 核心业务完全不可用或严重受损,需要立即响应和处理。
    • 例:核心服务大面积 5xx、数据库宕机、支付服务不可用。
    • 响应:立即响应(5 分钟内),24/7 全天候。
    • 通知:电话 + 短信 + 即时消息 + 全部 OnCall 人员。
  • P1(重要 / Warning)
    • 业务部分受损或有潜在风险,需要尽快处理。
    • 例:单实例故障、错误率轻微上升、磁盘使用率超 80%。
    • 响应:工作时间 30 分钟内响应。
    • 通知:即时消息 + 邮件。
  • P2(一般 / Info)
    • 需要关注但不紧急的告警,计划性处理即可。
    • 例:证书一个月后过期、非核心服务重启、日志量突增。
    • 响应:工作日内处理。
    • 通知:工单 / 邮件汇总。

告警设计原则

  1. 行动导向(Actionable)
    • 每条告警都应该对应一个明确的行动方案(Playbook)。
    • 如果收到告警不知道该做什么,说明这条告警不该发。
  2. 用户视角
    • 告警应该反映用户受到的影响,而不是内部技术指标。
    • 优先告警业务影响(错误率上升),其次才是技术指标(CPU 高)。
  3. 可追溯
    • 告警信息包含足够的上下文,能快速定位问题。
    • 关联相关的仪表盘、日志、文档、处理手册。
  4. 避免告警风暴
    • 告警太多等于没有告警。
    • 通过收敛、抑制、聚合减少噪音。

告警降噪手段

  • 分组(Grouping):同一类别的告警合并为一条通知。Alertmanager 的 group_by。
  • 抑制(Inhibition):高级别告警触发时,抑制低级别相关告警。如服务宕机时抑制所有该服务的指标告警。
  • 静默(Silence):计划内维护时主动静默告警。
  • 延迟告警:抖动性指标设置持续时间阈值(如 CPU 持续 5 分钟高于 90% 才告警)。
  • 告警收敛:相同告警重复出现时合并通知,而不是每次都发。

OnCall 轮值机制

  • 建立轮值表,明确每个时段的值班人员。
  • 主备 OnCall 机制,主值班人未响应时自动升级到备班。
  • 定期轮换,避免疲劳。
  • 事后复盘,优化告警质量。

最佳实践

  • 告警即代码:告警规则代码化管理,版本控制,代码评审。
  • 定期告警审计:定期清理无效告警,优化告警阈值。
  • 告警复盘:每次告警后回顾是否必要、阈值是否合理、响应是否及时。
  • 告警 → 故障 → 改进:告警触发的故障要有根因分析和改进措施。
  • SLO 驱动告警:基于错误预算消耗速率来告警,而不是基于静态阈值。
高质量告警的特征:
  少 ─── 只有真正需要人介入的才告警
  准 ─── 不误报、不漏报
  明 ─── 有明确的处理步骤和上下文
  快 ─── 及时发现,及时通知

追问延伸

  • 什么是告警疲劳?怎么解决?
  • 你怎么确定告警的阈值?拍脑袋定的还是有依据?
  • 基于 SLO 的告警和基于阈值的告警有什么区别?
  • 告警的 OnCall 排班有什么讲究?如何保证公平和效率?

Q7: 什么是SLO/SLI/SLA?怎么制定? 「🔴 高级」

考察点:考察 SRE 服务质量理念和方法论,筛掉对服务质量管理没有体系化认知的人。

参考答案

  • SLI、SLO、SLA 是 SRE(站点可靠性工程)中用于定义和衡量服务质量的核心概念。

核心概念

  1. SLI(Service Level Indicator,服务等级指标)

    • 衡量服务水平的量化指标,是一个具体的数值。
    • 是服务表现的直接度量。
    • 示例:请求成功率、P99 延迟、系统可用性。
    • 公式:SLI = 成功事件数 / 总事件数。
    • 好的 SLI 应该从用户视角出发,直接反映用户体验。
  2. SLO(Service Level Objective,服务等级目标)

    • 服务在一定时间内需要达到的目标值。
    • 是内部目标,用于指导团队的工作优先级。
    • 示例:月度可用性 99.9%、P99 延迟 < 200ms。
    • SLO 应该是可达成的、有意义的,不宜定得过高或过低。
  3. SLA(Service Level Agreement,服务等级协议)

    • 与客户签订的正式协议,包含未达成时的赔偿条款。
    • 是商业承诺,有法律约束力。
    • 通常 SLA 比 SLO 更宽松(SLO 是内部目标,SLA 是对外承诺)。
    • 示例:可用性低于 99.5% 赔偿当月服务费的 10%。
三者关系:
SLI(是什么) → SLO(目标是多少) → SLA(没达到会怎样)
  度量指标         内部目标            对外协议

通常:SLO > SLA(内部目标高于对外承诺,留出缓冲)

错误预算(Error Budget)

  • 错误预算 = 1 - SLO 目标。
  • 例如 SLO 是 99.9%,则错误预算是 0.1%。
  • 错误预算是团队在 SLO 周期内可以"消耗"的不可靠性总量。
  • 用途
    • 平衡可靠性和发布速度:错误预算充足时可以大胆发布新功能。
    • 错误预算耗尽时,停止新功能发布,专注于可靠性改进。
    • 是可靠性决策的量化依据。

制定 SLO 的方法

  1. 从用户视角出发
    • 用户关心什么?可用性、延迟、数据正确性、功能完整性。
    • 不要从内部技术指标出发,要从用户体验出发。
  2. 定义 SLI
    • 选择能直接反映用户体验的指标。
    • 明确"成功"和"失败"的定义。
    • 确保 SLI 可测量、数据可获取。
  3. 设定合理的目标
    • 参考历史数据,了解当前服务水平。
    • 考虑业务影响和用户期望。
    • 不同的服务可以有不同的 SLO。
    • 起步阶段可以先从当前水平开始,逐步提高。
  4. 选择时间窗口
    • 滚动窗口(如 28 天滚动)vs 日历窗口(自然月)。
    • 滚动窗口更平滑,日历窗口更易理解。
  5. 落地和迭代
    • 可视化展示 SLO 达成情况和错误预算消耗。
    • 定期回顾和调整 SLO。

最佳实践

  • SLO 不宜过多,每个服务 2-3 个核心 SLO 即可。
  • SLO 是团队共同的目标,开发和运维共同对 SLO 负责。
  • SLO 驱动的告警:错误预算消耗速率告警比静态阈值告警更有意义。
  • SLO 不是一成不变的,需要根据业务发展持续调整。

追问延伸

  • 错误预算耗尽了怎么办?团队应该怎么做?
  • 什么是基于错误预算的告警?和传统阈值告警比有什么优势?
  • 内部服务需要 SLO 吗?怎么给内部服务定 SLO?
  • SLO 和 KPI 有什么区别和联系?

Q8: 什么是混沌工程?为什么需要混沌工程? 「⭐ 专家」

考察点:考察韧性工程和高级运维理念,筛掉对可靠性工程只有被动响应、缺乏主动验证思路的人。

参考答案

  • 混沌工程(Chaos Engineering) 是一种通过主动注入故障来验证系统韧性的学科,通过在生产环境或类生产环境中有意识地注入故障,来检验系统是否具备预期的容错和自愈能力。
  • 混沌工程的核心思想:主动发现弱点,而不是被动等待故障发生

为什么需要混沌工程

  • 分布式系统越来越复杂,故障模式多样且不可预测。
  • 传统的测试(单元测试、集成测试)只能验证预期内的场景,无法覆盖所有故障模式。
  • "我们的系统有高可用设计" → 这个假设是否成立?需要验证。
  • 混沌工程就是用来验证系统的可靠性假设,提前发现隐患,降低真实故障的影响。

混沌工程原则(Netflix 提出)

  1. 建立稳态假说(Define Steady State)
    • 定义系统"正常"状态的指标(如错误率、延迟、QPS)。
    • 假设注入故障后系统仍能保持稳态(或快速恢复)。
  2. 多样化真实世界事件(Vary Real-world Events)
    • 注入反映真实世界的故障类型。
    • 优先选择影响大、发生概率高的故障。
  3. 在生产环境运行(Run Experiments in Production)
    • 最理想的是在生产环境做实验,结果最真实。
    • 可以从测试环境/预发环境开始,逐步推进到生产。
  4. 自动化持续运行(Automate Experiments to Run Continuously)
    • 手动实验只是一次性的,自动化才能持续验证。
    • 集成到 CI/CD 流水线中,持续验证系统韧性。
  5. 最小化爆炸半径(Minimize Blast Radius)
    • 控制实验的影响范围,从小范围开始,逐步扩大。
    • 有完善的中止机制,发现问题立即停止实验。

常见故障注入类型

  • 基础设施故障:服务器宕机、可用区故障、网络分区、磁盘故障。
  • 网络故障:网络延迟、丢包、带宽限制、DNS 故障。
  • 应用故障:服务实例宕机、依赖服务不可用、内存泄漏、CPU 满载。
  • 数据故障:数据库延迟、磁盘 IO 异常、数据损坏。
  • 资源耗尽:内存耗尽、文件描述符耗尽、线程池耗尽。

常见工具

  • Chaos Mesh:CNCF 项目,K8s 原生混沌工程平台,支持多种故障注入。
  • Litmus:CNCF 项目,云原生混沌工程框架。
  • Chaos Monkey:Netflix 出品,混沌工程鼻祖,随机终止生产实例。
  • Gremlin:商业混沌工程平台。
  • ChaosBlade:阿里巴巴开源,混沌工程工具。

实施步骤

  1. 规划阶段:确定实验目标、选择故障类型、定义稳态指标、设定爆炸半径。
  2. 准备阶段:准备环境、部署监控、制定回滚方案。
  3. 执行阶段:注入故障、观察系统行为、记录实验数据。
  4. 分析阶段:对比稳态假设,分析系统表现,发现弱点。
  5. 改进阶段:修复发现的问题,优化系统韧性,重复实验验证。
混沌工程 vs 故障演练 vs 测试:
测试      → 验证功能是否正确(预期内的验证)
故障演练   → 验证应急流程是否有效(计划性故障)
混沌工程   → 主动探索系统弱点(发现未知问题)

成熟度模型

  • Level 1:手动做实验,在测试环境进行。
  • Level 2:自动化实验,有稳态验证,最小化爆炸半径。
  • Level 3:持续运行在生产环境,有完善的安全机制。
  • Level 4:混沌工程融入研发流程,驱动架构改进。

追问延伸

  • 混沌工程和 GameDay(故障演练)有什么区别?
  • 在生产环境做混沌工程安全吗?怎么控制风险?
  • 你们系统如果做混沌工程,你会优先注入什么故障?
  • 混沌工程的结果怎么衡量?怎么证明混沌工程的价值?