今天我们进入架构可扩展模式的学习,这部分内容包括分层架构、SOA 架构、微服务和微内核等,先来聊聊架构的可扩展模式。
可扩展的基本思想
幸运的是,可扩展性架构的设计方法很多,但万变不离其宗,所有的可扩展性架构设计,背后的基本思想都可以总结为一个字:拆!
按照不同的思路来拆分软件系统,就会得到不同的架构。常见的拆分思路有如下三种。
我再以一个简单的学生信息管理系统为例(几乎每个技术人员读书时都做过这样一个系统),拆分方式是:
展示层 → 业务层 → 数据层 → 存储层
最终的架构如下:
将系统拆分为注册、登录、信息管理、安全设置等服务,最终架构示意图如下:
最终架构图如下:
可扩展方式
不同的拆分方式,将得到不同的系统架构,典型的可扩展系统架构有:
分层架构
分层架构是很常见的架构模式,它也叫 N 层架构,通常情况下,N 至少是 2 层。例如,C/S 架构、B/S 架构。常见的是 3 层架构(例如,MVC、MVP 架构)、4 层架构,5 层架构的比较少见,一般是比较复杂的系统才会达到或者超过 5 层,比如操作系统内核架构。
C/S 架构、B/S 架构
划分的对象是整个业务系统,划分的维度是用户交互,即将和用户交互的部分独立为一层,支撑用户交互的后台作为另外一层。例如,下面是 C/S 架构结构图。
MVC 架构、MVP 架构
划分的对象是单个业务子系统,划分的维度是职责,将不同的职责划分到独立层,但各层的依赖关系比较灵活。例如,MVC 架构中各层之间是两两交互的:
逻辑分层架构
划分的对象可以是单个业务子系统,也可以是整个业务系统,划分的维度也是职责。虽然都是基于职责划分,但逻辑分层架构和 MVC 架构、MVP 架构的不同点在于,逻辑分层架构中的层是自顶向下依赖的。典型的有操作系统内核架构、TCP/IP 架构。例如,下面是 Android 操作系统架构图。
典型的 J2EE 系统架构也是逻辑分层架构,架构图如下:
针对整个业务系统进行逻辑分层的架构图如下:
无论采取何种分层维度,分层架构设计最核心的一点就是需要保证各层之间的差异足够清晰,边界足够明显,让人看到架构图后就能看懂整个架构,这也是分层不能分太多层的原因。
分层架构的特点
分层架构的缺点
分层架构另外一个典型的缺点就是性能,因为每一次业务请求都需要穿越所有的架构分层,有一些事情是多余的,多少都会有一些性能的浪费。当然,这里所谓的性能缺点只是理论上的分析,实际上分层带来的性能损失,如果放到 20 世纪 80 年代,可能很明显;但到了现在,硬件和网络的性能有了质的飞越,其实分层模式理论上的这点性能损失,在实际应用中,绝大部分场景下都可以忽略不计。
SOA
SOA 的全称是 Service Oriented Architecture,中文翻译为“面向服务的架构”。
为了应对传统 IT 系统存在的问题,SOA 提出了 3 个关键概念。
SOA 解决了传统 IT 系统重复建设和扩展效率低的问题,但其本身也引入了更多的复杂性。SOA 最广为人诟病的就是 ESB,ESB 需要实现与各种系统间的协议转换、数据转换、透明的动态路由等功能。
为什么互联网企业很少采用 SOA 架构?
SOA是把多个系统整合,而微服务是把单个系统拆开来,方向正好相反
微服务与 SOA 的关系
SOA 和微服务本质上是两种不同的架构设计理念,只是在“服务”这个点上有交集而已,因此两者的关系应该是上面第三种观点
微服务的陷阱
我们看一下微服务具体有哪些坑:
专栏上一期,我谈了实施微服务需要避免踩的陷阱,简单提炼为:
服务粒度
针对微服务拆分过细导致的问题,我建议基于团队规模进行拆分,类似贝索斯在定义团队规模时提出的“两个披萨”理论(每个团队的人数不能多到两张披萨都不够吃的地步),分享一个我认为微服务拆分粒度的“三个火枪手”原则,即一个微服务三个人负责开发。
“三个火枪手”的原则主要应用于微服务设计和开发阶段,如果微服务经过一段时间发展后已经比较稳定,处于维护期了,无须太多的开发,那么平均 1 个人维护 1 个微服务甚至几个微服务都可以。当然考虑到人员备份问题,每个微服务最好都安排 2 个人维护,每个人都可以维护多个微服务。
拆分方法
这是最常见的一种拆分方式,将系统中的业务模块按照职责范围识别出来,每个单独的业务模块拆分为一个独立的服务。
将系统中的业务模块按照稳定性排序,将已经成熟和改动不大的服务拆分为稳定服务,将经常变化和迭代的服务拆分为变动服务。稳定的服务粒度可以粗一些,即使逻辑上没有强关联的服务,也可以放在同一个子系统中,例如将“日志服务”和“升级服务”放在同一个子系统中;不稳定的服务粒度可以细一些,但也不要太细,始终记住要控制服务的总数量。
将系统中的业务模块按照优先级排序,将可靠性要求高的核心服务和可靠性要求低的非核心服务拆分开来,然后重点保证核心服务的高可用。具体拆分的时候,核心服务可以是一个也可以是多个,只要最终的服务数量满足“三个火枪手”的原则就可以。
基于性能拆分和基于可靠性拆分类似,将性能要求高或者性能压力大的模块拆分出来,避免性能压力大的服务影响其他服务。常见的拆分方式和具体的性能瓶颈有关,可以拆分 Web 服务、数据库、缓存等。例如电商的抢购,性能压力最大的是入口的排队功能,可以将排队功能独立为一个服务。
以上几种拆分方式不是多选一,而是可以根据实际情况自由排列组合,例如可以基于可靠性拆分出服务 A,基于性能拆分出服务 B,基于可扩展拆分出 C/D/F 三个服务,加上原有的服务 X,最后总共拆分出 6 个服务(A/B/C/D/F/X)。
基础设施
微服务基础设施如下图所示:
虽然建设完善的微服务基础设施是一项庞大的工程,但也不用太过灰心,认为自己团队小或者公司规模不大就不能实施微服务了。第一个原因是已经有开源的微服务基础设施全家桶了,例如大名鼎鼎的 Spring Cloud 项目,涵盖了服务发现、服务路由、网关、配置中心等功能;第二个原因是如果微服务的数量并不是很多的话,并不是每个基础设施都是必须的。通常情况下,我建议按照下面优先级来搭建基础设施:
以上 3 和 4 两类基础设施,其重要性会随着微服务节点数量增加而越来越重要,但在微服务节点数量较少的时候,可以通过人工的方式支撑,虽然效率不高,但也基本能够顶住。
基本架构
微内核架构包含两类组件:核心系统(core system)和插件模块(plug-in modules)。核心系统负责和具体业务功能无关的通用功能,例如模块加载、模块间通信等;插件模块负责实现具体的业务逻辑,例如专栏前面经常提到的“学生信息管理”系统中的“手机号注册”功能。
微内核的基本架构示意图如下:
上面这张图中核心系统 Core System 功能比较稳定,不会因为业务功能扩展而不断修改,插件模块可以根据业务功能的需要不断地扩展。微内核的架构本质就是将变化部分封装在插件里面,从而达到快速灵活扩展的目的,而又不影响整体系统的稳定。
设计关键点
微内核的核心系统设计的关键技术有:插件管理、插件连接和插件通信。
OSGi 架构简析
OSGi 的全称是 Open Services Gateway initiative,本身其实是指 OSGi Alliance。现在我们谈到 OSGi,如果没有特别说明,一般都是指 OSGi 的规范。
OSGi 框架的逻辑架构图如下:
规则引擎架构简析
规则引擎从结构上来看也属于微内核架构的一种具体实现,其中执行引擎可以看作是微内核,执行引擎解析配置好的业务流,执行其中的条件和规则,通过这种方式来支持业务的灵活多变。
例如电商促销,常见的促销规则,规则引擎却能够很灵活的应对这种需求,主要原因在于: