可靠性只有靠对最大程度的简化不断追求而得到。 —C.A.R. Hoare,Turing Award lecture
软件系统本质上是动态的和不稳定的。只有真空中的软件系统才是永远稳定的。如果我们不再修改代码,就不会引入新的 Bug。如果底层硬件或类库永远不变,这些组件也就不会引入Bug。如果冻结当前用户群,我们将永远不必扩展系统。事实上,一个对SRE管理系统的方法不错的总结是∶"我们的工作最终是在系统的灵活性和稳定性上维持平衡。”
系统的稳定性与灵活性 有的时候为了灵活性而牺牲稳定性是有意义的。我在面临一个不熟悉的问题域时,经常进行"探索性编码"———给我写的任何代码设置一个明确的保质期,我清楚地知道自己需要先探索以及失败才能真正理解需要完成的任务。这种带保质期的可以在测试覆盖和发行管理上更宽松,因为它永远不会被发布到生产环境或被用户使用。
对于大多数生产环境软件系统来说,我们想要在稳定性和灵活性上保持平衡。SRE通过创造流程、实践以及工具,来提高软件的可靠性。同时,SRE需要最小化这些工作对于开发人员的灵活性造成的影响。事实上,SRE的经验表明,可靠的流程会提高研发人员的灵活性∶快速、可靠的产品发布使得生产系统中的变化显而易见。这样,一旦出现错误,找到和改正错误的时间会更少。在开发过程中引入可靠性可以让开发人员关注那些真正需要关注的事情———软件和系统的功能与性能。
乏味是一种美德 与生活中的其他东西不同,对于软件而言,"乏味"实际上是非常正面的态度! 我们不想要自发性的和有趣的程序;我们希望这些程序按设计执行,可以预见性地完成商业目标。Google 工程师 Robert Muth 曾说过,"与侦探小说不同,缺少刺激、悬念和困惑是源代码的理想特性。"生产环境中的意外是 SRE 最大的敌人。
FredBrooks 在他写的名为 No Siver Bulet的文章(参见文献 【Bro95】)中表示,关注必要复杂度和意外复杂度之间的区别非常关键。必要复杂度是一个给定的情况所固有的复杂度,不能从该问题的定义中移除,而意外复杂度则是不固定的,可以通过工程上的努力来解决。例如,编写一个Web服务器需要处理快速提供Web页面的必要复杂度。但是,如果我们用Java编写该服务器,试图减少GC的影响就可能会引入意外复杂度。
为了最小化意外复杂度,SRE 团队应该∶
● 在他们所负责的系统中引入意外复杂度时,及时提出抗议。 ● 不断地努力消除正在接手的和已经负责运维的系统的复杂度。
|