[架构之路-106]:《软件架构设计:程序员向架构师转型必备》-16-常见的十余种软件分层架构

Posted 文火冰糖的硅基工坊

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[架构之路-106]:《软件架构设计:程序员向架构师转型必备》-16-常见的十余种软件分层架构相关的知识,希望对你有一定的参考价值。

1. 软件架构体系

1.1. 系统与子系统

  • 系统:泛指由一群有关联的个体组成,根据某种规则运作,能完成个别元件不能单独完成的工作的群体

  • 关联:系统是由一群有关联的个体组成的,没有关联的个体堆在一起不能成为一个系统。例如,把一个汽车发动机和一堆苹果放在一起不能称之为一个系统,把发动机、底盘、轮胎、车架组合起来才能成为一台汽车,构成一个系统。

  • 规则:系统内的个体需要按照指定的规则运作,而不是单个个体各自为政。规则规定了系统内个体分工和协作的方式。例如,汽车发动机负责产生动力,然后通过变速器和传动轴,将动力输出到车轮上,从而驱动汽车前进。

  • 能力:系统能力与个体能力有本质的差别,系统能力不是个体能力之和,而是产生了新的能力。例如,汽车能够载重前进,而发动机、变速器、传动轴、车轮本身都不具备这样的能力。

  • 子系统:子系统也是由一群有关联的个体所组成的系统,多半会是更大系统中的一部分。子系统的定义和系统定义是一样的,只是观察的角度有差异,一个系统可能是另外一个更大系统的子系统。

以微信为例来做一个分析:

微信本身是一个系统,包含聊天、登录、支付、朋友圈等子系统。

朋友圈这个系统又包括动态、评论、点赞等子系统。

评论这个系统可能又包括防刷子系统、审核子系统、发布子系统、存储子系统。

评论审核子系统不再包含业务意义上的子系统,而是包括各个模块或者组件,这些模块或者组件本身也是另外一个维度上的系统。例如,mysql、Redis 等是存储系统,但不是业务子系统

1.2. 模块、组件、服务

  • 模块:是一套一致而互相有紧密关连的软件组织。它分别包含了程序和数据结构两部分。现代软件开发往往使用模块作为合成的单位

  • 组件:自包含的、可编程的、可重用的、与语言无关的软件单元,组件可以很容易被用于组装应用程序中

模块和组件都是系统的组成部分,只是从不同的角度拆分系统而已。例如:

从逻辑的角度来拆分系统后,得到的单元就是“模块” ;从物理的角度来拆分系统后,得到的单元就是“组件” 。

划分模块的主要目的是职责分离;划分组件的主要目的是单元复用。

例如我们要做一个学生信息管理系统,这个系统从逻辑的角度来拆分,可以分为:登录注册模块、个人信息模块、个人成绩模块;从物理的角度来拆分,可以拆分为应用程序、 nginx、Web 服务器、MySQL等

  • 服务: 服务和组件有某种相似之处:它们都将被外部的应用程序使用。两者之间最大的差异在于:组件是在本地使用的(例如Jar文件);而服务是运行起来的,要通过同步或异步的远程接口来远程使用(例如RESTFul接口、web service、消息系统、RPC,或者socket)

服务是可以单独运行,并且对外提供功能的一种形式。可以将一个复杂的项目分解成多个服务。当某一个服务挂掉时不会拖垮整个系统。如果没有服务化,每当一个新的功能被添加到系统中就会影响到所有功能;如果采取服务化,每个服务只对其上下游的服务负责。

1.3. 软件架构体系

2. 架构原则

2.1. 解耦

在软件工程中,耦合指的就是对象之间的依赖性。对象之间的耦合度越高,维护成本越高。因此对象的设计应使类和构件之间的耦合最小。软件设计中通常用耦合度和内聚度作为衡量模块独立程度的标准。划分模块的一个准则就是高内聚低耦合。

耦合性存在于各个领域,而非软件设计中独有的,理论上说绝对的零耦合是做不到的,但可以通过一些方法将耦合降至最低,降低耦合度即可理解为解耦,在设计上解耦的核心思想是【彼此独立,互不依赖】。

2.2. 分层

分层结构是最为流行、应用最广泛的应用软件的设计方式。在应用了分层结构的系统中,各个子系统按照层次的形式组织起来,上层使用下层的各种服务,而下层对上层一无所知。每一层都对自己的上层隐藏其下层的细节。

2.3. 封装

假设我们有一个程序,它在逻辑上有一些不同的对象,并且这些对象彼此之间会相互交流。

在一个类中,当每个对象的状态保持相对孤立,就实现了封装。其余的对象并不能观察到这个对象的状态。他们能做到的只有调用一些被称作“方法”的通用功能。

