热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

架构的变迁,从分层架构先聊起

架构,的,变迁,从,分
摘要:分层架构简单而高效,业界已经有很多成熟的应用,对那些项目刚刚起步,架构师们还没想好要采用哪种架构模式的系统而言,这是非常适合的。

前言

软件刚出现的时候,还是大型计算机的年代,一个软件系统一般都只会运行在一台机器上。随着软硬件技术的革新,计算机体积和成本逐渐变小,此时工程师们发现一个软件系统只运行在单台机器上会存在各种瓶颈。如果将系统按照功能划分成前端和后端,分别部署在两台服务器上,问题得到了缓解,于是便有了Client/Server架构的出现。

随后,个人电脑的兴起带动了众多富桌面应用(rich desktop application)的出现,它们基于操作系统上的user interface开发,数据则是存储在单独部署的database server上,通过标准的网络协议进行数据通信。这种Desktop + Database Server的架构和C/S架构一样,同属两层架构(two-tier architecture)。

随着90年代互联网的迅速崛起,Browser + Web Server + Database Server的组合也渐渐风靡。Browser为表现层,提供用户交互界面;Web Server为业务层,处理具体的业务逻辑;Database Server为数据层,存储系统数据。三个层次各司其职,这也是大家最熟悉的三层架构(three-tier architecture)。

上述的几种架构模式都属于分层架构(layered architecture)的范畴,分层架构并没有限定一定得有多少个层次,层次的数量可以根据应用场景灵活控制,因此也被称为n-tier architecture。它结构简单,基于此架构进行系统开发成本也很低(很多公司在组织结构上划分为前端工程师、后端工程师、DBA,根据康威定律,这天然就具备了分层架构开发的良好条件),因此它在业界备受欢迎。如果你的团队还不确定选择什么样的架构,又或者为了践行敏捷宣言中的“just starts coding“,那么分层架构会是一个不错的选择

架构视图

在分层架构中,组件根据功能被划分在不同的层次上,虽然层次的数量和类型并没有被限制,但大多数的分层架构都由以下4层组成:表现层(presentation)、业务层(business)、持久层(persistence)和数据层(database),如下图所示。在一些简单的系统中,持久层的逻辑(如SQL)被嵌入到业务层中,形成了经典的三层架构;而在一些复杂的系统中,也会根据具体的业务划分为五层甚至更多的层次。

分层架构的标准逻辑分层

前文所述的表现层等4个层次都是逻辑的划分方法,在实际部署时,一般会有下图所示的几种部署形态。形态1中,表现层、业务层和持久层为一个部署单元,而数据层则单独部署,具体表现为一个独立部署的数据库或文件系统;形态2中,表现层被分离出单独部署,业务层和持久层组成一个部署单元,数据层依旧是单独部署的数据库或文件系统;形态3中,包括数据层在内的4层全都在同一个部署单元内,常见于业务简单的系统,它们往往使用的是嵌入式数据库或内存数据库。

分层架构的部署形态

分层架构中的每一层都扮演着各自的角色,比如表现层负责处理所有的用户请求和浏览器交互,而业务层则负责执行每次请求下的特定业务逻辑;表现层无需担心从哪里获取用户数据,它只需要将数据以特定的格式在浏览器上显示即可。同样地,业务层也无需关心用户数据从何而来以及如何呈现,它只需从持久层中取出数据,执行特定的业务逻辑(比如聚合数据),然后将结果返回给表现层。

每一层都是特定行为的抽象,这样的职责划分,使得组织能够快速高效地创建出责任模型,围绕各层打造开发团队

层间隔离

分层架构中的每一层可以是封闭的或者开放的,封闭意味着当一个请求自顶向下在层间传递时,它不能跳过任意的一层。比如,当表现层接收到请求之后,它必须先后经过业务层和持久层才能到达数据层,如下图所示。

封闭的分层架构

对于简单的数据获取类请求,如果让表现层能够直接访问数据层获取数据,无疑是最简单高效的。也即是让业务层和持久层变成开放状态,允许请求在层间传递时跳过此层。那么,究竟是封闭好,还是开放好呢?要解答这个问题,就要回到层间隔离的出发点上。

所谓的层间隔离,旨在降低一个层次上的变化对其他层次的组件的影响,简单来说,就是每个层次对其他层次的功能知道的越少越好。为了达到层间隔离的目的,就需要将每个层次置为封闭的状态。假设表现层能够直接访问持久层,那么持久层的变化将会直接影响到业务层和表现层,这加剧了层间的耦合,导致系统变化的代价高昂。

层间隔离可以降低层次变化对系统的影响,凡事没有绝对,在某些的场景,将特定的层次置为开放的状态也不失为一件好事。考虑以下例子,业务层中存在着一些共享组件承载着业务层公共的功能(比如日志类、审计类、日期和字符串工具类等)。现在有一项架构决策要求表现层不能直接访问这些共享组件,但矛盾的是,原则上表现层是可以直接访问业务层的,这种需要违反原则的决策将会很难落地。

业务层中的共享组件

