1.单体应用框架
1.1.什么是单体架构
简单来说,我们以前传统的应用就是单体架构,即所有的模块,组件等都在一个应用中,应用最终打包成一个(jar,war)包,使用一个容器(tomcat)进行部署,通常一个应用享用一个数据库。在单体应用中我们通常把应用分为三个组成部分:持久层,业务层,表现层,这样的应用结构在项目初期业务较少的情况下没有任何问题,但是随着业务需求不断的增加要求单体应用中的业务逻辑,业务组件等日益扩张,应用将会变得越来越臃肿,往后的开发和维护就会变得特别麻烦,再加上越来越大访的问量,并发越来越高,面对海量的用户无论从应用性能还是从数据库方面都有吃不消的时候。所以单体应用在数据量,并发量到一定程度的时候一定会遇到瓶颈。如下图:
1.2.单体架构的优缺点
当然单体应用在项目初期也有很多优势,主要有如下表现:
易于开发 :架构简单,技术成本低
易于测试 :所有功能在一个项目,方便测试
易于部署 :一个Tomcat就可以实现部署,简单方便
随着项目规模日益变大,我们可以采用集群的手段来出来解决高并发,但包含了所有组成部分的单体应用终归是有许多不足,主要缺点如下:
代码臃肿不方便开发维护(代码可读性差)
代码编译系统启动变慢
系统扩展性能变差(牵一发而动全身)
无法针对某一个业务做扩展(集群)
对大数据量,高并发量的处理不占优势
技术选型单一
模块/业务耦合度高
1.3.单体应用与集群
在单体架构中,为了提高应用的并发作业能力和防止应用的单节点故障,我们通常会对应用做集群,这里的集群是指把应用进行复制多个相同的应用一起工作来提高作业能力,多个应用做的是相同的事情,就像我们在银行进行存钱服务,一个银行业务员不足以支持大量的储户的存取款流程,因此多个业务台同时进行工作,这就是集群。
当我们的应用做了集群,那么就会存在多个应用节点,多个应用将会暴露多个访问地址(ip:port),那客户端是不知道该访问哪个应用节点的,这个时候我们就需要有一个请求分发的功能的组件(负载均衡器)将客户端的请求相对平均的分发多个应用节点上,这就是负载均衡,这个做请求分发的组件就是负载均衡器,如下图:
这里的Nginx就是一个负载均衡器,它可以按照某种算法(轮询,ip_hash等等)将请求路由到不同的后端服务器上,同类型的负载均衡器如“HAproxy”,“LVS”等,这里不展开讨论。负载均衡算法如:轮询,随机,权重等等...
总之,当我们的单体应用没办法支撑较高的并发请求时,我们可以对应用做集群,同时加入负载均衡器来提升应用的作业能力,甚至我们也可以在数据库层也做集群(如主从复制),这样的架构有一定的并发处理能力,也能满足一定的复杂业务需求,但是就应用本身而言任然是单体结构,仍然有其不足之处,如:
项目本身任然是单体,代码依然臃肿
面对海量数据数据库会成为性能瓶颈(需要分库分表)
持续交互能力差,代码臃肿,业务复杂,开发维护时间长,新人入手成本高。
所以当单体应用不能满足复杂的业务和海量数据的系统时,我们需要考虑其他的架构方式。
2. 分布式与SOA
2.1.分布式架构
我们知道,单体应用包含了整个项目的所有代码和服务逻辑,也就是说一个Tomcat需要把整个系统跑起来,那么Tomcat总有处理不过来的时候,我们是否可以为Tomcat减轻一些压力呢?当然可以。我们拿生活中的案例“厨师炒菜”,来说,当饭店规模小的时候我们一个厨师就可以完成所有厨房的工作如“洗菜”,“切菜”,“炒菜”三件事情,当饭店规模增加,一个厨师就忙不过来,这个时候可能要再招聘两个厨师,然后进行分工,厨师A负责洗菜,厨师B负责切菜,厨师C负责炒菜,这样一来每个厨师的压力减轻,并且每个厨师就只需要专注一件事情即可。
将上面的案例映射到我们的应用程序中也是一样的道理,当一个Tomcat负担不起系统中的所有业务的时候,我们可以按照业务把应用进行拆分成多个小的应用,每个小应用都用一个Tomcat去运行,每个小应用都是单体架构,每个应用只需要关系自己的业务即可,应用之间通过API相互调用,如图:
当然如果某个子系统压力依然很大,可以单独对该子系统再做集群,所以分布式和集群并不冲突。
总结一下什么是分布式 :分布式就是将应用按照业务进行拆分成多个子应用,多个子应用部署在不同的服务器中,多个子应用组成一个完整的系统,所有的子系统一起工作相互通信相互协调才能完成最终的业务流程,缺一不可,简单理解:“多个人在一起做不同的事情,多人和在一起才是一件完整的事情,有点0.5+0.5=1的感觉”。
2.2.面向服务的架构SOA
SOA是面向服务的架构,它的思想是每个子应用可以通过网络通信协议向其他子应用提供服务或者消费服务,SOA也是分布式架构,我们可以简单的理解为SOA把分布式架构划分成表示层和服务层,服务层中包含了业务逻辑和相关流程,只需要对外暴露服务即可,表现层负责处理和页面的交互。这样的划分好处在于系统之间调用的方便性,如用户子系统只需要调用订单子系统的服务层即可完成应用之间的通信。这样的结构划分提高了应用的重用性,业务逻辑也变得可组合。如图:
SOA架构中有重要的两个角色,服务消费者(Consumer)和服务提供者(Provider)即服务调用者和服务被调用者,这样的架构优点有:
- 模块拆分,使用API通信,降低模块之间的耦合度
- 项目拆分多个子应用,每个子应用业务简单,代码简单,方便维护开发。
- 不同技术人员可以负责不同的子应用
- 提高服务之间的重用性,业务逻辑可组合。
其缺点在于:
- 服务之间的API接口开发增加了工作量,
- SOA服务之间的网络通信调用对性能有一定的影响(尽管很小)
- 相对于单体应用来说,技术,人力成本较高。
- 部署和运维相对麻烦
3.微服务架构
3.1.什么是微服务
微服务架构可以认为是在SOA架构上的一种发展,最早由“Martin Fowler”提出:就目前而言,对于微服务业界并没有一个统一的、标准的定义(While there is no precise definition of this architectural style ) 。但通常而言,微服务架构是一种架构模式或者说是一种架构风格,它提倡将单一应用程序划分成一组小的服务,每个服务运行独立的自己的进程中,服务之间互相协调、互相配合,为用户提供最终价值。服务之间采用轻量级的通信机制互相沟通(通常是基于 HTTP 的 RESTFUL API ) 。每个服务都围绕着具体业务进行构建,并且能够被独立地部署到生产环境、类生产环境等。另外,应尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建,可以有一个非常轻量级的集中式管理来协调这些服务。可以使用不同的语言来编写服务,也可以使用不同的数据存储。
我们从这段描述中可以看出,微服务架构和SOA架构很像,总体来说,微服务就是把单一应用进行细粒度的拆分成多个小(微)的服务相,每个服务独立运行,每个服务只需要专注一个业务即可,并且每个服务都可以有自己的数据库(分库),服务之间互协调配合完成整个系统的业务,我们用一个图来理解微服务架构:
我们总结一下微服务有如下的特点 :
由多个服务组成完整的系统
每个服务都是独立的,有自己的进程
服务之间使用HTTP协议通信
不同的服务可以使用不同的编程语言
不同的服务的数据库可以多样化选择
微服务是一个分布式系统
3.2. 微服务的优缺点
在项目规模较大的时候,相对于单体应用来说,微服务具备很多优势,主要体现在如下方面:
单个服务业务简单,代码简单方便开发维护
服务之间无耦合,服务之间升级维护互不影响
轻量级HTTP通信机制,使得的不同的服务可以采用不同的编程语言
微服务有极强的扩展能力,业务量大的服务可以再次拆分服务,也可以进行集群部署,剔除服务也很方便
更大的系统负载能力和容错能力(集群)
对于开发人员来说,通常只需要关注单一服务,新员工上手也比较快
微服务架构对现在流行的敏捷开发支持优化
凡是都有双面性,微服务展示出了他都优势之处,同时也有其不足的地方,主要体现如下方面:
分布式事务 :服务通信机制增加了事务的复杂性,架构师要选择合适的分布式方案(CAP理论)
部署麻烦 :微服务众多,部署麻烦,需要借助容器技术和自动化部署工具,这又增加了开发人员的学习成本。
技术成本高 :微服务架构本身比较复杂,技术成本高,开发人员需要花更多的时间学习相关技术。
服务通信对性能的损耗 : 微服务架构一定要考虑服务通信延迟对服务调用性能的损耗问题,开发人员需要选择合适的通信方式解决这一问题。
3.3.如何选型
虽然微服务有诸多好处,但是不是任何系统都适合用微服务架构来开发,在项目规模不大的情况下单体应用性能表现良好,当项目规模较大,用户体量,并发较大的时候,微服务总体性能占优势,所以我们应该根据项目类型以及项目规模来决定应用架构的选型,如大型电商,物流,售票等系统我们可以选择使用微服务架构,对于中小型的企业级应用我们依然可以选择单体架构。
总结:中小型项目选择单体 ,大型项目选择微服务。