为什么说优秀架构师往往是一个悲观主义者?

游骥 2019-12-14 09:57:00

 

 

 

 

 

 

 

 

 

 

 

 

 

 

6、外部攻击
 

你需要考虑各种攻击行为,包含流量攻击和安全攻击。你的系统可能随时会面临着DDOS和CC类攻击,你传输的数据可能会被盗取或者篡改。

7、依赖库问题
 

你的系统很可能会用大量的二方库或者三方库,它们对你来说是黑盒子,你不了解它们存在哪些风险,并且你无法掌控。这些库可能会存在漏洞、可能会有bug,可能会大量消耗你的系统资源,总之不要太信任它们。

8、依赖服务问题
 

你依赖的服务也一定不会100%可用,它们可能会超时,可能会失败。当依赖服务超时的时候,如果你没有很好地处理,可能会导致你自己的系统无法工作,在分布式场景下,这种失败状态会持续辐射,最终导致大面积的不可用。

二、如何面向失败设计

作为一个悲观主义者,你需要在一开始的系统设计阶段就考虑到以上各种失败场景,把面向失败当成系统设计的一部分,并且准备好从失败中恢复的策略,这有助于更好地提升整个系统的可用性。

 

只有你意识到事情会随着时间的推移而失败,并将这种思想融入到体系结构中,那么在失败发生的时候你才能完全不受影响或者将失败损失降到最低。面向失败的设计理念数十年来并没有多大的变化,一些好的经典原则在今天依旧被广泛运用。

1、冗余设计避免单点故障
 

硬件和软件都不可靠,环境和人都存在极大的不确定性,虽然无法避免失败场景的发生,但是可以通过冗余设计来规避局部失败对系统的影响。

 

冗余设计避免单点故障这一策略在互联网技术架构中处处可见,比如重要的服务通常都会部署多个、数据库的主备结构、服务调用的重试机制、存储的多副本等概念都属于这一范畴。

2、面向失败的宏观多活架构
 

除了局部失败场景,你的系统可能还面临着大范围的失败场景。大范围的原因有两个:

 

  • 天灾,比如火灾、地震、台风、雷电等大的自然灾害可能导致大面积的基础设备被毁坏;

  • 人祸:人的失误或者刻意破坏行为有时候也会酿成大祸,如操作错误、破坏、植入有害代码和恐怖袭击。

3、服务能力与依赖调用自我保护
 

如何来衡量一个软件系统的设计是否优良?一条很重要的衡量标准——在任何情况之下你的软件系统都应该工作在当前环境的最优状态。

 

每个人都知道机翼是飞机的重要部件,一旦机翼出现问题,飞机很可能就会坠落。然而在二战当中,许多战斗机即便机翼千疮百孔了,依然保持着最佳战斗能力;甚至还有更夸张的情况:1983年的一次战斗机演习当中,一架飞机由于事故损失了一个机翼,这架缺少一个机翼的飞机依然保持了飞行能力、最终完成安全着陆。

软件系统由两部分构成:系统自身的代码和依赖的库以及服务。“服务能力与依赖调用自我保护”需要从这两块分别切入构建系统在任意情况都始终工作在最佳状态的能力。服务限流、系统负载保护、给依赖的服务设置超时或者资源限制等都是相应的应对策略。

4、为一切不可预料的情况备好预案
 

能够抵抗失败和从失败中快速恢复是面向失败设计的核心思想,然而即便已经做了万全的设计,也并非所有的失败场景都是系统能够自动抵御的。

 

你需要考虑到所有的失败场景,并准备好相应的应对预案。为一切不可预料的情况备好预案才能在失败场景真正发生时做到有条不紊。做好预案需要对失败场景有全面的考虑:会发生哪些失败?失败会带来什么问题?应对策略是什么?预期的恢复时间多久?恢复后的影响面有多大?需要通知到哪些角色?等这一系列的因子构成了一个完整的预案体系。

5、自动化运维管控
 

大量的系统故障是因为人的失误造成的,即便让一个优秀的运维工程师进行一万次同样的运维操作也难免不出错。

 

唯一的解决办法便是在运维过程当中尽可能降低人为操作的比重。系统化、白屏化是第一个阶段——将人为的操作步骤固化成系统程序,避免操作失误;自动化以及智能化是第二个阶段——将正确的决策过程也固化成智能程序,避免决策失误。

 

同时所有的运维动作都需要遵循灰度原则,做到可灰度、可监测、可回滚,即便出现了失误也能控制好爆炸半径,并且做到快速恢复。

6、精细化的监控体系
 

面向失败设计不仅要求你的系统足够健壮,同时要求你能够在第一时间感知到失败的发生。无论是自动化的系统恢复,还是人为介入,如果你压根都不知道是哪里出问题了,一切都将束手无策。

 

精细化的监控体系一方面能够在出现问题的时候以最快的速度将最准确的信息传递到人或者运维系统,同时它还能够展现趋势、进行提前预警。

 

AI技术的结合使得监控领域在近几年得到了新的发展驱动力:智能监控报警、根因定位、智能预测、智能决策等能力都是学术界和工程界非常热衷的课题。

7、故障与攻防演练锤炼容灾应急能力
 

最后,即便以上工作都做好了,你也不能高枕无忧去等待失败到来。你的设计、系统、流程、技术人员等需要通过不断演练,来保障能力和进化升级。对于代价非常巨大的事件,做好前期的充分演练是非常有必要的,比如军事演练、消防演练等都属于这一范畴。

 

而系统不可用的代价对于企业来讲很可能是无法承受的,因此需要在平时做好充分的演练:通过故障与攻防演练锤炼容灾应急能力,对面向失败的设计做好充分验证。只有当所有的失败场景都被提前演练过,当失败真正来临时才能做到胸有成竹。

 

作者丨游骥
来源丨阿里技术(ID:ali_tech)
dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn
活动预告