八种架构设计模式及其优缺点.docx
《八种架构设计模式及其优缺点.docx》由会员分享,可在线阅读,更多相关《八种架构设计模式及其优缺点.docx(11页珍藏版)》请在冰豆网上搜索。
八种架构设计模式及其优缺点
八种架构设计模式及其优缺点
八种架构设计模式及其优缺点概述(上)
1.什么是架构
我想这个问题,十个人回答得有十一个答案,因为另外的那一个是大家妥协的结果。
哈哈,我理解,架构就是骨架,如下图所示:
人类的身体的支撑是主要由骨架来承担的,然后是其上的肌肉、神经、皮肤。
架构对于软件的重要性不亚于骨架对人类身体的重要性。
2.什么是设计模式
这个问题我问过的面试者不下于数十次,回答五花八门,在我看来,模式就是经验,设计模式就是设计经验,有了这些经验,我们就能在特定情况下使用特定的设计、组合设计,这样可以大大节省我们的设计时间,提高工作效率。
作为一个工作10年以上的老码农,经历的系统架构设计也算不少,接下来,我会把工作中用到的一些架构方面的设计模式分享给大家,望大家少走弯路。
总体而言,共有八种,分别是:
1.单库单应用模式:
最简单的,可能大家都见过
2.内容分发模式:
目前用的比较多
3.查询分离模式:
对于大并发的查询、业务
4.微服务模式:
适用于复杂的业务模式的拆解
5.多级缓存模式:
可以把缓存玩的很好
6.分库分表模式:
解决单机数据库瓶颈
7.弹性伸缩模式:
解决波峰波谷业务流量不均匀的方法之一
8.多机房模式:
解决高可用、高性能的一种方法
3.单库单应用模式 这是最简单的一种设计模式,我们的大部分本科毕业设计、一些小的应用,基本上都是这种模式,这种模式的一般设计见下图:
如上图所示,这种模式一般只有一个数据库,一个业务应用层,一个后台管理系统,所有的业务都是用过业务层完成的,所有的数据也都是存储在一个数据库中的,好一点会有数据库的同步。
虽然简单,但是也并不是一无是处。
优点:
结构简单、开发速度快、实现简单,可用于产品的第一版等有原型验证需求、用户少的设计。
缺点:
性能差、基本没有高可用、扩展性差,不适用于大规模部署、应用等生产环境。
4.内容分发模式 基本上所有的大型的网站都有或多或少的采用这一种设计模式,常见的应用场景是使用CDN技术把网页、图片、CSS、JS等这些静态资源分发到离用户最近的服务器。
这种模式的一般设计见下图:
如上图所示,这种模式较单库单应用模式多了一个CDN、一个云存储OSS(七牛、又拍等雷同)。
一个典型的应用流程(以用户上传、查看图片需求为例)如下:
1.上传的时候,用户选择本地机器上的一个图片进行上传
2.程序会把这个图片上传到云存储OSS上,并返回该图片的一个URL
3.程序把这个URL字符串存储在业务数据库中,上传完成。
4.查看的时候,程序从业务数据库得到该图片的URL
5.程序通过DNS查询这个URL的图片服务器
6.智能DNS会解析这个URL,得到与用户最近的服务器(或集群)的地址A
7.然后把服务器A上的图片返回给程序
8.程序显示该图片,查看完成。
由上可知,这个模式的关键是智能DNS,它能够解析出离用户最近的服务器。
运行原理大致是:
根据请求者的IP得到请求地点B,然后通过计算或者配置得到与B最近或通讯时间最短的服务器C,然后把C的IP地址返回给请求者。
这种模式的优缺点如下:
优点:
资源下载快、无需过多的开发与配置,同时也减轻了后端服务器对资源的存储压力,减少带宽的使用。
缺点:
目前来说OSS,CDN的价格还是稍微有些贵(虽然已经降价好几次了),只适用于中小规模的应用,另外由于网络传输的延迟、CDN的同步策略等,会有一些一致性、更新慢方面的问题
八种架构设计模式及其优缺点概述(中)
2017-03-31码农原创码农原创
码农原创
微信号
功能介绍码农原创文章,适合程序员、工程师、架构师等一切与软件开发相关的工作者阅读
在上篇文章中,介绍了八种架构设计模式中的两种,既:
单库单应用模式、内容分发模式,没有读过的同学请手动微信关注“码农原创”公众号,在历史消息中寻找。
接下来继续介绍三种架构模式,分别是:
查询分离模式、微服务模式、多级缓存模式。
1.查询分离模式
这种模式主要解决单机数据库压力过大,从而导致业务缓慢甚至超时,查询响应时间变长的问题,也包括需要大量数据库服务器计算资源的查询请求。
这个可以说是单库单应用模式的升级版本,也是技术架构迭代演进过程中的必经之路。
这种模式的一般设计见下图:
如上图所示,这种模式较单库单应用模式与内容分发模式多了几个部分,一个是业务数据库的主从分离,一个是引入了ES,为什么要这样?
都解决了哪些痛点,下面具体结合业务需求场景进行叙述。
场景一:
全文关键词检索
我想这个需求,绝大多数应用都会有,如果使用传统的数据库技术,大部分可能都会使用like这种SQL语句,高级一点可能是先分词,然后通过分词index相关的记录。
SQL语句的性能问题与全表扫描机制导致了非常严重的性能问题,现在基本上很少见到。
这里的ES是ElasticSearch的缩写,是一种查询引擎,类似的还有Solr等,都差不多的技术,ES较Solr配置简单、使用方便,所以这里选用了它。
另外,ES支持横向扩展,理论上没有性能的瓶颈。
同时,还支持各种插件、自定义分词器等,可扩展性较强。
在这里,使用ES不仅可以替代数据库完成全文检索功能,还可以实现诸如分页、排序、分组、分面等功能。
具体的,请同学们自行学习之。
那怎么使用呢?
一个一般的流程是这样的:
1.服务端把一条业务数据落库
2.服务端异步把该条数据发送到ES
3.ES把该条记录按照规则、配置放入自己的索引库
4.客户端查询的时候,由服务端把这个请求发送到ES,得到数据后,根据需求拼装、组合数据,返回给客户端
实际中怎么用,还请同学们根据实际情况做组合、取舍。
场景二:
大量的普通查询
这个场景是指我们的业务中的大部分辅助性的查询,如:
取钱的时候先查询一下余额,根据用户的ID查询用户的记录,取得该用户最新的一条取钱记录等。
我们肯定是要天天要用的,而且用的还非常多。
同时呢,我们的写入请求也是非常多的,导致大量的写入、查询操作压向同一数据库,然后,数据库挂了,系统挂了,领导生气了,被开除了,还不起房贷了,露宿街头了,老婆跟别人跑了,......
不敢想,所以要求我们必须分散数据库的压力,一个业界较成熟的方案就是数据库的读写分离,写的时候入主库,读的时候读从库。
这样就把压力分散到不同的数据库了,如果一个读库性能不行,扛不住的话,可以一主多从,横向扩展。
可谓是一剂良药啊!
那怎么使用呢?
一个一般的流程是这样的:
1.服务端把一条业务数据落库
2.数据库同步或异步或半同步把该条数据复制到从库
3.服务端读数据的时候直接去从库读相应的数据
比较简单吧,一些聪明的、爱思考的、上进的同学可能发现问题了,也包括上面介绍的场景一,就是延迟问题,如:
数据还没有到从库,我就马上读,那么是读不到的,会发生问题的。
对于这个问题,各家公司解决的思路不一样,方法不尽相同。
一个普遍的解决方案是:
读不到就读主库,当然这么说也是有前提条件的,但具体的方案这里就不一一展开了,我可能会在接下来的分享中详解各种方案。
另外,关于数据库的复制模式,还请同学们自行学习,太多了,这里说不清。
该总结一下这种模式的优缺点的了,如下:
优点:
减少数据库的压力,理论上提供无限高的读性能,间接提高业务(写)的性能,专用的查询、索引、全文(分词)解决方案。
缺点:
数据延迟,数据一致性的保证。
2.微服务模式
上面的模式看似不错,解决了性能问题,我可以不用露宿街头了、老婆还是我的,哈哈。
但是
软件系统天生的复杂性决定了,除了性能,还有其他诸如高可用、健壮性等大量问题等待我们解决,再加上各个部门间的撕逼、扯皮,更让我们码农雪上加霜,所以
继续吧......
微服务模式可以说是最近的热点,花花绿绿、大大小小、国内国外的公司都在鼓吹,实践这个模式,可是大部分都没有弄清楚为什么要这么做,也并不知道这么做有什么好处、坏处,在这里,我将以我自己的亲身实践说一下我对这个模式的看法,不喜勿喷!
随着业务与人员的增加,遇到了如下的问题:
1.单机数据库写请求量大量增加,导致数据库压力变大
2.数据库一旦挂了,那么整个业务都挂了
3.业务代码越来越多,都在一个GIT里,越来越难以维护
4.代码腐化严重、臭味越来越浓
5.上线越来越频繁,经常是一个小功能的修改,就要整个大项目要重新编译
6.部门越来越多,该哪个部门改动大项目中的哪个东西,撕逼的厉害
7.其他一些外围系统直接连接数据库,导致一旦数据库结构发生变化,所有的相关系统都要通知,甚至对修改不敏感的系统也要通知
8.每个应用服务器需要开通所有的权限、网络、FTP、各种各样的,因为每个服务器部署的应用都是一样的
9.作为架构师,我已经失去了对这个系统的把控......
为了解决上述问题,我司使用了微服务模式,这种模式的一般设计见下图:
如上图所示,我把业务分块,做了垂直切分,切成一个个独立的系统,每个系统各自衍化,有自己的库、缓存、ES等辅助系统,系统之间的实时交互通过RPC,异步交互通过MQ,通过这种组合,共同完成整个系统功能。
那么,这么做是否真的解决上述问题了呢?
不玩虚的,一个个来说。
对于问题一,由于拆分成了多个子系统,系统的压力被分散了,而各个子系统都有自己的数据库实例,所以数据库的压力变小。
对于问题二,一个子系统A的数据库挂了,只是影响到系统A和使用系统A的那些功能,不会所有的功能不可用,从而解决一个数据库挂了,导致所有功能不可用的问题。
问题三、四,也因为拆分得到了解决,各个子系统有自己独立的GIT代码库,不会相互影响。
通用的模块可通过库、服务、平台的形式解决。
问题五,子系统A发生改变,需要上线,那么我只需要编译A,然后上线就可以了,不需要其他系统做同样的事情。
问题六,顺应了康威定律,我部门该干什么事、输出什么,也通过服务的形式暴露出来,我部只管把我部的职责、软件功能做好就可以。
问题七,所有需要我部数据的需求,都通过接口的形式发布出去,客户通过接口获取数据,从而屏蔽了底层数据库结构,甚至数据来源,我部只需保证我部的接口契约没有发生变化即可,新的需求增加新的接口,不会影响老的接口。
问题八,不同的子系统需要不同的权限,这个问题也优雅的解决了。
问题九,暂时控制住了复杂性,我只需控制好大的方面,定义好系统边界、接口、大的流程,然后再分而治之、逐个击破、合纵连横。
目前来说,所有问题得到解决!
bingo!
但是,还有许多其他的副作用会随之产生,如RPC、MQ的超高稳定性、超高性能,网络延迟,数据一致性等问题,这里就不展开来讲了,太多了,一本书都讲不完。
另外,对于这个模式来说,最难把握的是度,切记不要切分过细,我见过一个功能一个子系统,上百个方法分成上百个子系统的,真的是太过度了。
实践中,一个较为可行的方法是:
能不分就不分,除非有非常必要的理由!
。
优点:
相对高性能,可扩展性强,高可用,适合于中等以上规模公司架构。
缺