混沌工程及基本原理

概念

Untitled

混沌工程(Chaos Engineering)是通过主动向系统中引入软件或硬件的异常状态(扰动),制造故障场景并根据系统在各种压力下的行为表现确定优化策略的一种系统稳定性保障手段。是在系统上进行实验的学科,目的是建立对系统抵御生产环境中失控条件的能力以及信心。

我们知道发生故障的那一刻不是由你来选择的,而是那一刻来选择你,你能做的就是为之做好准备。所以构建稳定性系统很重要的一环是混沌工程,在可控范围或环境下,通过故障注入,来持续提升系统的稳定性和高可用能力。

混沌工程的必要性

混沌工程有哪些好处?

  • 架构师角度:可以验证系统架构的容错能力,比如验证现在提倡的面向失败设计的系统;
  • 运维角度:在云环境中,混沌工程可以模拟各种网络、硬件或服务故障,帮助开发和运维团队更好地应对这些故障;
  • 开发角度:可以提高故障的应急效率,实现故障告警、定位、恢复的有效和高效性;
  • 产品角度:通过混沌事件查看产品的表现,提升客户使用体验。所以说混沌工程面向的不仅仅是开发、测试,拥有最好的客户体验是每个人的目标。所以实施混沌工程,可以提早发现生产环境上的问题,并且可以以战养战,提升故障应急效率和可以使用体验,逐渐建设高可用的韧性系统;
  • 测试角度:可以弥补传统测试方法留下的空白,之前的测试方法基本上是从用户的角度去做,而混沌工程是从系统的角度进行测试,降低故障复发率。

混沌工程有哪些应用场景?

Untitled

  1. 衡量微服务的容错能力

    通过模拟调用延迟、服务不可用、机器资源满载等,查看发生故障的节点或实例是否被自动隔离、下线,流量调度是否正确,预案是否有效,同时观察系统整体的 QPS 或 RT 是否受影响。在此基础上可以缓慢增加故障节点范围,验证上游服务限流降级、熔断等是否有效。最终故障节点增加到请求服务超时,估算系统容错红线,衡量系统容错能力,或进行强弱依赖治理。

  2. 测试 PaaS 层是否健壮

    通过模拟上层资源负载,验证调度系统的有效性;模拟依赖的分布式存储不可用,验证系统的容错能力;模拟调度节点不可用,测试调度任务是否自动迁移到可用节点;模拟主备节点故障,测试主备切换是否正常。

  3. 验证监控告警的时效性

    通过对系统注入故障,验证监控指标是否准确,监控维度是否完善,告警阈值是否合理,告警是否快速,告警接收人是否正确,通知渠道是否可用等,提升监控告警的准确和时效性。

  4. 定位与解决问题的应急能力演练

    通过故障突袭,随机对系统注入故障,考察相关人员对问题的应急能力,以及问题上报、处理流程是否合理,达到以战养战,锻炼人定位与解决问题的能力。

在当前微服务云原生架构大行其道的环境下,微服务的规模和架构复杂性都增加了软件的不稳定因素,而混沌工程是一种增加系统稳定性,确定系统优化策略的手段;也是一种认知复杂系统的手段。

实践

一般大的互联网公司都会有放火平台,像比较常用的借助阿里的 ChaosBlade 能力搭建混沌工程实验工具,演练可以分为四步:

准备阶段

ChaosBlade、Chaos Agent 安装,可参考 Box 平台快速入门

新建故障、定义故障参数

Untitled

Untitled

故障注入(实验发布)

需要有指标观测到故障注入生效。

期间要注意观察监控报警等是否符合预期,如果在线上或可能影响用户的环境进行实验要时刻注意监控指标数据,避免影响用户。

结束实验,实验报告复盘

通过观测到某些指标,例如某个监控报警、日志出现的关键词、响应的关键词、成功率等指标验证放火发生、服务稳态、止损停止。形成自动化的防火发生到观测到结果收集的过程。

Untitled

基本原理

这里总结 ChaosBlade 基本原理,根据作用目标,主要分为三个方面

  1. 物理机注入 2. k8s 注入 3. 进程注入。

