在敏捷软件开发领域,质量内建是一个广受欢迎的实践。这种将质量意识贯彻到软件开发各个环节,从而节省返工成本的做法,其本质就是”预防为主“。
但片面强调“预防为主”,会给人一个错觉,那就是软件系统的任何故障,都可以通过“预防”来解决。
基于这个错觉,一旦出现了线上事故,那么人们首先就会责备开发、测试和运维人员,因为他们“不能也不该出现失误”。
像“绝不能将任何风险引入生产环境”这样的口号,只是人们美好的愿望。“暗债本固有”的客观事实,大家则都心知肚明。
在云原生和微服务这些复杂系统大行其道的年代,必须承认,一个人的大脑,无法承载分布式系统的全部细节;每个人对系统的理解,也会存在差异;加上沟通时所发生的信息损耗,当他们合作开发软件时,就必然会产生不可预知的“暗债”。
然而,这些只是我们所开发的系统的内部暗债。更可怕的,是外部暗债,它们潜伏在我们的系统所依赖的外部系统和网络环境中。由于在我们的控制之外,这些外部暗债更难以预测,所以它们“不按常理出牌”就再自然不过了。
我们虽然能凭借”软件测试“和”故障演练“来提升软件质量,但这种经常采用固定测试用例和相同演练流程的手段,却让软件系统在生产环境上,无法应对来自外部暗债”不按常理出牌“的种种”恶毒“考验,比如本应通畅的网络出现了延迟,本应能正常写入的磁盘被写满了,本应理智的用户不知为何开始疯狂地反复点击提交按钮……
我们就生活在这种充满了非线性和不确定性的世界中。
“预防为主”固然很好,但因为”人无完人“,所以“暗债”必然会产生。而其不可预知的特点,导致无法做到“预防暗债”。
让我们重温一下“面向恢复的计算“所信奉的观点:
. 无论在硬件方面还是软件方面,系统失效都是不可避免的。
. 建模和分析永远都不会足够完备,用推导的方法预测所有系统失效方式是不可能的。
. 人的行为是系统失效的主要原因。
这种论断是不是太悲观了。面对复杂系统中无法预知和“预防”的“暗债”,我们还能做什么?
我们可以做下面三件事:
. 承认“暗债”本就固有
. 故障发现修复要快
. 随时树立起警示牌
下次云平台发生故障,我期望能看到这样的故障说明:“我们要为该故障树立起警示牌,并提升故障的发现和修复速度,最终达到在用户尚未察觉的情况下,快速发现并修复故障。”
在承认暗债本固有的前提下,设计安全的方法来做“不按常理出牌”的实验,以考验软件系统的稳定性,以促进“快速发现和修复故障”,从而有效地对“预防为主“的质量内建进行补充。
这种工程实践,就是混沌工程。