因此,对象使用方法掌控着自己的状态,除非明确允许,没有其他人可以接触到它。如果你想和某个对象交流,你需要使用提供的方法。但在默认情况下,你无法改变对象的状态。

3. 常见的软件分层架构

经典三层架构:

在软件架构中,经典三层架构自顶向下由用户界面层、业务逻辑层、数据访问层组成。在提出该分层架构的时代,多数系统往往较为简单,本质上都是一个单体架构的数据库管理系统。这种分层架构有效地隔离了业务逻辑与数据访问逻辑,使得这两个不同关注点能够相对自由和独立地演化。经典的三层架构如下所示:

分层的设计原则是:保证同一层的组件处于同一个抽象层次。即所谓的“单一抽象层次原则”。这一原则可以运用到分层架构中。比如下图所示:

3.1 单机版/单体经典三分层应用程序架构

在软件架构中,经典三层架构自顶向下由用户界面层、业务逻辑层、数据访问层组成。在提出该分层架构的时代,多数系统往往较为简单,本质上都是一个单体架构的数据库管理系统。这种分层架构有效地隔离了业务逻辑与数据访问逻辑,使得这两个不同关注点能够相对自由和独立地演化。

经典的三层架构如下所示:

3.2 单机版/单体经典四分层应用程序架构

有时候,把数据库看成一个独立的层,经典的单体三层架构就演进程了经典四层架构

分层架构(layered architecture)是最常见的软件架构,也是事实上的标准架构。如果你不知道要用什么架构,那就用它。

这种架构将软件分成若干个水平层,每一层都有清晰的角色和分工,不需要知道其他层的细节。层与层之间通过接口通信。

虽然没有明确约定,软件一定要分成多少层,但是四层的结构最常见。

有的软件在逻辑层和持久层之间,加了一个服务层(service),提供不同业务逻辑需要的一些通用接口。

用户的请求将依次通过这四层的处理,不能跳过其中任何一层。

优点

  • 结构简单,容易理解和开发

  • 不同技能的程序员可以分工,负责不同的层,天然适合大多数软件公司的组织架构

  • 每一层都可以独立测试,其他层的接口通过模拟解决

缺点

  • 一旦环境变化,需要代码调整或增加功能时,通常比较麻烦和费时

  • 部署比较麻烦,即使只修改一个小地方,往往需要整个软件重新部署,不容易做持续发布

  • 软件升级时,可能需要整个服务暂停

  • 扩展性差。用户请求大量增加时,必须依次扩展每一层,由于每一层内部是耦合的,扩展会很困难

分层的设计原则是:

保证同一层的组件处于同一个抽象层次。即所谓的“单一抽象层次原则”。

这一原则可以运用到分层架构中。比如下图所示:

在上图中:

表现层:用户界面层

控制层:业务逻辑数据处理层、业务逻辑层等。

引擎层:数据持久化层就是该层。

基础层:数据库就处于该层。

3.3 单机版/单体交互式应用程序架构:MVC架构

MVC: Model-view-controller pattern

模型/视图/控制器模式(简称 MVC 模式)将交互式应用程序拆分为三个部分:

模型(model) – 包含核心功能及数据,业务处理逻辑

视图(view) – 呈现信息给用户,通过有多个不同的视图,呈现给不同的用户

控制器(controller) – 处理用户的输入操作

MVC 模式通过将内部信息表示、用户信息呈现以及用户操作接收分开的方式解耦组件,实现高效代码重用。

使用场景

主流开发语言所构建的互联网网页应用架构

DjangoRails网页应用开发框架

3.4 网络协议栈:ISO七层协议架构

七层模型,亦称OSI(Open System Interconnection)。参考模型是国际标准化组织(ISO)制定的一个用于计算机通信系统间互联的标准体系,一般称为OSI参考模型或七层模型。

它是一个七层的、抽象的模型体,不仅包括一系列抽象的术语或概念,也包括具体的协议。

应用层

网络服务与最终用户的一个接口。

协议有:HTTP FTP TFTP SMTP SNMP DNS TELNET HTTPS POP3 DHCP

表示层

数据的表示、安全、压缩。(在五层模型里面已经合并到了应用层)

格式有,JPEG、ASCll、EBCDIC、加密格式等 [2]

会话层

建立、管理、终止会话。(在五层模型里面已经合并到了应用层)

对应主机进程,指本地主机与远程主机正在进行的会话

传输层

定义传输数据的协议端口号,以及流控和差错校验。

协议有:TCP UDP,数据包一旦离开网卡即进入网络传输层

网络层

进行逻辑地址寻址,实现不同网络之间的路径选择。

协议有:ICMP IGMP IP(IPV4 IPV6)

数据链路层