这里举几个例子:

  1. 模拟 CPU 负载

    代码可以看到,对每个 CPU 的逻辑核执行 burn(),核心是通过循环模拟消耗 CPU

    func burn(ctx context.Context, quota <-chan int64, slopePercent float64, percpu bool, cpuIndex int) {
        q := getQuota(ctx, slopePercent, percpu, cpuIndex)
        ds := period - q
        if ds < 0 {
            ds = 0
        }
        s, _ := time.ParseDuration(strconv.FormatInt(ds, 10) + "ns")
        for { // 死循环实现
            startTime := time.Now().UnixNano()
            select {
            case offset := <-quota:
                q = q + offset
                if q < 0 {
                    q = 0
                }
                ds := period - q
                if ds < 0 {
                    ds = 0
                }
                s, _ = time.ParseDuration(strconv.FormatInt(ds, 10) + "ns")
            default:
                for time.Now().UnixNano()-startTime < q { 
                }
                runtime.Gosched()
                time.Sleep(s)
            }
        }
    }
    
  2. 模拟网络延时

    代码利用 tc 命令将 eth0 网卡的传输设置为延迟 XX ms发送。

    tc qdisc add dev eth0 root netem delay XXms

  3. 模拟 Java 类方法调用延迟

    对于 Java 进程层面注入故障,依赖于 JVM Agent Attach 机制,故障注入时会将 jvm-sandbox 动态的挂载(attach)到目标进程 JVM 上,再通过插件生成字节码的形式对目标类进行增强。(所以需要容器中提前安装 Chaos Agent)

    社区提供了大量插件

    社区提供了大量插件

常见问题

Q. 预发布环境可以进行常态化放火演练,那么生产应该进行放火演练吗?

A. 实验环境越真实,混沌工程越有价值,但如果知道系统在某个故障场景下不具备容灾能力,不可以执行此混沌实验,避免资损发生。

  • 对于预发环境,由于没有生产流量,所以用户不会有体感,并且rd自测过程,不会影响生产数据。
  • 对于生产环境进行放火,可能会影响用户体验。特别是对于强依赖的链路如果放火,必然影响真实用户,通常生产环境的弱依赖是可以进行放火演练的(确定是弱依赖,并且具备降级方案)。对于真实生产环境,需要更细粒度的把控,例如特定区域,特定帐号等等,目标是减小影响面(控制爆炸半径)。
  • 一个可用的经验是可以对生产的流量进行染色(例如压测流量通常天生链路带压测标识),对这部分流程进行故障注入,实现不影响线上真实流量。

一些经验

初次去了解混沌工程源于部门业务调整,研发人力完全不足,对于存量系统我们希望能够按照链路的重要程度,把对于弱依赖的维护成本降低,期望只关注核心链路,好钢要用在刀刃上。于是和 QA 同学一起把公司的放火平台和其他部门的使用经验过了一遍。

过去使用放火平台帮助我们系统解决了不少问题,例如验证强弱依赖、超时时间、监控报警的验证等。

强弱依赖验证

主要关注强依赖发生故障是否有报警,弱依赖降级是否产生错误响应。

这一部分的难点在于,对于梳理出来的强弱依赖节点,尽可能一个节点一个节点进行故障注入验证,否则无法区分是哪个节点导致异常。这里能做的是在验证确认节点为弱依赖后,那么它的下游肯定也是弱依赖,则不需要验证弱依赖下游。

例如对于 C 端导购场景我们验证出弱依赖:商品活动标签、券列表、ES 订单列表(可降级)、弹窗文案提示等接口。

超时时间设置评估

依赖超时应该足够长来减少因为超时导致的业务失败率;

依赖超时应该尽量短来避免拖垮核心流程(主要是线程、连接资源有限,容易引发雪崩)。

  1. RPC超时配置多少合适?

结合具体业务场景,超时配置不要太激进,推荐通过监控查看接口调用的p99(也可以p99.9)+ buffer作为超时,buffer可以取p99的20-50%,p99 比较小的可以取 buffer 为 20-30ms。有的接口响应长尾比较大,设置太短会导致有部分请求永远超时。

  1. 是否需要重试?

重试会增加下游压力,谨慎添加。

混沌工程在 Netflix 的演进

混沌工程实践指南

ChaosBlade: Java Dev Guide

Linux 网络故障模拟工具TC

Building resiliency with chaos engineering

ChaosBlade 简述及内部实现逻辑

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

Scroll to Top