架构设计的简单原则,你学会了吗?

科技事要畅享 2024-09-10 19:45:16

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

图片

由于软件架构与建筑架构在表面上存在相似性,我们往往会下意识地将对建筑的审美观念迁移至软件架构之上。对于我们亲自构建的软件架构,我们期望它如著名建筑一般宏伟、精美、富有艺术感且豪华…… 总之,绝不能显得寒酸或简单。

团队压力有时也会在有意无意间促使我们走向复杂的方向。因为在大多数人评价一个方案水平高低时,复杂性是一项重要的参考指标。例如,设计一个主备方案,若采用心跳机制来实现,或许大家会觉得这太过简单。然而,若引入 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 个小时就要重启一次。线上运行出现故障,几十个人扑上去定位和处理,一间小黑屋都装不下所有人,整个办公区都会闹翻天。

总之,谁都无法忍受这样的场景。功能复杂的组件,另一个典型特征就是采用了复杂的算法。复杂算法导致的问题主要是难以理解,进而难以实现、难以修改,并且出了问题难以快速解决。

更多资讯,点击

0 阅读:12

科技事要畅享

简介:感谢大家的关注