建立逻辑连接、进行硬件地址寻址、差错校验 [3] 等功能。(由底层网络定义协议)

将比特组合成字节进而组合成帧,用MAC地址访问介质,错误发现但不能纠正。

物理层

建立、维护、断开物理连接。(由底层网络定义协议)

3.5 网络协议栈:TCP/IP 四层协议架构

不同人员关注的模型不一样:

对于大众人员会更关注四层模型,因为物理层和数据链路层都是跟网卡和物理线路有关,会话层、表示层、应用层都属于上层制定协议规则的人员决定。

对于网络设备公司,可能更关注五层协议,因为他们生产的设备要明确区分物理层和数据链路层,物理设备更关注数据的传输,相对不太关注应用层协议定制。

对于制定应用层协议的人员,就要更关注七层协议,选择TCP还是UDP,数据的加解密方式,压缩格式等,SSH、HTTPS这些协议的,就要关注并区分会话层、表示层、应用层负责处理哪些功能。

3.6 网络架构:客户端/服务器模式: CS架构

3.6.1 概述

CS: Client-server pattern

cs架构是客户端/服务器体系结构,其中客户端依靠服务器来获取资源。

C/S架构全称为客户端/服务器体系结构,它是一种网络体系结构,其中客户端是用户运行应用程序的PC端或者工作站,客户端要依靠服务器来获取资源。C/S架构是通过提供查询响应而不是总文件传输来减少了网络流量。它允许多用户通过GUI前端更新到共享数据库,在客户端和服务器之间通信一般采用远程调用(RPC)或标准查询语言(SQL)语句。

客户端/服务器模式由两个部分构成:

一个服务器与多个客户端。服务器组件同时为多个客户端组件提供服务。

客户端向服务器发启服务请求,

服务器将相应服务信息回应给客户端。

此外,服务器持续监听来自客户端的请求。

使用场景

电子邮件、文件共享及银行业务等在线应用

3.6.2 多层模型

3.7 网络架构:浏览器/服务器模式: BS架构

3.7.1 概述

B/S(Brower/Server,浏览器/服务器)模式又称B/S结构,是Web兴起后的一种网络结构模式。Web浏览器是客户端最主要的应用软件。

这种模式统一了客户端,将系统功能实现的核心部分集中到服务器上,简化了系统的开发、维护和使用;

客户机上只需要安装一个浏览器,服务器上安装SQL Server, Oracle, MySql等数据库;浏览器通过Web Server同数据库进行数据交互。  

B/S架构采取浏览器请求,服务器响应的工作模式。

用户可以通过浏览器去访问Internet上由Web服务器产生的文本、数据、图片、动画、视频点播和声音等信息;

而每一个Web服务器又可以通过各种方式与数据库服务器连接,大量的数据实际存放在数据库服务器中;

从Web服务器上下载程序到本地来执行,在下载过程中若遇到与数据库有关的指令,由Web服务器交给数据库服务器来解释执行,并返回给Web服务器,Web服务器又返回给用户。在这种结构中,将许许多多的网连接到一块,形成一个巨大的网,即全球网。而各个企业可以在此结构的基础上建立自己的Internet。

一张图看懂B/S架构工作原理:

3.7.2 架构与原理

B/S 与C/S 的两层架构不同,它采取三层架构。只要有浏览器就可以打开,具体工作原理如下。

3.7.3 CS/BS区别

3.8 事件驱动架构

事件(event)是状态发生变化时,软件发出的通知。

事件驱动架构(event-driven architecture)就是通过事件进行通信的软件架构。

3.8.1 通用模型

它分成四个部分:

事件队列(event queue):接收事件的入口

分发器(Event mediator/Dispacher):将不同的事件分发到不同的业务逻辑单元

事件通道(Event channel):分发器与事件处理单元之间的联系渠道,该事件通道可以做成消息队列或者消息主题(message topics),或者两种的结合。

事件处理器(Event processor):实现业务逻辑,处理完成后会发出事件,触发下一步操作。

3.8.2 简化模型

对于简单的项目,事件队列、分发器和事件通道,可以合为一体,整个软件就分成:

事件代理和事件处理器两部分。

优点

分布式的异步架构,事件处理器之间高度解耦,软件的扩展性好

适用性广,各种类型的项目都可以用

性能较好,因为事件的异步本质,软件不易产生堵塞

事件处理器可以独立地加载和卸载,容易部署

缺点

涉及异步编程(要考虑远程通信、失去响应等情况),开发相对复杂

难以支持原子性操作,因为事件通过会涉及多个处理器,很难回滚

分布式和异步特性导致这个架构较难测试

3.9 微架构

微核架构(microkernel architecture)又称为"插件架构"(plug-in architecture),指的是软件的内核相对较小,主要功能和业务逻辑通过插件实现。

