软件系统与硬件和建筑系统最大的差异在于软件是可扩展的。架构可扩展模式主要包括分层架构、SOA 架构、微服务和微内核等。
所有的可扩展性架构设计,基本思想都可以总结为一个字:拆!将原本大一统的系统拆分成多个规模小的部分,扩展时只修改其中一部分即可,无须整个系统到处都改,通过这种方式来减少改动范围,降低改动风险。
按照不同的思路来拆分软件系统,就会得到不同的架构。常见的拆分思路有如下三种:
理解这三种思路的关键就在于如何理解“流程”“服务”“功能”三者的联系和区别。
从范围上来看,从大到小依次为:流程 > 服务 > 功能,。以 TCP/IP
协议栈为例,来说明“流程”“服务”“功能”的区别和联系,TCP/IP
协议栈和模型图如下图所示。
TCP/IP
四层模型,因为 TCP/IP
网络通信流程是:应用层 → 传输层 → 网络层 → 物理 + 数据链路层。以学生信息管理系统为例,拆分方式是:
面向流程拆分
展示层 → 业务层 → 数据层 → 存储层,各层含义是:
最终的架构如下:
面向服务拆分
将系统拆分为注册、登录、信息管理、安全设置等服务,最终架构示意图如下:
面向功能拆分
每个服务都可以拆分为更多细粒度的功能,例如:
最终架构图如下:
通过学生信息管理系统的案例可以发现,不同的拆分方式,架构图差异很大。但无论哪种方式,最终都是可以实现的。不同的拆分方式,本质上决定了系统的扩展方式。
合理的拆分,能够强制保证即使程序员出错,出错的范围也不会太广,影响也不会太大。下面是不同拆分方式应对扩展时的优势。
不同的拆分方式,将得到不同的系统架构,典型的可扩展系统架构有:
这些系统架构并不是非此即彼的,而是可以在系统架构设计中进行组合使用的。
以学生管理系统为例,最终可以这样设计架构:
- 整体系统采用面向服务拆分中的“微服务”架构,拆分为“注册服务”“登录服务”“信息管理服务”“安全服务”,每个服务是一个独立运行的子系统。
- 其中的“注册服务”子系统本身又是采用面向流程拆分的分层架构。
- “登录服务”子系统采用的是面向功能拆分的“微内核”架构。
分层架构(也称为 N 层架构,至少2层)是很常见的架构模式,通常情况下:
按照分层架构进行设计时,根据不同的划分维度和对象,可以得到多种不同的分层架构。
TCP/IP
架构。无论采取何种分层维度,分层架构设计最核心的是需要保证各层之间的差异足够清晰,边界足够明显,让人看到架构图后就能看懂整个架构,这也是分层不能分太多层的原因。
分层架构能够较好地支撑系统扩展,本质在于隔离关注点(separation of concerns),即每个层中的组件只会处理本层的逻辑。
这样在扩展某层时,其他层是不受影响的,通过这种方式可以支撑系统在某层上快速扩展。并不是简单地分层就一定能够实现隔离关注点从而支撑快速扩展,分层时要保证层与层之间的依赖是稳定的,才能真正支撑快速扩展。
分层结构的另外一个特点就是层层传递,一旦分层确定,整个业务流程是按照层进行依次传递的,不能在层之间进行跳跃。最简单的 C/S 结构,用户必须先使用 C 层,然后 C 层再传递到 S 层,用户是不能直接访问 S 层的。
SOA 的全称是 Service Oriented Architecture,翻译为“面向服务的架构”。
SOA 出现的背景是企业内部的 IT 系统重复建设且效率低下,主要体现在:
为了应对传统 IT 系统存在的问题,SOA 提出了 3 个关键概念。
服务
所有业务功能都是一项服务,服务就意味着要对外提供开放的能力,当其他系统需要使用这项功能时,无须定制化开发。服务可大可小,可简单也可复杂。服务的粒度根据企业实际情况进行判断。
ESB
全称是 Enterprise Service Bus,翻译为“企业服务总线”。ESB 参考了计算机总线的概念。计算机中的总线将各个不同的设备连接在一起,ESB 将企业中各个不同的服务连接在一起。
因为各个独立的服务是异构的,如果没有统一的标准,则各个异构系统对外提供的接口是各式各样的。SOA 使用 ESB 来屏蔽异构系统对外提供各种不同的接口方式,以此来达到服务间高效的互联互通。
松耦合
目的是减少各个服务间的依赖和互相影响。因为采用 SOA 架构后,各个服务是相互独立运行的,甚至都不清楚某个服务到底有多少对其他服务的依赖。
如果做不到松耦合,某个服务一升级,依赖它的其他服务全部故障,这样肯定是无法满足业务需求的。但实际上真正做到松耦合并没有那么容易,要做到完全后向兼容,是一项复杂的任务。
典型的 SOA 架构样例如下:
SOA 架构是比较高层级的架构设计理念,一般情况下可以说某个企业采用了 SOA 的架构来构建 IT 系统,但不会说某个独立的系统采用了 SOA 架构。
ESB 虽然功能强大,但现实中的协议有很多种,如 JMS、WS、HTTP、RPC 等,数据格式也有很多种,如 XML、JSON、二进制、HTML 等。
ESB 要完成这么多协议和数据格式的互相转换,工作量和复杂度都很大,而且这种转换是需要耗费大量计算性能的,当 ESB 承载的消息太多时,ESB 本身会成为整个系统的性能瓶颈。
SOA 的 ESB 设计也是无奈之举。SOA 的提出背景是各种异构的 IT 系统都已经存在很多年了,完全重写或者按照统一标准进行改造的成本是非常大的,只能通过 ESB 方式去适配已经存在的各种异构系统。