Java开发网站架构演变过程,到目前为止,大致分为5个阶段,分别为单体架构、集群架构、分布式架构、SOA架构和微服务架构。下面玄武老师来给大家详细介绍下这5种架构模式的发展背景、各自优缺点以及涉及到的一些技术,并且教会你如何区分它们。
第1阶段:单体架构
单体架构介绍
单体架构就是将所有的应用、数据库、文件都部署在一台机器上,俗称All-In-One。简单来讲其实就是我们熟知的SSH架构或SSM架构,把所有的业务模块都放在一个应用中开发,这里面又衍生出三层架构,即表示层、业务逻辑层和数据库访问层,虽然在软件设计中划分了经典的三层模型,但是对业务场景没有划分,一个典型的单体应用就是将所有的业务场景的表示层、业务逻辑层和数据访问层放在一个工程项目中,最终经过编译、打包,部署在一台服务器上。单体架构图如下:
单体架构优点
1)部署简单: 由于是完整的结构体,可以直接部署在一个服务器上即可。
2)技术单一: 项目不需要复杂的技术栈,往往一套熟悉的技术栈就可以完成开发。
3)用人成本低: 单个程序员可以完成业务接口到数据库的整个流程。
单体架构缺点
1)系统启动慢: 一个进程包含了所有的业务逻辑,涉及到的启动模块过多,导致系统的启动、重启时间周期过长;
2)系统错误隔离性差、可用性差:任何一个模块的错误均可能造成整个系统的宕机;
3)可伸缩性差:系统的扩容只能只对这个应用进行扩容,不能做到对某个功能点进行扩容;
4)线上问题修复周期长:任何一个线上问题修复需要对整个应用系统进行全面升级。
单体架构向集群架构过渡(1):应用和数据分离
随着公司业务的不断发展,由于单台服务器性能有限,逐渐无法满足业务需求,大量用户高并发的访问导致系统性能越来越差,数据存储空间开始出现不足,这时我们需要将应用和数据分离,分离后开始使用三台服务器:应用服务器、文件服务器、数据库服务器。如图:
应用和数据分离后,不同种类的服务器承担着不同的服务角色,网站的并发处理能力和数据存储空间都得到了很大的改善,支持网站业务进一步发展,但是随着用户量进一步增多,数据库压力依然越来越大,访问延迟不可避免,进而影响整个网站的性能,糟糕的用户体验使得系统需要进一步优化。
单体架构向集群架构过渡(2):缓存的使用
随着QPS持续提高,为了降低接口访问时间、提高服务性能和并发,我们注意到,网站访问有个著名的二八定律,即80%的业务集中访问在20%的数据上(热数据),其实部分数据有很多不需要每次都从数据库获取,比如经常被查询但对准确性要求并不是特别高的数据。如果我们将这一小部分热数据缓存在内存中,能够很好的减少数据库的访问压力,并大幅提升网站响应速度,因此网站就开始加入了缓存应用,常用的缓存组件有redis,ehcache等。
注意:能使用缓存的数据得满足如下要求:
1)对于数据实时性要求不高
对于一些经常访问但是很少改变的数据,查询明显多于修改,适用缓存就很有必要,比如一些网站配置项。
2)对于性能要求高
比如一些秒杀活动场景。
第2阶段:集群架构
缓存在一定程度上解决了数据库访问量比较大的问题,但仍无法解决随着业务增多造成的服务器并发压力大的问题,因为单台服务器的计算能力有限,应用程序运行速度就有限,因此这时想要突破服务器性能的瓶颈,最直接的办法就是增加一台甚至多台应用服务器来分担原来服务器的访问压力和存储压力,多台应用服务器之间没有直接的交互,他们都是依赖数据库各自对外提供服务。注意,这里的多台应用服务器部署的都是同一套应用程序(即同一套项目源码或war包),这就是集群架构,结构如图:
思考:系统演变到这里,将会出现下面四个问题(不做具体展开):
1)用户的请求由谁来转发到到具体的应用服务器
2)有什么转发的算法
3)应用服务器如何返回用户的请求
4)用户如果每次访问到的服务器不一样,那么如何维护session的一致性
这时候,你会发现图中多了一个名为负载均衡器的代理服务器,通常我们使用Nginx来实现,它的作用主要就是用户不需要记住两个甚至多个应用服务器的IP或域名,只要记住一台代理服务器IP就可以了。由代理服务器来负责分发用户是访问哪个应用服务器,那么用户具体是访问服务器1、访问服务器2还是服务器N,由Nginx里面的权重设置来决定的,并且通过Nginx的配置,Session共享也可以附带实现,保证多台应用服务器的Session一致性。另外,这样做还有一个好处就是将代理服务器放在外网,应用服务器均放在内网,可以有效防止应用服务器被恶意攻击。
集群架构演变(1):数据库读写分离
系统正常运行了一段时间后,虽然加有缓存,使绝大多数的数据库操作可以不通过数据库就能完成,但是仍然有一部分的数据库操作(缓存访问不命中或缓存过期)和全部的写操作需要访问数据库,当用户规模再一步增长后,数据库因为负载压力过大还是会成为系统性能的瓶颈,这时主流的数据库都提供的有主从热备份功能,通过配置两台数据库实现主从关系,可以将一台数据库服务器的数据更新同步到另一台服务器上。可以利用这一功能来实现数据库读写分离,从而改善数据库的负载压力,如图:
在图中我们可以发现主数据库服务器负责写操作,而从服务器负责读操作,这样数据库的压力就被分散在两台服务器上,而我们只需保证主从数据库的数据一致性即可,这里说明下Mysql的读写分离可以通过自身自带的从主复制实现,Oracle数据库可以通过阿里巴巴的mycat组件来实现。
概念补充:
1)负载:是指将请求负载到不同的服务器;
2)均衡:指的是平分服务器的请求次数。
3)热备份:指的是它可以在不停止数据库运行的情况下,自动的根据定时任务或者数量容量大小去备份数据库。
集群架构演变(2):反向代理和CDN加速
为了应对复杂的网络环境和不同地区用户的访问(比如你的服务器在美国或新加坡,国内用户直接访问可能会很卡),保障各个地区的用户都能流畅地访问系统,可以通过CDN和反向代理来加快用户访问的速度,同时减轻后端服务器的负载压力。CDN与反向代理的基本原理其实本质上都是缓存。CDN部署在网络提供商的机房,用户请求到来的时候从距离自己最近的网络提供商机房获取数据,而反向代理则部署在网站的中心机房中,请求带来的时候先去反向代理服务器中查看请求资源,如果有则直接返回。结构如图:
第3阶段:分布式架构
分布式架构的演变涉及分布式文件、分布式数据库、NoSql、搜索引擎以及业务模块的拆分,下面我们一个个看。
分布式架构演变(1):分布式文件和分布式数据库
即使性能再强大的单台服务器也无法满足大型网站持续增长的业务需求,数据库经过读写分离后,数据库服务器从一台拆分成了两台,但是随着业务的飞速增长依然会达到性能瓶颈,这时我们需要使用分布式数据库,同时文件系统也一样,需要使用分布式文件系统。
分布式数据库是数据库拆分的最后的手段,只有在表单数据规模非常庞大的时候才使用,不到不得已时,我们更常用的手段是业务分库,将不同的业务数据部署在不同的物理服务器上。结构如图:
分布式架构演变(2):NoSql和搜索引擎
随着业务越来越复杂,系统对数据存储和检索的需求也跟着复杂化,这时一些NoSQL(Reids,HBase,mongodb)数据库技术和搜索引擎(Solr,Elasticsearch)的时候就显得很有必要。数据库做读库的时候,往往对模糊查询显得力不从心,即使做了读写分离,这个问题还未能解决。以我们电商网站为例,发布的商品存储在数据库中,用户最常使用的功能就是查找商品,尤其是根据商品的标题来查找对应的商品。对于这种需求,一般我们都是通过like功能来实现的,但是这种方式的代价非常大。此时我们可以使用搜索引擎的倒排索引来完成。
搜索引擎能够大大提高查询速度,但系统引入搜索引擎后也会带来以下的开销:
1)带来大量的维护工作,我们需要自己实现索引的构建过程,设计全量/增加的构建方式来应对非实时与实时的查询需求。
2)需要维护搜索引擎集群
3)搜索引擎并不能替代数据库,他解决了某些场景下的“读”的问题,是否引入搜索引擎,需要综合考虑整个系统的需求。
结构如下图:
NoSQL和搜索引擎对可伸缩的分布式特性具有更好的支持,应用服务器通过一个统一的数据访问模块访问各种数据,减轻应用程序管理诸多数据源的麻烦。
分布式架构演变(3):业务模块拆分成子项目
当访问量达到一定规模的时候我们可以通过分而治之的手段将整个系统的业务分成不同的产品线,例如我们将系统的首页,商铺,订单,买家,卖家,支付,订单等模块拆分成不同的产品线,每个产品线都独立成一个子项目,每个子项目都有自己的独立的数据库,子项目之间通过RPC框架(dubbo,webService,httpClient…)建立连接通信,也可以通过消息队列实现异步分发处理,从而构成一个完整的系统,结构如下图:
第4阶段:SOA架构
SOA是什么?SOA全英文是Service-Oriented Architecture,意为面向服务编程,也称为服务治理,是一种思想,一种方法论,一种分布式的服务架构,这里的服务可以理解为service层业务服务,它将共同的业务逻辑拆分成独立的应用进行部署,这些应用没有视图层,只对外提供RPC调用接口。
注意区分项目与服务概念:
项目表达的意思:包含业务逻辑层和视图层
服务表达的意思是:只包含业务逻辑层,没有视图层
SOA 系统原型的一个典型例子是 CORBA,它已经出现很长时间,其定义的概念与 SOA 相似。SOA 建立在 XML 等新技术的基础上,通过使用基于 XML 的语言来描述接口,服务已经转到更动态且更灵活的接口系统中,CORBA 中的 IDL 无法与之相比。如图描述了一个完整的 SOA 模型。
在 SOA 模型中,所有的功能都定义成了独立的服务。服务之间通过交互和协调完成业务的整体逻辑。所有的服务通过服务总线或流程管理器来连接。这种松散耦合的架构使得各服务在交互过程中无需考虑双方的内部实现细节,以及部署在什么平台上。一个独立的服务基本结构如图所示:
服务模型的表示层从逻辑层分离出来,中间增加了服务对外的接口层。通过服务接口的标准化描述,使得服务可以提供给在任何异构平台和任何用户接口使用。这允许并支持基于服务的系统成为松散耦合、面向构件和跨技术实现,服务请求者很可能根本不知道服务在哪里运行、是由哪种语言编写的,以及消息的传输路径,而是只需要提出服务请求,然后就会得到答案。举个例子:
通过上面的图我们可以看出,多个子系统直接相互交互,相互调用非常凌乱,这样我们就很不爽,所以我们就用到了我们的SOA架构,SOA又叫服务治理,SOA就是帮助我们把服务之间调用的乱七八糟的关系给治理起来,然后提供一个统一的标准,把我们的服务治理成下图所示,以前我们的服务是互相交互,现在是只对数据总线进行交互,这样系统就变得统一起来。
各个系统分别根据统一标准向数据总线进行注册,各子系统调用其他子系统时,我们并不关心如何找到其他子系统,我们只找数据总线,数据总线再根据统一标准找其他子系统,所以数据总线在这里充当一个指路人的作用。
SOA的特点:
1)系统集成:站在系统的角度,解决企业系统间的通信问 题,把原先散乱、无规划的系统间的网状结构,梳理成 规整、可治理的系统间星形结构,这一步往往需要引入 一些产品,比如 ESB、以及技术规范、服务管理规范; 这一步解决的核心问题是【有序】
2)系统的服务化:站在功能的角度,把业务逻辑抽象成 可复用、可组装的服务,通过服务的编排实现业务的 快速再生,目的:把原先固有的业务功能转变为通用 的业务服务,实现业务逻辑的快速复用;这一步解决 的核心问题是【复用】
3)业务的服务化:站在企业的角度,把企业职能抽象成 可复用、可组装的服务;把原先职能化的企业架构转变为服务化的企业架构,进一步提升企业的对外服务能力;“前面两步都是从技术层面来解决系统调用、系统功能复用的问题”。第三步,则是以业务驱动把一个业务单元封装成一项服务。这一步解决的核心问题是【高效】
SOA的优点:
1)降低用户成本,用户不需要关心各服务之间是什么语言的、不需要知道如果调用他们,只要通过统一标准找数据总线就可以了。
2)程序之间关系服务简单
3)识别哪些程序有问题(挂掉)
SOA的缺点:
提示了系统的复杂程度,性能有相应影响。
第5阶段:微服务架构
随着业务拆分越来越小,存储系统越来越庞大,应用系统的整体复杂度呈指数级增加,部署维护越来越困难,由于所有应用要和所有数据库系统连接,最终导致数据库连接资源不足,拒绝服务。
1)当服务越来越多时,服务URL配置管理变得非常困难,F5硬件负载均衡器的单点压力也越来越大。
2)当进一步发展,服务间依赖关系变得错踪复杂,甚至分不清哪个应用要在哪个应用之前启动,架构师都不能完整的描述应用的架构关系。
3)接着,服务的调用量越来越大,服务的容量问题就暴露出来,这个服务需要多少机器支撑?什么时候该加机器?
4)服务多了,沟通成本也开始上升,调某个服务失败该找谁?服务的参数都有什么约定?
5)一个服务有多个业务消费者,如何确保服务质量?
6)随着服务的不停升级,总有些意想不到的事发生,比如cache写错了导致内存溢出,故障不可避免,每次核心服务一挂,影响一大片,人心慌慌,如何7)控制故障的影响面?服务是否可以功能降级?或者资源劣化?
解决方案:公共的应用模块被提取出来,部署在分布式服务器上供应用服务器调用。也就是我们所说的分布式服务或者微服务。
微服务架构是一种架构概念,核心思想在于通过将业务功能和需求分解到各个不同的服务中进行管理,实现对业务整体解耦。围绕业务模式创建应用服务,应用服务可独立地进行开发、迭代、部署,使项目的架构更加清晰明确。目前主流的微服务架构框架就是SpringCloud。
以下是一个微服务案例的架构图:
微服务优点
1)每个服务足够内聚,足够小,代码容易理解、开发效率提高;
2)服务之间可以独立部署,微服务架构让持续部署成为可能;
3)每个服务可以各自进行负载均衡扩展和数据库扩展,而且,每个服务可以根据自己的需要部署到合适的硬件服务器上;
4)容易扩大开发团队,可以针对每个服务(service)组件开发团队;
5)提高容错性(fault isolation),一个服务的内存泄露并不会让整个系统瘫痪;
6)系统不会被长期限制在某个技术栈上。
微服务缺点
1)开发人员要处理分布式系统的复杂性;
2)开发人员要设计服务之间的通信机制,对于需要多个后端服务的user case,要在没有分布式事务的情况下实现代码非常困难;
3)涉及多个服务直接的自动化测试也具备相当的挑战性;
4)服务管理的复杂性,在生产环境中要管理多个不同的服务的实例,这意味着开发团队需要全局统筹(PS:现在docker的出现适合解决这个问题);
总结:架构之间的区别
1)单体架构很好区分,只要看所有应用程序、文件系统、数据库等是否都在一个服务器上
2)集群架构,其实就是将原先的单体架构中的应用程序分别部署在多台应用服务器上,不过他们还是公用一个数据库。
3)分布式架构,将原先的单体架构中的项目按照功能模块拆分成多个单独的子项目,分别部署在不同的应用服务器,并且每个子项目都有自己的独立的数据库。
4)SOA架构与微服务架构的区别:
首先SOA和微服务架构一个层面的东西,而对于ESB和微服务网关是一个层面的东西,一个谈到是架构风格和方法,一个谈的是实现工具或组件。
(Service Oriented Architecture)“面向服务的架构”:他是一种设计方法,其中包含多个服务, 服务之间通过相互依赖最终提供一系列的功能。一个服务 通常以独立的形式存在与操作系统进程中。各个服务之间 通过网络调用。
2.微服务架构:其实和 SOA 架构类似,微服务是在 SOA 上做的升华,微服务架构强调的一个重点是“业务需要彻底的组件化和服务化”,原有的单个业务系统会拆分为多个可以独立开发、设计、运行的小应用。这些小应用之间通过服务完成交互和集成。
微服务架构 = 80%的SOA服务架构思想 + 100%的组件化架构思想 + 80%的领域建模思想