内核(core)通常只包含系统运行的最小功能。插件则是互相独立的,插件之间的通信,应该减少到最低,避免出现互相依赖的问题。

优点

良好的功能延伸性(extensibility),需要什么功能,开发一个插件即可

功能之间是隔离的,插件可以独立的加载和卸载,使得它比较容易部署,

可定制性高,适应不同的开发需要

可以渐进式地开发,逐步增加功能

缺点

扩展性(scalability)差,内核通常是一个独立单元,不容易做成分布式

开发难度相对较高,因为涉及到插件与内核的通信,以及内部的插件登记机制

Linux操作系统与内核驱动的关系,就是微核架构!!!

3.10 微服务架构

微服务架构(microservices architecture)是面向服务的架构(service-oriented architecture,缩写 SOA)的升级。

每一个服务就是一个独立的部署单元(separately deployed unit)。

这些单元都是分布式的,互相解耦,通过远程通信协议(比如REST、SOAP)联系。

微服务架构分成三种实现模式:

(1)RESTful API 模式:服务通过 API 提供,云服务就属于这一类

(2)RESTful 应用模式:服务通过传统的网络协议或者应用协议提供,背后通常是一个多功能的应用程序,常见于企业内部

(3)集中消息模式:采用消息代理(message broker),可以实现消息队列、负载均衡、统一日志和异常处理,缺点是会出现单点失败,消息代理可能要做成集群

优点

扩展性好,各个服务之间低耦合

容易部署,软件从单一可部署单元,被拆成了多个服务,每个服务都是可部署单元

容易开发,每个组件都可以进行持续集成式的开发,可以做到实时部署,不间断地升级

易于测试,可以单独测试每一个服务

缺点

由于强调互相独立和低耦合,服务可能会拆分得很细。这导致系统依赖大量的微服务,变得很凌乱和笨重,性能也会不佳。

一旦服务之间需要通信(即一个服务要用到另一个服务),整个架构就会变得复杂。典型的例子就是一些通用的 Utility 类,一种解决方案是把它们拷贝到每一个服务中去,用冗余换取架构的简单性。

分布式的本质使得这种架构很难实现原子性操作,交易回滚会比较困难。

3.11云架构

云结构(cloud architecture)主要解决扩展性并发的问题,是最容易扩展的架构

它的高扩展性,主要原因是没使用中央数据库,而是把数据都复制到内存中,变成可复制的内存数据单元。然后,业务处理能力封装成一个个处理单元(prcessing unit)。访问量增加,就新建处理单元;访问量减少,就关闭处理单元。由于没有中央数据库,所以扩展性的最大瓶颈消失了。

由于每个处理单元数据都在内存里,最好要进行数据持久化。

这个模式主要分成两部分:处理单元(processing unit)和虚拟中间件(virtualized middleware)。

处理单元:实现业务逻辑

虚拟中间件:负责通信、保持sessions、数据复制、分布式处理、处理单元的部署。

虚拟中间件又包含四个组件。

消息中间件(Messaging Grid):管理用户请求和session,当一个请求进来以后,决定分配给哪一个处理单元。

数据中间件(Data Grid):将数据复制到每一个处理单元,即数据同步。保证某个处理单元都得到同样的数据。

处理中间件(Processing Grid):可选,如果一个请求涉及不同类型的处理单元,该中间件负责协调处理单元

部署中间件(Deployment Manager):负责处理单元的启动和关闭,监控负载和响应时间,当负载增加,就新启动处理单元,负载减少,就关闭处理单元。

优点

高负载,高扩展性

动态部署

缺点

实现复杂,成本较高

主要适合网站类应用,不合适大量数据吞吐的大型数据库应用

较难测试

3.12 移动通信网络分层架构

3.12.1 网络分层架构

3.12.2 数据面协议栈

3.13 物联网网络封层

以上是关于[架构之路-106]:《软件架构设计:程序员向架构师转型必备》-16-常见的十余种软件分层架构的主要内容,如果未能解决你的问题,请参考以下文章

[架构之路-94]:《软件架构设计:程序员向架构师转型必备》-4-软件架构设计的通用过程

[架构之路-100]:《软件架构设计:程序员向架构师转型必备》-10-细化架构设计

[架构之路-92]:《软件架构设计:程序员向架构师转型必备》-2-解析软件架构的概念

[架构之路-92]:《软件架构设计:程序员向架构师转型必备》-2-解析软件架构的概念

[架构之路-101]:《软件架构设计:程序员向架构师转型必备》-11-原型设计与架构评估与提前验证

[架构之路-103]:《软件架构设计:程序员向架构师转型必备》-13-软件架构如何分层(四层架构)