QA 工程师刚出现时,大部分工作都需要手动完成。随着自动化概念的出现,QA 工程师的重要性开始下降,美国互联网公司中很大一部分已经不再由 QA 工程师负责。那么,这些公司开始通过什么方式保证系统稳态呢?
在科技圈,很多技术概念的出现都要早于这一名词的诞生,混沌工程也是如此。简单来说,混沌工程旨在建立合成事件以测试弹性工程假设是否成立,虽然这一名词听起来有些陌生,但其实是一种历史悠久的文化,只是最开始并没有将这一系列方法称作混沌工程,而是将其作为“工程”的一部分。
多年来,软件行业一直在利用混沌工程的方法支持单元测试,但随着软件组件变得愈发复杂且依赖性更强,行业开始回归旧有方法并对混沌工程进行重建。在 QCon 全球软件开发大会(上海站)2019 即将召开之际,InfoQ 就这一话题采访了 LinkedIn 的资深 SRE 工程师 Brian Wilcox,听他聊对这一技术的具体想法以及可推荐的实践工具。
混沌工程遵循路径与 QA 并无区别
很多文章都会在开篇先阐述混沌工程的具体概念,对于这样一个新的技术,确实需要在开篇理清边界,这样才方便接下来的讨论。在 Brian Wilcox 看来,混沌工程遵循的路径与 QA 并无区别。在 QA 工程师刚刚出现在软件行业中时,大部分工作只能以手工方式完成。大部分 UI 测试以及“施加破坏以观察其是否中断”的方法都以混沌工程这一概念为基础。随着集成测试、发布 commit/pull 请求验证以及持续集成等自动化概念的出现,QA 工程师的重要性开始下降。在美国,很多互联网公司的 QA 工程师主要工作就是通过模拟与合成流量进行整体验证。
随着工程师们创建的系统越来越复杂,活动部件越来越多,出现的问题也就越多。组织希望建立自动或者手动流程来绕过生产故障,或者从故障状态迅速恢复至稳定状态。这些具体流程被称为弹性工程。弹性工程的核心问题在于纠正效果验证。当然,企业可以选择等待故障自然发生,也可以利用混沌工程等手段主动制造故障事件。后一种方式的优势在于及时性更强、爆炸半径更小,而且由此建立起的弹性信心也足以指导未来可能出现的真实故障事件。
混沌工程让组织能够将弹性从理论层面升级到实践层面。接下来,组织就可以依据这些新的信息采取改进行动,或者借此断定“目前的弹性是否足够大”。如今,大多数考虑采用混沌工程的企业都意识到,混沌工程在本质上与“施加破坏以观察其是否中断”没什么区别,这是个很好的起点。但一定得注意遗留问题以及预期目标:以小规模手动方式为开端,努力引入自动化与验证机制,而后将其直接集成至构建流程中。
那么,组织应该从哪里起步?
混沌工程的引入条件
组织的起步点应该是来看最严重的问题存在于哪里,什么地方出现变化会造成最大影响。——Brian Wilcox
在开发混沌工程实验时,牢记以下原则将有助于实验设计。Brian Wilcox 同样分享了自己对于这几大原则的看法:
建立稳定状态的假设;
多样化现实世界事件;
在生产环境运行实验;
持续自动化运行实验;
最小化“爆炸半径”。
先从稳态问题开始。Brian Wilcox 认为,建立稳定状态的第一步往往始于错误率——即当一切“顺利”推进时,系统会向用户返回多少错误。随着企业走向成熟,大家往往会进一步转向 SLO 或者 SLA。随着 SLO 引入延迟与体积大小等指标,组织也将获得更好的稳定状态指标和手段。到目前为止,Brian Wilcox 认为最好的稳态类型是真实用户监控与 SLO 的组合,这也是组织能够获得的、最接近“真实用户体验”的评估方式。
除此之外,混沌工程将“实验”作为基本单位,如上“在生产环境运行实验”、“持续自动化运行实验”,这有种科学研究的感觉。Brian Wilcox 建议,开发者可以先从假设起步,而后围绕假设设计出实验、尽可能减少其中的变量,以获取一个能够反复验证的可靠结果。对于混沌工程,问题在于开发者几乎很少控制未知变量的数量,而这些变量确实会在实验过程中对系统产生影响。“最小化爆炸半径”正是为了减少对系统的影响,同时得出足够可靠的结果以带来有意义的见解。
不过最重要的是,组织需要思考“需要多少指标才能对影响进行量化?”举例来说,如果我在一家运送包裹的物流公司工作,那么我为整个系统设置的稳定状态可能是包裹在未送达或者送达后发生损坏的机率。但是,如果单纯分析最后一英里的交付过程,那么我就不需要关注区域内损坏或丢失的包裹数量,而只需关注送货人员造成的损坏或丢失数量,并把衡量范围缩小到这一点上。
Brian Wilcox 也会采取这种方法确定该如何使用混沌工程:一切取决于到底想解决什么问题。混沌工程目前在业界很有吸引力,但要想实践,首先得思考如下基本问题:证明系统弹性水平的目标是不是为了吸引客户?是否经常因为生产状态不够稳定而失去客户?是否打算减少运营费用?是否正在努力与现有客户建立信任关系?打算解决的问题究竟是什么?
无论是分段环境还是生产环境,开发者都可以在任意阶段启动弹性工程机制。Brian Wilcox 表示,如果可以利用混沌工程证明系统能够在分段环境中正常运作,那也会对系统在生产环境中的运作状态抱有更强信心。当然,这种信心只存在于理论层面,即在理论上,系统应该能很好地应对生产环境的挑战。根据谷歌 SRE 指南所言:“只要没有经过实际测试,就可以默认其已经发生故障。”在混沌工程的推进中,可以最小化实验爆炸半径,从而避免引发严重问题甚至造成不可恢复的后果,但最终,我们仍然需要在生产环境中进行测试。
举例来说,如果遇到写入磁盘数据经常损坏这类问题,基本思路当然是不要破坏整个数据集,而是为开发人员或者运营人员保留明确目标并执行测试。通过这种方式,开发者能够了解到消费这部分数据的系统能否正常识别并更正损坏问题,或者说系统能否正常处理损坏问题。此外,虽然在生产环境中进行测试也很重要,但通过分段环境测试建立信心,也是减少爆炸半径的一种好办法。直接关闭生产环境中的系统可能没有实际意义;不妨先从负载均衡器入手,确保自动化机制能够处理生产环境中的这一类故障,而后再切入真实生产环境。这样,无疑会对系统的应对能力抱有更充分的信心。
领英内部用到了一种流行机制,即利用 HTTP/RPC 标头来指示客户端何时将下游请求识别为失败。由于 HTTP 标头被限定为单一请求(与能够在整个会话中持续存在的 cookie 不同),因此,开发人员能够简单通过停止发送标头来轻松恢复至良好状态。
实践人员及工具
虽说混沌工程的呼声很高,但组织将其应用到实践中时还是需要考虑一些现实问题,毕竟如果对生产环境产生影响,后果将非常严重。Brian Wilcox 认为,混沌工程最吸引人的地方在于:“让我们破坏生产环境中的一切!”。但是,其它行业一直将故障测试标准视为“工程”的固有组成部分。Brian Wilcox 表示,将故障因素剥离成单独的“一类问题”才是真正的风险。毕竟产品中包含数以千计的细小决策,因此,所有人都有必要了解弹性工程,这一点与应用程序安全性保障非常类似。之所以出现这么多新的保障性模式,就是因为软件工程师面临的保障环境越来越恶劣——大量新框架、新语言以及全新最佳实践的出现,使开发人员很难保障产品弹性。人类总会选择阻力最小的道路,因此除非能够将混沌工程作为单元测试中的必要元素,否则大部分人还是会把弹性工程视为“别人的工作”。
遗憾的是,由于混沌工程的特殊性及其与应用程序堆栈的集成程度问题,目前的相关工具还很不完善。在工具方面,Gremlin 能够与 AWS、GCE 以及 Azure 等顺畅对接,感兴趣的开发者不妨将它作为混沌工程的起步选项。另外,网飞公司也在 GitHub 上发布了大量 Simian Army 源代码——但目前已经不再维护。
从 Brian Wilcox 的角度看,分布式系统最大的控制面在于客户端,从客户端的角度出发,一切都属于网络节点。当存储节点上的磁盘发生故障时,节点本身往往无法凭借弹性设计解决这类故障。相反,远程客户端的灵活性可能更大,例如其在收取故障警告后决定继续使用该数据存储区、还是移动至运行状态数据更好的另一存储区。凭借着这一优势,最理想的模拟应用场景应该是以资源故障为基础,探索优雅而顺畅的错误处理途径。比如,网站能在发生故障时优雅地进行页面降级吗?网站能否继续提供大部分内容,而非直接瘫痪且无法向用户提供任何服务?
至于谁该关心这个问题,Brian Wilcox 的答案是每个人都该关心,这不仅仅是开发人员或者架构师,产品所有者以及管理者都需要权衡并描述应用程序“失效的可能性”,以及哪些组件“有可能导致站点瘫痪”,比如无法投放广告时,是否应该同时停止页面内容的正常显示?或者说,应该继续提供正常的页面内容,并在广告服务恢复后再考虑运营收益的问题?
事实上,大多数高级工程师与架构师都很清楚故障的不可避免特性,而且会在产品开发初期就考虑该如何处理某些故障;然而,用于站点运行的大部分代码实际是由初级工程师们编写的。初级工程师们可能还没有建立起故障终会出现的意识,也无法理解应用程序失败并不等同于职业失败。如果能够让 CEO、项目经理以及软件工程师以生产伙伴的姿态坦然讨论失败问题,相信各个层面都将获得更好的解决方案。
混沌工程并不一定非常复杂。如果已经拥有了充分的信心,同时配合适当的监控,那么“sudo poweroff”也不是什么大事。Brian Wilcox 的一位同事最近谈到了 LuanchDarkly,用 python Flask 中间件执行请求中断。另外,也有不少经典的系统管理工具值得一试,例如使用“iptables”阻断入口与出口,或者使用“tc”来提高延迟,并查看负载均衡器以怎样的速度丢弃集群中缓慢及损坏的节点等。具体方法很多,并不是只有粗暴地关闭机器电源。
结束语
最后,Brian Wilcox 建议组织应该把混沌工程视为框架中的一种默认选项。gRPC、Rest.li、Django、Flask、Request Libraries 等都应该在此列,应该让开发人员能够更轻松地测试自己的应用程序。混沌工程就应该像单元测试里的 Pytest 与 Java Mocks 一样简便易行,应该充分强调 pychaos 与 Java Chaos 的重要地位。虽然根据企业中原有监控方式的具体特性,可能很难了解全面引入混沌工程所带来的影响。但这种标准化工作仍然意义重大,而且组织完全有能力实现这一目标。此外,Brian Wilcox 坚信丰富工具的全面出现将只是时间问题。
采访嘉宾:
Brian Wilcox,现就职于 LinkedIn,任 Staff Site Reliability Engineer。Brian 是一位跨学科工程师和实践爱好者,大部分时间,他都在试图将结构的最佳原则、软件和系统工程结合到可扩展、健壮和有弹性的系统中。他在 LinkedIn 工作了 5 年,最近专注于弹性工程和混沌工程工具。
相关文章:
《PingCAP 唐刘:如何利用混沌工程打造健壮的分布式系统?》
今年 10 月,Brian Wilcox 将在 QCon 上海 2019 分享混沌工程在 LinkedIn 的实践经验,让你对系统的弹性建立起信心,点击了解详情 。
评论