第四章:实验环境搭建

环境搭建这事儿,说实话,是混沌工程里最容易被低估的一环。我见过太多团队,兴致勃勃地写好了故障注入脚本,结果在错误的环境上一跑,要么把线上搞崩了,要么得出的结论毫无参考价值。今天咱们就聊聊,怎么把实验环境这摊子事儿整明白。

生产环境 vs 预发环境

先问个问题:你会在生产环境直接做混沌实验吗?

我的答案是:分情况。但绝大多数时候,先在预发环境验证,再考虑生产环境

生产环境和预发环境,说白了就是「真刀真枪」和「模拟演习」的区别。我曾在某券商做项目,预发环境配了4台机器,生产环境是32台。你以为只是数量差异?错了,流量模型、数据分布、网络延迟,全都不一样。

核心差异对照表:
维度 生产环境 预发环境
流量规模 真实用户流量,峰值可达数万QPS 模拟流量,通常为生产的1%~10%
数据敏感度 包含真实用户隐私数据 脱敏数据或模拟数据
故障容忍度 极低,任何异常都可能影响收入 较高,允许出现短暂不可用
监控完备度 全链路监控,告警完善 基础监控,告警可能不完整
变更频率 受控,需审批 相对自由,可频繁调整

我个人习惯是:预发环境做「功能验证」,生产环境做「韧性验证」。什么意思呢?

  • 预发环境:验证故障注入工具是否正常工作,监控是否捕获到异常,告警是否触发。说白了,先确保实验本身没问题。
  • 生产环境:验证系统在真实流量下的容错能力。这才是混沌工程的真正战场。
注意: 生产环境的混沌实验,必须设置「熔断机制」。我曾经见过一个团队,在生产环境注入网络延迟,结果熔断阈值设得太高,导致整个集群雪崩。嗯,那天的复盘会开了整整四个小时。

流量复制与隔离

做混沌实验,最怕什么?怕把真实用户搞崩了。所以流量复制和隔离,是保命的手段。

流量复制,简单说就是把生产环境的真实请求「拷贝」一份,打到预发环境或者实验集群里。这样你就能在接近真实的流量下做实验,又不影响线上用户。

常用的工具有哪些?

  • GoReplay:轻量级,支持HTTP流量录制和回放。我常用它来做预发环境的压力测试。
  • TCPCopy:更底层,支持TCP流量复制。适合需要精确模拟网络环境的场景。
  • 自研流量复制中间件:大厂常用,比如基于Netty的流量复制组件,可以按需过滤和修改请求。

这里分享一个我踩过的坑:流量复制时,别忘了处理「写请求」。读请求复制过去没问题,但写请求如果直接打到预发环境,可能会污染数据。我的做法是:在预发环境做一层「写请求拦截」,把写入操作重定向到独立的测试数据库。

小技巧: 流量复制时,可以给请求打上「影子标签」。这样在预发环境里,所有影子请求都能被识别出来,方便后续分析和排查。

隔离方面,我建议采用多级隔离策略

  1. 网络隔离:实验集群和生产集群使用不同的VPC或子网。
  2. 数据隔离:实验数据使用独立的数据库实例,或者使用数据脱敏后的副本。
  3. 资源隔离:通过容器化(如Kubernetes)实现资源限制,防止实验影响其他服务。

监控与可观测性工具

做混沌实验,没有监控就像闭着眼睛开车。你根本不知道故障注入后系统发生了什么。所以,可观测性是混沌工程的基石

我常用的三件套:Prometheus + Grafana + Jaeger。咱们一个一个说。

Prometheus:指标采集

Prometheus 负责采集各种指标数据,比如CPU使用率、内存占用、请求延迟、错误率等。它的核心是「拉模型」——每隔一段时间去目标服务拉取一次数据。

在混沌实验中,我特别关注这几个指标:

  • P99延迟:故障注入后,P99延迟是否飙升?如果从10ms涨到1000ms,说明系统扛不住了。
  • 错误率:5xx错误是否增加?这是最直接的故障信号。
  • 熔断器状态:服务是否触发了熔断?熔断后是否自动恢复?

配置示例:

# prometheus.yml
scrape_configs:
  - job_name: 'trading-service'
    scrape_interval: 5s
    static_configs:
      - targets: ['localhost:8080']
    metrics_path: '/actuator/prometheus'

Grafana:可视化面板

光有指标数据还不够,你得能直观地看到变化。Grafana 就是干这个的。

我习惯为每个混沌实验创建独立的 Dashboard,包含:

  • 实时流量曲线(QPS)
  • 延迟分布图(P50、P90、P99)
  • 错误率趋势
  • 资源使用情况(CPU、内存、网络)
  • 实验状态标记(注入开始、注入结束)

这样一眼就能看出,故障注入后哪些指标发生了变化。

Jaeger:分布式追踪

指标告诉你「系统出问题了」,但 Jaeger 能告诉你「问题出在哪里」。它通过追踪每个请求的完整调用链,帮你定位故障点。

在交易系统中,一个下单请求可能经过网关、风控、订单中心、清算中心等多个服务。如果某个环节出了问题,Jaeger 能清晰地展示出来。

我曾经遇到过一个案例:注入网络延迟后,P99延迟从50ms涨到了500ms。但通过 Jaeger 追踪发现,延迟主要卡在「风控服务」的数据库查询上。原来风控服务用了同步查询,网络延迟导致连接池被占满。嗯,这就是典型的「故障放大效应」。

我的建议: 在混沌实验前,先通过 Jaeger 建立「基线追踪」。这样实验后对比追踪数据,能更快定位异常点。

知识体系结构图

下面这张图,概括了本章的核心逻辑:

混沌工程实验环境搭建核心逻辑 环境选择 流量复制与隔离 监控与可观测性 生产环境:韧性验证 预发环境:功能验证 先预发,后生产 GoReplay / TCPCopy 影子标签 + 写请求拦截 网络/数据/资源隔离 Prometheus:指标采集 Grafana:可视化面板 Jaeger:分布式追踪 安全、可控、可复现的混沌实验

这张图想表达的核心思想是:环境选择是基础,流量复制是手段,监控是眼睛。三者缺一不可。

最后说一句: 环境搭建这事儿,别怕麻烦。我见过太多团队,为了省事直接在预发环境做实验,结果预发环境配置和生产差太多,得出的结论完全没用。花时间把环境搭好,后面能省十倍的时间。

公众号:蓝海资料掘金营,微信deep3321