一种解决方法是,新增一个服务层,该层包含了业务层的这些共享组件。因为业务层是关闭的状态,故表现层也就不能访问到这些共享组件了。然而,新增的服务层必须置为开放状态,否则业务层将无法直接访问持久层。新增一个服务层并置为开放状态,这样既落地了架构决策,也不会影响到原有的功能,一举两得。

在分层架构中新增一个层次

一些注意事项

在使用分层架构时,需要注意以下两点:

1、做好模块的划分

为分层架构做好模块划分主要是为后续的架构演进做好准备,比如在业务复杂到一定程度后演进为微服务架构时,各个模块可以很自然地演进为微服务。为此,应该避免出现类的继承层次过深的现象,这会导致代码严重的耦合,不利于后续的架构演进。

2、避免掉进sinkhole反模式的陷阱

所谓sinkhole反模式指的是请求只是简单地路过各个层次,并没有做一些业务处理。

比如,表现层接收到一个获取基本用户数据(姓名、地址等)的请求后将它传递到业务层;然而,业务层并没有做任何的业务处理,直接将请求传递到持久层;持久层也仅仅是构造了一个简单的SQL语句,向数据层查询用户数据;最后,数据按照原路返回到表现层,中途没有经过任何的数据汇聚、转换等操作。

sinkhole反模式会导致很多不必要的对象实例化开销,从而增大了系统的内存消耗,并且影响了性能

然而,一个系统多多少少都会存在一些sinkhole反模式场景,要判断一个系统是否已经彻底掉进sinkhole反模式的陷阱,主要还是看这类业务请求所占的百分比。根据20-80法则,当系统中有超过80%的业务请求是sinkhole类请求时,表示系统已经掉进sinkhole反模式的陷阱,这从侧面也说明该系统已经不再适合分层架构,是时候考虑架构演进了。

综合得分

 

分层架构的综合得分

从综合得分上看,分层架构的Overall cost和Simplicity得分很高,这很大程度上得益于分层架构本身是单体架构,少了很多分布式系统才有的复杂性。但这样导致Deployability得分很低,因为3行代码的改动就足以造成整个系统的重新部署。Testability得分不高也是这个原因,整系统的重新上线通常都需要将测试用例全部执行一遍,多了不少额外的工作量。

Elasticity、Fault tolerance、Scalability这些都是单体架构天然的劣势,自然地,分层架构在这些方面得分都很低。另外,sinkhole反模式的存在也拉低了分层架构在Performance上的得分。

总结

分层架构简单而高效,业界已经有很多成熟的应用,对那些项目刚刚起步,架构师们还没想好要采用哪种架构模式的系统而言,这是非常适合的。在实现分层架构时,我们需要合理地设置各个层次的封闭或开放状态,做好层间隔离,同时也要避免掉进sinkhole反模式陷阱。随着业务的不断扩张,分层架构在可维护性、可测试性、可扩展性等上的短板也会逐步被放大,此时就需要考虑往其他架构模式演进了。

 

点击关注,第一时间了解华为云新鲜技术~


推荐阅读
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
  • 本文介绍了sqlserver云存储和本地存储的区别,云存储是将数据存储在网络上,方便查看和调用;本地存储是将数据存储在电脑磁盘上,只能在存储的电脑上查看。同时提供了几种启动sqlserver的方法。此外,还介绍了如何导出数据库的步骤和工具。 ... [详细]
  • 本文介绍了自动化测试专家Elfriede Dustin在2008年的文章中讨论了自动化测试项目失败的原因。同时,引用了IDT在2007年进行的一次软件自动化测试的研究调查结果,调查显示很多公司认为自动化测试很有用,但很少有公司成功实施。调查结果表明,缺乏资源是导致自动化测试失败的主要原因,其中37%的人认为缺乏时间。 ... [详细]
  • 浅解XXE与Portswigger Web Sec
    XXE与PortswiggerWebSec​相关链接:​博客园​安全脉搏​FreeBuf​XML的全称为XML外部实体注入,在学习的过程中发现有回显的XXE并不多,而 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • Tomcat/Jetty为何选择扩展线程池而不是使用JDK原生线程池?
    本文探讨了Tomcat和Jetty选择扩展线程池而不是使用JDK原生线程池的原因。通过比较IO密集型任务和CPU密集型任务的特点,解释了为何Tomcat和Jetty需要扩展线程池来提高并发度和任务处理速度。同时,介绍了JDK原生线程池的工作流程。 ... [详细]
  • 使用eclipse创建一个Java项目的步骤
    本文介绍了使用eclipse创建一个Java项目的步骤,包括启动eclipse、选择New Project命令、在对话框中输入项目名称等。同时还介绍了Java Settings对话框中的一些选项,以及如何修改Java程序的输出目录。 ... [详细]
  • 翻译 | 编写SVG的口袋指南(上)
    作者:DDU(沪江前端开发工程师)本文是原文翻译,转载请注明作者及出处。简介ScalableVectorGraphics(SVG)是在XML中描述二维图形的语言。这些图形由路径,图 ... [详细]
author-avatar
GRIROR格雷尔
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有