架构设计的三个原则 | 张逸说
在进行架构设计时,我认为需要遵循如下原则:
- 一致原则
- 简单原则
- 演进原则
一致原则
一致性是软件架构质量原则的根基,遵循一致原则的软件架构可以有效地保证整个架构解决方案的清晰直接,降低了解决方案的复杂度。尤其对于一个大规模系统,往往需要多个团队共同开发完成,如果不遵循一致原则,就会导致整个平台的建设缺乏完整性和规范性,各个子系统各自为政,业务功能重复开发,技术实现五花八门,服务集成复杂低效,信息冗余制造出知识壁垒。
一致原则具体体现为:
- 架构风格的一致性:针对相同的业务复杂度和技术复杂度,要形成统一的架构风格。例如,对外公开的业务能力采用微服务架构风格,保证各个服务的高内聚低耦合,确保了整个系统的可扩展能力;数据采集、治理和分析业务采用基于Lambda架构模式的大数据架构风格,为数据的处理建立批处理层与速度处理层,满足不同业务场景的数据需求;服务之间的异步消息协作采用事件驱动架构风格,保证服务之间消息传递的高效性与实时性,提高整个系统的响应能力;
- 技术选型的一致性:针对相同或相似的问题,应采用相同的方案和技术,从而使得开发人员在掌握了其中一种解决方案后,针对相似的问题,可以推导出相同的解决方案,降低了方案的复杂度,规避了重复开发,降低了代码的维护成本。以微服务架构为例,技术选型涉及的内容主要包括微服务组件、日志处理、权限管理、分布式事务、数据库访问、消息通信机制、缓存技术、安全策略、开发语言、框架版本、监控运维,同时,还要求开发团队遵循一致的编码规范。
简单原则
软件架构的目的就是为了控制软件系统的复杂度。分析软件系统的复杂度成因,主要来自规模、结构和变化。
对于规模引起的复杂度,可以通过“分而治之”的思想来解决,也就是将整个系统按照业务维度拆分为多个细小而简单的模块(组件或服务),每个服务的规模都是团队或团队成员可以控制的。
结构引起的复杂度取决于参与协作的模块(组件或服务)的数量,数量越多,模块之间的关系就越复杂,因为协作产生的依赖很容易让整个系统变得混乱而无序,增加了开发和维护的成本。要降低复杂度,就需要清晰地定义模块的边界,合理地分配职责,以减少不必要的依赖关系;同时,定义一致而稳定的协作接口,让模块之间的协作变得有序,清晰地体现彼此之间的调用链,明确消息数据的传递方向。
需求的变化总是会带来解决方案的调整,最终使得持续变化的解决方案变得越来越复杂。如何有效地应对需求变化?一方面需要团队提前识别出可能发生变化的热点功能,另一方面也需要注意避免对未来做出过度设计。若能识别出变化的热点功能,就能通过封装或抽象的设计原则,让实现方案尽可能具有可扩展能力,将变化产生的影响降到最低。然而,未来的变化总是不可预测的,如果不能确定未来是否会发生变化,则不要引入太多的间接和抽象,形成过度设计,增加了解决方案的复杂度。
遵循简单原则的架构体现为:
- 引入领域驱动设计的限界上下文模式帮助合理地识别微服务,明确微服务之间的协作模式,确定业务需求与微服务之间的映射关系,减少不必要的微服务协作;
- 采用前后端分离,避免了前端用户体验复杂度与后端业务复杂度之间混合导致的复杂度叠加,也可以保证前、后端开发团队明确前后端协作的接口,进行并行开发;
- 保持模块之间接口的松耦合,从架构上考虑数据分析场景与业务处理场景的分离,以定义数据平台的边界,驱动出数据交换的接口,确定数据平台和业务服务之间的协作方式;
- 识别复用的业务能力:站在产品高度和全面视角分析业务能力,将满足单一职责的业务能力封装为高内聚的服务或组件,完成功能的复用,降低系统的代码规模,保证了系统的简单性。
演进原则
架构设计不是一蹴而就的,由于需求会不断发生变化,架构设计也需要针对变化的需求做出调整。由于架构做出的设计和决策往往是一个软件系统最为重要的部分,对架构做出的调整成本和难度都比较大,因此,在进行架构设计时,应考虑解决方案的演进能力,即能够随着需求的变化以最小的修改成本实现架构方案的不断演进。
遵循演进原则的架构应满足:
- 响应变化的能力:演进能力的一个体现是响应变化的能力,一个设计原则是将变化产生的影响控制到最小范围。这一原则确定了架构方案需要按照变化的方向进行模块的划分,从而顺应变化,同时,保证业务复杂度与技术复杂度的正交关系,避免业务的变化影响到技术实现的变化,反之亦然。我们可遵循企业架构的设计思想,根据不同的观察视角将整个系统架构划分为业务架构、应用架构、数据架构和技术架构。其中,为了降低变化影响,让系统的应用架构和数据架构对准业务架构,即按照业务能力对系统的模块(组件或服务)进行职责划分,同时保证每个应用模块中的领域模型与数据模型对应;对于技术架构,则通过分层架构模式将业务与技术分离,保证二者的松散耦合;
- 职责分配与合理抽象:识别和设计微服务的质量直接影响到系统的演进能力,整个系统需要针对领域进行分析,从业务能力的角度进行功能的职责分配,保证每个微服务是内聚的,同时,通过有效识别变化的热点,对其利用抽象降低彼此之间的耦合,保证了具体实现的可扩展能力与可替换能力;
- 架构模式的运用:对于业务系统而言,通过采用微服务架构模式、事件驱动架构模式和分层架构模式,尽可能保证整个业务系统的松散耦合,提高系统架构的演化能力;对于数据平台,可采用基于流处理的管道-过滤器模式,通过将数据处理功能拆分为一个个过滤器(processor),然后在管道中自由组合这些过滤器,满足整个数据处理流程的需要。这一模式保证了功能的复用性和可扩展性。