作为一个开发人员,经常会听到架构一词,那么架构到底是什么呢?又为什么需要架构呢?以及架构设计的要点在哪?目前我作为一年级新生(工作经验一年),希望能以自己的了解浅显的回答下这个问题。
架构的定义
架构是什么?维基百科给出的解释是:架构是有关软件整体结构与组件的抽象描述,用于指导大型软件系统各个方面的设计。软件架构会包括软件组件、组件之间的关系,组件特性以及组件间关系的特性。这个回答比较宽泛,实际理解时可能难以和日常工作关联起来。我的理解是,架构是一套开发规范和体系下(如公司、部门规定的开发规范)的具体落地方案,包括了各个模块之间的关系,以及它们协同起来完成功能的具体运作规则。
例如我从网上找到的微博容器调度架构:
其中就介绍了容器调度系统包含了决策层、内核调度层等模块,以及这些模块之间的依赖关系、运作规则。
极客时间《从零开始学架构》里,将架构定义为 4R 架构:
- 软件系统的顶层(Rank)结构;
- 系统由哪些角色(Role)组成;
- 角色之间的关系(Relation);
- 运作规则(Rule)。
结合上图来看,首先架构是分层(Rank)的,一般我们都是关注某一层的架构,而不是把每一层都杂糅在一起。架构设计时采用自顶向下、逐渐细化的方法。
而Role表示系统包含哪些角色,每个角色都会负责系统的一部分功能。而Relation就是指系统角色之间的关系。Rule即角色之间如何协调来完成系统功能。
架构设计的目的
那么为什么需要架构呢?从软件开发的历史来看,早在20世纪60年代,就有计算机大神提出过软件架构的概念。但直到20世纪90年代,随着微软等大公司开发的软件系统逐具规模,此时系统由许多部分组成,他们开始面临软件架构相关的问题,因此“软件架构”开始流行。
而架构设计的目的,简单来说,就是为了解决软件系统复杂度带来的问题。
因此进行架构设计时,并不是盲目追求高性能、高可用、可扩展,而是通过熟悉和理解需求,识别本项目系统的复杂度所在之处,并评估这些复杂度,最后根据复杂点有针对性的设计出满足要求的架构。
作为新人,并不应该盲目追求高性能等指标,符合自己系统的要求即可,例如系统只有2000的TPS,那就没必要设计出可支持TPS每秒10万的系统,这样的系统当然可用,但会浪费成本,没有必要。
架构复杂度来源
软件架构的复杂度主要来自于高可用、高性能以及可扩展性,除此之外,还需要考虑低成本性、安全、规模效应等方面的因素。
高性能
“摩尔定律”表明了CPU的处理能力是每18个月就翻倍,随着硬件系统的性能提升,软件系统一般也会跟随硬件系统的发展而发展。进而导致软件系统的复杂度增加。例如一开始是批处理,后来发展到多进程,为了继续提高并行处理的性能,又提出来多线程,到目前的多协程。那么如果我们要完成一个高性能的软件系统,所考虑的技术点也就有所不同,并且往往不是非此即彼的选择,一般是要多方面考量,这些因素都会增加软件系统的复杂度。目前讨论的还是单机可能遇到的情况,进入互联网时代后,业务发展速度远超硬件发展速度,又引入了机器集群来满足高性能的要求。多台机器的高性能配合要求又会引入更多的复杂度,例如如何分配任务到不同的机器上,不同机器上部署的任务不同时,如何保证一个完整的流程经过不同机器的任务处理后能顺利且快速的完成。
高可用
无论是单机还是多个集群,都很难保证不出问题。毕竟硬件可能会出故障,软件也可能有bug。即使我们的系统非常完美,外部因素也可能导致异常,如光纤被挖断、断电、地震等情况的方式。高可用本质还是通过“冗余”来实现,即一条通道可能会出问题,那么就部署多条可用通道,一个地区可能有问题,那么跨地区、多地区部署服务。它和高性能的机器集群类似,都引入了更多的机器,但引入机器的目的却有本质区别:高性能增加机器是为了“扩展”处理的性能,高可用增加机器是为了“冗余”处理单元。
高可用又可以根据不同的应用场景,分为计算高可用、存储高可用等,其需要解决的问题也不同。对于计算高可用来说,同一个输入和算法,在不同的机器上的输出结果需要保持一致。而存储高可用,由于涉及到机器数据的备份和传输,需要考虑如何尽量减小或者规避数据不一致对业务造成的影响。
可扩展性
对于可扩展性来说,需要预测未来的变化,并在设计架构时考虑应对变化的方案。一般,一个软件系统自上线起,就会不断地更新迭代,因此在设计架构时,需要考虑可能会有的变化是否会对当前的架构设计产生影响。同时,如何把握需要考虑多长时间维度内的变化,也值得思考,否则考虑的太多,架构设计的太过复杂,反而不利于上线初期的开发、维护。因此,一般考虑2-3年内的变化,并将可能发生变化的模块与不变的模块分开,通过隔离变化来尽量降低其影响。在《重构》一书中也给出过一个"Rule of three"的原则,即一开始时设计尽量简单的架构,前两次遇到类似的实现时,直接copy,直到第三次遇到,再考虑可扩展性方案,进行重构。
软件架构设计原则
针对软件架构中可能出现的复杂度,可以遵循合适、简单和演化这三个原则来进行考量。
合适原则
在设计架构或者做方案时,不需要一开始就想着设计多么庞大的系统,应该结合当前的人力、资源等约束进行考虑,满足当下的要求之后,再考虑2年内可能出现的变化,以此为考量进行设计一般即可满足要求。