一分钟精华速览
混沌工程是在分布式系统上进行实验,在整个系统中随机位置通过工具引发故障,从而提高系统健壮性以及人员的响应效率,建立对系统抵御生产环境中失控条件的能力以及信心的手段。虽然混沌工程已经发展了十余年,但对大部分公司和研发团队,它仍是一个比较陌生的领域。本文总结了去哪儿 2019 年至今,从零开始建设混沌工程平台的 4 个阶段,以及各阶段的落地成果,整体建设思路和落地路线极具参考性。
作者介绍
去哪儿网高级技术总监 - 朱仕智TakinTalks 社区特聘专家,2013 年加入去哪儿网,负责过公共业务、国际机票、基础架构等团队,擅长高并发高可用高性能的系统设计和落地,多年的技术管理经验。目前负责基础架构部门,包含基础平台、中间件架构、大前端、质量保障等团队,近期专注公司整体技术演进和云原生、数字化技术落地。
温馨提醒:本文约 5000 字,预计花费 8 分钟阅读。
TakinTalks 公众号后台回复 “交流” 进入读者交流群;回复“1151”获取讲师课件;
回复“混沌”获取《混沌工程实践指南》。
背景
在我接手去哪儿基础架构团队之后,每次看到系统故障的新闻,比如之前 Facebook 服务器宕机、B 站去年的“713 故障”(传送门:B站SRE负责人亲述713事故后的多活容灾建设),会非常感同身受,因为在去哪儿也陆续出现过一些比较严重的故障。
2019 年去哪儿在 ZK 上出现了多次比较严重的故障,因为我们的基础设施里所有内网的 Java 服务之间的通信,主要采用 dubbo 的分布式服务框架,它重度依赖 ZK 组件,故障频发影响可想而知,最严重的一次故障让整个公司的业务几乎停摆了 2 个小时。面对这些大范围的严重故障,经过调研评估后,我们决定在内部推行混沌工程来解决。
经过 3 年的实践,我们的混沌工程也取得了很好的效果,这里也和大家分享一下去哪儿混沌工程平台从无到有、从 0 到 1 的建设实践。
一、为什么建议做混沌工程?
1.1 混沌工程的价值
混沌工程作为软件测试和质量保证的一种方法,非常适合现代分布式系统和流程,在抵御失控、避免不确定上,它是非常不错的技术手段。在去哪儿的实践中,我总结混沌工程的价值主要有以下三个方面:
1.2 混沌工程落地效果
混沌工程在去哪儿落地后,确实给我们带来了不错的成效。比如,在 2019 年我们有大量的中间件如 ZK、MQ 之类的质量和稳定性是比较糟糕的,经过了混沌工程一系列的保障措施之后,在过去的近三年里,我们再没有产生过任何由于中间件可靠性导致的故障了,这对我们来说是非常大的进步。另外,现阶段很多问题的定位时间,已经从几十分钟降为 3-5 分钟的水平,排查定位问题的速度也有了质的飞跃。
二、落地前需要做哪些思考和盘点?
2.1 两个值得思考的问题
如果你也恰好计划在企业内部落地混沌工程,有两个非常重要的问题我认为是值得思考的。
1、混沌工程的最佳实践是随机攻防演练吗?
2、混沌工程的落地价值如何确保?
我看到过很多同学想去实践混沌工程,更多是因为它是云原生的配套,或者因为它是一个非常新的技术。但是,当我们在企业里去落地一项技术,我们其实需要思考它真正的价值,确保它产出的价值能够大于投入,而且要能充分地展示这个价值。如果只是去建立一个混沌工程平台,是没办法确保能获得价值的。所以,如果这两个问题没有得到很好的答案,我觉得不应该大规模地进行混沌工程的实践。
2.2 盘点常见故障原因
思考和盘点常见的故障原因大概都有哪些,才能够针对性地提供比较有效的定向演练,结合去哪儿的经验,我大概把常见的故障分成了五类——机房问题、中间件问题、机器问题、应用问题、依赖问题。
我们可以从应用架构的层次来看的这五类问题,从上往下看,它出问题的概率越来越小,但是影响却正好相反,是越来越大的。比如,机房层网络挂掉或者大规模的机器实体机被中断,这些情况出现的概率很小,但只要出现一个就意味着是非常大规模的影响,而且它恢复时长相对会比较长。我们之所以要去看这样的结构和层次,其实它跟我们的混沌工程实践路线是有关系的。刚开始做混沌工程是要考虑性价比的,即先去解决我们认为最重要的事情。
对去哪儿来说,特别是在前面提到的 2019 年的那种情况下,我们是优先做了机房层和中间件层,因为我们当时的中间件和基础设施出问题的概率较高。所以这里也就是引出来一个点——我们混沌工程的实践路线到底应该怎么去弄。
2.3 混沌工程实践线路
去哪儿的混沌工程从 2019 年 11 月开始,到 2022 年 9 月我们一直持续在做,但每个阶段在做的点和层次是不一样的,针对不同的实践对象,我们做了不同时长的落地,整个时间轴和关键节点大概如下图:
2019.11-2020.1 基础设施演练:比如上面提到的机房、中间件。这种基础设施的演练,适合稳定性保障非常弱的时期,在这里出的问题影响面往往比较大,所以做基础设施演练的收益就会比较明显。
2020.2-2020.3 应用演练:这个阶段实践的主要对象是应用的各类进程问题。当大规模的故障已经得到了基本保障,但是应用状态频出,此时就可以考虑落地应用演练了。
2021.2-2022.9 依赖演练:主要针对系统所有的外部依赖,如 HTTP 接口或者 RPC 接口等,即使应用本身没有问题,但是依赖的资源出现问题时系统也会被拖垮。此时,就需要做服务治理的问题预防。当然,如果服务治理从来没出现过任何问题,这个可能价值就不会那么大。
2022.3-2022.4 攻防演练:前面的演练都是针对系统的,攻防演练的对象主要是开发、质量保障或者 SRE 等人员。当混沌工程的系列工具和机制已经相对完善,但是人员在应急情况下的处理能力还是不足的时候就可以做攻防演练了。以上是去哪儿实践落地的路线,也非常推荐大家按照这种路线来做,从性价比由高往低的方式去推进。
三、各阶段的目标和效果有哪些?
3.1 阶段一:基础设施演练
3.1.1 建设目标和关键点
在做基础设施演练之前,我们需要先分析目标,才能提取出它对应的关键点。
去哪儿在这块的能力建设目标,是同一个机房某个业务线里面所有的服务节点全部都失效掉的时候,应用也能不受影响。对应这个目标,我们也有几个关键点是需要特别注意的。机房聚合信息查询,方便应用改造我们 CMDB 里面的信息要尽可能地全,而且是能够比较方便地检索出来,这样方便应用做前置改造。即开始制定演练计划时,已经知道机房里部署的应用有哪些不符合容灾特征,就可以提前通知这些应用的负责人进行改造了。自动建立沟通群,进度周知演练是一个非常大规模、横跨多部门和团队、跨长周期的事情,所以需要有效的沟通机制。在去哪儿网,我们依托内部的 IM 把整个流程串起来,在开始规划时就会有专门的沟通群,真正开始执行也会有对应的进度周知,有预警时也会在群里周知恢复等等,这样能够保证信息的共享是足够实时和全面的。真实关机拔电测试、网络断掉等等都能演练,但是恢复起来相对较快,为了尽可能模拟真实复杂的关机场景,我们选择了对数千个节点做真实关机,这样可以针对里面的场景去做提效类的工作。只有真实关机,才能验证恢复时长是不是真的能够达到要求。接入告警,告警事件关联推送如果公司里面已经有告警体系,那么需要和演练的事件绑定和关联起来,确保告警信息能及时送达。
3.1.2 技术实现
整体来说,这部分的技术要求不高。比如,去哪儿当时是 openstack 虚拟机和容器并存的状态,当时就主要面向虚拟机,我们的演练测试只需对接 openstack API ;其他我们只需要针对批量运维的工具,类似 saltstack 这种方式,就可以满足技术要求了。
这里特别说一下自研控制面,它非常关键,从制定演练计划开始,到编排和触发演练等等,都需要依托这个控制面去把它抽象好,包含其他各种目的和形态的演练,都是依托它来进行的,所以它其实是一个复杂的控制平台。所以在最开始设计的时候就要考虑好,它可能不是简单只针对基础设施演练的平台,它需要适应各种演练策略和演练场景,还需要能相当灵活地控制,需要足够方便地去筛选出要演练的目标,这样就能快速针对大批的应用、机器去进行真实关机的演练和恢复状态的观察,然后以及后续的问题分析和跟进。
3.1.3 演练效果
我们在机房演练了几十次,涉及到了几千个机器,大几百个应用,每次大概能够发现十几个问题——从日常设计来说,我们觉得它是不应该出现的。但当我们真正去做这种机房级别的演练时,仍会发现不少会影响业务的问题,甚至会影响我们主流程的业务。
3.2 阶段二:应用演练
3.2.1 建设目标和关键点
前面说到,我们应用演练的能力建设目标,是对所有应用可以选择多种策略进行故障注入。这里我认为也有 4 个关键点需要关注。线上环境应用资源会强依赖于环境状态,如果是在测试环境中去做应用演练,会发现演练出来的结论不一定可靠,测试环境中很多配置不能保证百分百和线上一致。可靠的注入工具在线上环境做演练就要求注入故障的工具要非常可靠,去哪儿当时选择了开源的 chaosblade 。(回复“混沌”,获取混沌工程工具总结对比表)丰富的演练策略演练策略需要能涵盖公司历史上出现过的 90% 以上的故障场景,通过这个方式至少能把应用层的问题模拟出来,这就要求有非常丰富的策略才能够满足。生效面可控在注入故障的工具上需要做一定的控制,比如,要注入的应用实例的规模、应用上下线等等。
3.2.2 应用演练流程
当我们要真正对线上的应用的进程变更时,我们需要把 agent 装载进去,再把故障策略注入进去,这两个过程中去哪儿之前也碰到了一些问题,比如,当 agent 注入时,会有瞬时 CPU 升高的问题,我们是通过把应用的实例先下线,流量先不进入这个实例,等 agent 注入完成且恢复后,再把它重新挂载上去,这个点可能会在大家实践中面临到,以上处理方式可以供参考。
3.2.3 应用演练效果
下图是演练计划的效果界面图,能够看到我们可以按照应用去演练,人工或者定时地去触发,在线上环境里选择不同的场景、不同的演练策略、不同的应用等等。目前在去哪儿有 31 种的故障场景支持,已经满足了公司内至少 95% 的诉求了。
3.3 阶段三:依赖演练
3.3.1 建设目标和关键点
依赖的演练不同于前面两种形式的演练,它更多是服务于服务治理,很多的服务之间都需要协同通信才能完成功能,但是这些通信的配置,比如超时、熔断或者是应用本身的代码的编写,都会造成原本期望它是一个弱依赖,但实际上代码写出来和配置出来,它就变成了一个强依赖。通过这个依赖的演练,我们就可以提前发现哪些是不符合预期的,就可以提前把它修复掉。应用元数据采集故障注入时需要有元信息,比如 A- 应用要调 B 应用什么接口,我们不可能依靠人工去输入,不仅人工成本高,对人的要求也高,所以我们需要有非常完善的元数据的采集,并且形成比较有效的拓扑结构能够方便我们去制定计划。
可视化的应用拓扑结构收集应用元数据能够形成一个比较有效的可视化的应用拓扑结构,就可以对拓扑结构进行依赖级别的演练,在大规模演练中,我们基本上都是从核心链路的入口开始,全链路拓扑结构大范围覆盖的方式来进行的。区分不同场景的同一个依赖这是上面提到的 chaosblade 中企业场景的功能。强弱关系依赖标注这部分刚开始时需要人工进行标注,才能知道这个依赖断言出来后,强弱到底合不合理。
(去哪儿标记对象效果页面)
3.3.2 依赖演练效果
我们大概进行了 1200 多次的演练,涉及到了 3000 多个依赖。去年五一之前,我们对机票酒店业务的主流程进行全面覆盖演练时,共计发现了 136 个问题。
3.4 阶段四:攻防演练
3.4.1 建设目标和关键点
攻防演练是大家日常经常看到的,就是线上的随机性攻防对抗演练。需要强调的是,攻防演练并不是混沌工程中达成稳定性保障目标的有效手段,它服务于人工排查和处理速度的提升。线上环境的故障排查受限于各种因素,比如,处理人员相对分散、处理类似故障的频率不高导致经验难积累、故障原因种类繁多等等,都会导致当线上出现问题时,排查处理速度较慢,攻防演练就是为了帮助团队提前积累经验,提高排查速度。
培养混沌文化我们需要让公司大部分开发人员认同混沌工程的价值,开发人员必须要认同它的价值,才能比较好地去开展攻防演练,所以内部文化的建立很重要。时间和策略真随机如果只是提前预告,告诉大家某个时候要演练,这样会对处理人做预判和处理都有影响,此时得到的处理速度和效率数据就不可信,所以时间和注入的策略一定要真随机。信息干扰各类组件都有对应的异常栈,以及我们是用测试流量或者是压测流量来做触发流量它带有的流量标识,这些信息都会在开发定位时有提示,变相加快了处理速度。所以这些信息需要抹除掉,还原到跟线上一样的信息,才能真正测试响应速度。
3.4.2 攻防对抗演练流程
整个攻防对抗中,我认为有两个要点,第一个是编排流程比之前的单个点演练更复杂;第二个是需要依赖内部的其他基础设施,比如攻击点的规划就必须得参考历史故障,就要求要有故障的汇总平台等。
(去哪儿攻防演练故障注入过程演示)
3.4.3 攻防演练效果
在今年 4 月份集中的两次测试可以看出,我们的整体定位速度大部分都是在 3 分钟左右,相比之前的需要几十分钟,故障排查耗时已经降低了很多。
3.5 混沌工程平台架构
通过这些场景落地之后,目前去哪儿混沌工程的平台的系统结构大概是这样的。其中最核心的是中间的演练系统,整个平台它本身是一个组合性、综合性的功能平台,很多事情并不是自己在这个平台内部去做的,而是使用了其他平台的能力。
1、混沌工程对小企业是否有必要?
2、混沌工程 4 个阶段的人员投入如何?
3、对于左移的做法,老师觉得意义大吗?
关于本文的更多疑问,欢迎公众号后台回复“1105”获取答案
四、总结
针对以上的分享,我总结概括为以下三个核心观点。
1、实践路线要合理:整个混沌工程的实践落地路线需要结合公司情况和诉求进行设计,千万不要人云亦云,性价比高收益高的场景先支持。
2、演练成本很关键:大规模、常态化演练才能获得长期有效的稳定性保障。演练成本是确保混沌工程落地价值的关键。
3、攻防演练为提速:混沌工程的尽头是随机攻防演练,但并不是性价比最高的。攻防演练的目的是加上排查速度,而不是发现问题。
了解更多去哪儿网混沌工程实践细节,欢迎扫码进入「读者交流群」,和老师实时互动。
回复【1151】获取讲师课件回复【交流】进入读者交流群更多内容欢迎进入「TakinTalks 稳定性社区」,观看完整版视频内容。
声明:本文由公众号「TakinTalks 稳定性社区」联合社区专家共同原创撰写,如需转载,请后台回复“转载”获得授权。