在上篇文章中,介绍了八种架构设计模式中的两种,既:单库单应用模式、内容分发模式,没有读过的同窗请手动微信关注“码农原创”公众号,在历史消息中寻找。接下来继续介绍三种架构模式,分别是:查询分离模式、微服务模式、多级缓存模式。nginx
1. 查询分离模式数据库
这种模式主要解决单机数据库压力过大,从而致使业务缓慢甚至超时,查询响应时间变长的问题,也包括须要大量数据库服务器计算资源的查询请求。这个能够说是单库单应用模式的升级版本,也是技术架构迭代演进过程当中的必经之路。
后端
这种模式的通常设计见下图:设计模式
如上图所示,这种模式较单库单应用模式与内容分发模式多了几个部分,一个是业务数据库的主从分离,一个是引入了ES,为何要这样?都解决了哪些痛点,下面具体结合业务需求场景进行叙述。浏览器
场景一:全文关键词检索缓存
我想这个需求,绝大多数应用都会有,若是使用传统的数据库技术,大部分可能都会使用like这种SQL语句,高级一点多是先分词,而后经过分词index相关的记录。SQL语句的性能问题与全表扫描机制致使了很是严重的性能问题,如今基本上不多见到。服务器
这里的ES是ElasticSearch的缩写,是一种查询引擎,相似的还有Solr等,都差很少的技术,ES较Solr配置简单、使用方便,因此这里选用了它。另外,ES支持横向扩展,理论上没有性能的瓶颈。同时,还支持各类插件、自定义分词器等,可扩展性较强。在这里,使用ES不只能够替代数据库完成全文检索功能,还能够实现诸如分页、排序、分组、分面等功能。具体的,请同窗们自行学习之。那怎么使用呢?一个通常的流程是这样的:微信
服务端把一条业务数据落库网络
服务端异步把该条数据发送到ES架构
ES把该条记录按照规则、配置放入本身的索引库
客户端查询的时候,由服务端把这个请求发送到ES,获得数据后,根据需求拼装、组合数据,返回给客户端
实际中怎么用,还请同窗们根据实际状况作组合、取舍。
场景二:大量的普通查询
这个场景是指咱们的业务中的大部分辅助性的查询,如:取钱的时候先查询一下余额,根据用户的ID查询用户的记录,取得该用户最新的一条取钱记录等。咱们确定是要每天要用的,并且用的还很是多。同时呢,咱们的写入请求也是很是多的,致使大量的写入、查询操做压向同一数据库,而后,数据库挂了,系统挂了,领导生气了,被开除了,还不起房贷了,露宿街头了,老婆跟别人跑了,......
不敢想,因此要求咱们必须分散数据库的压力,一个业界较成熟的方案就是数据库的读写分离,写的时候入主库,读的时候读从库。这样就把压力分散到不一样的数据库了,若是一个读库性能不行,扛不住的话,能够一主多从,横向扩展。可谓是一剂良药啊!那怎么使用呢?一个通常的流程是这样的:
服务端把一条业务数据落库
数据库同步或异步或半同步把该条数据复制到从库
服务端读数据的时候直接去从库读相应的数据
比较简单吧,一些聪明的、爱思考的、上进的同窗可能发现问题了,也包括上面介绍的场景一,就是延迟问题,如:数据尚未到从库,我就立刻读,那么是读不到的,会发生问题的。
对于这个问题,各家公司解决的思路不同,方法不尽相同。一个广泛的解决方案是:读不到就读主库,固然这么说也是有前提条件的,但具体的方案这里就不一一展开了,我可能会在接下来的分享中详解各类方案。
另外,关于数据库的复制模式,还请同窗们自行学习,太多了,这里说不清。该总结一下这种模式的优缺点的了,以下:
优势:减小数据库的压力,理论上提供无限高的读性能,间接提升业务(写)的性能,专用的查询、索引、全文(分词)解决方案。
缺点:数据延迟,数据一致性的保证。
2. 微服务模式
上面的模式看似不错,解决了性能问题,我能够不用露宿街头了、老婆仍是个人,哈哈。可是
软件系统天生的复杂性决定了,除了性能,还有其余诸如高可用、健壮性等大量问题等待咱们解决,再加上各个部门间的撕逼、扯皮,更让咱们码农雪上加霜,因此
继续吧......
微服务模式能够说是最近的热点,花花绿绿、大大小小、国内国外的公司都在鼓吹,实践这个模式,但是大部分都没有弄清楚为何要这么作,也并不知道这么作有什么好处、坏处,在这里,我将以我本身的亲身实践说一下我对这个模式的见解,不喜勿喷!随着业务与人员的增长,遇到了以下的问题:
单机数据库写请求量大量增长,致使数据库压力变大
数据库一旦挂了,那么整个业务都挂了
业务代码愈来愈多,都在一个GIT里,愈来愈难以维护
代码腐化严重、臭味愈来愈浓
上线愈来愈频繁,常常是一个小功能的修改,就要整个大项目要从新编译
部门愈来愈多,该哪一个部门改动大项目中的哪一个东西,撕逼的厉害
其余一些外围系统直接链接数据库,致使一旦数据库结构发生变化,全部的相关系统都要通知,甚至对修改不敏感的系统也要通知
每一个应用服务器须要开通全部的权限、网络、FTP、各类各样的,由于每一个服务器部署的应用都是同样的
做为架构师,我已经失去了对这个系统的把控......
为了解决上述问题,我司使用了微服务模式,这种模式的通常设计见下图:
如上图所示,我把业务分块,作了垂直切分,切成一个个独立的系统,每一个系统各自衍化,有本身的库、缓存、ES等辅助系统,系统之间的实时交互经过RPC,异步交互经过MQ,经过这种组合,共同完成整个系统功能。
那么,这么作是否真的解决上述问题了呢?不玩虚的,一个个来讲。对于问题一,因为拆分红了多个子系统,系统的压力被分散了,而各个子系统都有本身的数据库实例,因此数据库的压力变小。
对于问题二,一个子系统A的数据库挂了,只是影响到系统A和使用系统A的那些功能,不会全部的功能不可用,从而解决一个数据库挂了,致使全部功能不可用的问题。
问题3、四,也由于拆分获得了解决,各个子系统有本身独立的GIT代码库,不会相互影响。通用的模块可经过库、服务、平台的形式解决。
问题五,子系统A发生改变,须要上线,那么我只须要编译A,而后上线就能够了,不须要其余系统作一样的事情。
问题六,顺应了康威定律,我部门该干什么事、输出什么,也经过服务的形式暴露出来,我部只管把我部的职责、软件功能作好就能够。
问题七,全部须要我部数据的需求,都经过接口的形式发布出去,客户经过接口获取数据,从而屏蔽了底层数据库结构,甚至数据来源,我部只需保证我部的接口契约没有发生变化便可,新的需求增长新的接口,不会影响老的接口。
问题八,不一样的子系统须要不一样的权限,这个问题也优雅的解决了。
问题九,暂时控制住了复杂性,我只需控制好大的方面,定义好系统边界、接口、大的流程,而后再分而治之、逐个击破、合纵连横。
目前来讲,全部问题获得解决!bingo!
可是,还有许多其余的反作用会随之产生,如RPC、MQ的超高稳定性、超高性能,网络延迟,数据一致性等问题,这里就不展开来说了,太多了,一本书都讲不完。
另外,对于这个模式来讲,最难把握的是度,切记不要切分过细,我见过一个功能一个子系统,上百个方法分红上百个子系统的,真的是太过分了。实践中,一个较为可行的方法是:能不分就不分,除非有很是必要的理由!。
优势:相对高性能,可扩展性强,高可用,适合于中等以上规模公司架构。
缺点:复杂、度很差把握。指不只须要一个能在高层把控大方向、大流程、整体技术的人,还须要可以针对各个子系统有针对性的开发。把握很差度或者滥用的话,这个模式拔苗助长!
3.多级缓存模式
这个模式能够说是应对超高查询压力的一种广泛采用的策略,基本的思想就是在全部链路的地方,能加缓存就加缓存,以下图所示:
如上图所示,通常在三个地方加入缓存,一个是客户端处,一个是API网关处,一个是具体的后端业务处,下面分别介绍。
客户端处缓存:这个地方加缓存能够说是效果最好的---无延迟。由于不用通过长长的网络链条去后端业务处获取数据,从而致使加载时间过长,客户流失等损失。虽然有CDN的支持,可是从客户端到CDN仍是有网络延迟的,虽然不大。具体的技术依据不一样的客户端而定,对于WEB来说,有浏览器本地缓存、Cookie、Storage、缓存策略等技术;对于APP来说,有本地数据库、本地文件、本地内存、进程内缓存支持。以上提到的各类技术有兴趣的同窗能够继续展开来学习。若是客户端缓存没有命中,那么就会去后端业务拿数据,通常来说,都会有个API网关,在这里加缓存也是很是有必要的。
API网关处缓存:这个地方加缓存的好处是不用把请求发送到后方,直接在这里就处理了,而后返回给请求者。常见的技术,如http请求,API网关用的基本都是nginx,可使用nginx自己的缓存模块,也可使用Lua+Redis技术定制化。其余的也都大同小异。
后端业务处:这个我想就不用多说了,你们应该差很少都知道,什么Redis,Memcache,Jvm内等等,不熬述了。
实践中,要结合具体的实际状况,综合利用各级缓存技术,使得各类请求最大程度的在到达后端业务以前就被解决掉,从而减小后端服务压力、减小占用带宽、加强用户体验。至因而否只有这三个地方加缓存,我以为要活学活用,心法比剑法重要!总结一下这个模式的优缺点:
优势:抗住大量读请求,减小后端压力。
缺点:数据一致性问题较突出,容易发生雪崩,即:若是客户端缓存失效、API网关缓存失效,那么全部的大量请求瞬间压向后端业务系统,后果可想而知。
本次分享的中篇到此结束,接下来的下篇将介绍最后三种模式:分库分表模式、弹性伸缩模式、多机房模式,相对来说技术含量更高,敬请期待!