你好,欢迎收听极客视点。

很多程序员都有一个架构梦,但难点之一在于架构设计领域并没有一套通用的规范来指导架构师进行架构设计。此前,极客时间专栏《从0开始学架构》的作者李运华表示,在研究了众多互联网公司架构设计后,他发现有几个共性的原则隐含其中,就是合适原则、简单原则和演化原则,架构设计时遵循这几个原则,有助于你做出最好的选择。本文摘录了李运华在《从0开始学架构》专栏中对简单原则的解释,供你参考。

简单原则宣言是:“简单优于复杂”。

由于软件架构和建筑架构表面上的相似性,我们也会潜意识地将对建筑的审美观点移植到软件架构上面。对于我们自己亲手打造的软件架构,我们希望它像著名建筑那样宏伟、精美、艺术、豪华……总之就是不能寒酸、不能简单。

团队的压力有时也会有意无意地促进我们走向复杂的方向,因为大部分人在评价一个方案水平高低的时候,复杂性是其中一个重要的参考指标。例如设计一个主备方案,如果你用心跳来实现,可能大家都认为这太简单了。但如果你引入ZooKeeper来做主备决策,可能很多人会认为这个方案更加“高大上”一些,毕竟ZooKeeper使用的是ZAB协议,而ZAB协议本身就很复杂。其实,真正理解ZAB协议的人很少,但并不妨碍我们都知道ZAB协议很优秀。

软件领域的复杂性体现在两个方面:

第一个方面是结构的复杂性

结构复杂的系统几乎毫无例外具备两个特点:

  • 组成复杂系统的组件数量更多;

  • 同时这些组件之间的关系也更加复杂。

但是,结构上的复杂性存在的第一个问题是,组件越多,就越有可能其中某个组件出现故障,从而导致系统故障。这个概率可以算出来,假设组件的故障率是10%(有10%的时间不可用),那么有3个组件的系统可用性是(1-10%)×(1-10%)×(1-10%)= 72.9%,有5个组件的系统可用性是(1-10%)×(1-10%)×(1-10%)×(1-10%)×(1-10%)=59%,两者的可用性相差13%。

结构上的复杂性存在的第二个问题是,某个组件改动,会影响关联的所有组件,这些被影响的组件同样会继续递归影响更多的组件。这个问题会影响整个系统的开发效率,因为一旦变更涉及外部系统,需要协调各方统一进行方案评估、资源协调、上线配合。

结构上的复杂性存在的第三个问题是,定位一个复杂系统中的问题总是比简单系统更加困难。首先是组件多,每个组件都有嫌疑,因此要逐一排查;其次组件间的关系复杂,有可能表现故障的组件并不是真正问题的根源。

第二个方面体现在逻辑的复杂性

意识到结构的复杂性后,我们的第一反应可能就是“降低组件数量”,毕竟组件数量越少,系统结构越简单。最简单的结构当然就是整个系统只有一个组件,即系统本身,所有的功能和逻辑都在这一个组件中实现。

不幸的是,这样做是行不通的,原因在于除了结构的复杂性,还有逻辑的复杂性,即如果某个组件的逻辑太复杂,一样会带来各种问题。

逻辑复杂的组件,一个典型特征就是单个组件承担了太多的功能。以电商业务为例,常见的功能有:商品管理、商品搜索、商品展示、订单管理、用户管理、支付、发货、客服……把这些功能全部在一个组件中实现,就是典型的逻辑复杂性。

假设现在淘宝将这些功能全部在单一的组件中实现,可以想象一下这个恐怖的场景:

  • 系统会很庞大,可能是上百万、上千万的代码规模,“clone”一次代码要30分钟。

  • 几十、上百人维护这一套代码,某个“菜鸟”不小心改了一行代码,导致整站崩溃。

  • 需求像雪片般飞来,为了应对,开几十个代码分支,然后各种分支合并、各种分支覆盖。

  • 产品、研发、测试、项目管理不停地开会讨论版本计划,协调资源,解决冲突。

  • 版本太多,每天都要上线几十个版本,系统每隔1个小时重启一次。

  • 线上运行出现故障,几十个人扑上去定位和处理,一间小黑屋都装不下所有人,整个办公区闹翻天。

  • ……

不用多说,肯定谁都无法忍受这样的场景。

功能复杂的组件,另外一个典型特征就是采用了复杂的算法。复杂算法导致的问题主要是难以理解,进而导致难以实现、难以修改,并且出了问题难以快速解决。

综上,无论是结构的复杂性,还是逻辑的复杂性,都会存在各种问题,所以架构设计时如果简单的方案和复杂的方案都可以满足需求,最好选择简单的方案。《UNIX编程艺术》总结的KISS(Keep It Simple, Stupid!)原则一样适应于架构设计。

优惠口令:jiagou999 适用专栏:《从0开始学架构》 适用规则:立减 10 元(满 40 元可用) 有效期:8月5日 - 8月11日