「和耳朵」聊聊微服务与分布式系统

我是和耳朵,很久没有写文了,今天趁着和你们聊聊分布式html

前段时间一直没有写文是由于忙于面试~,没错😂离职了换了一家公司工做,新公司的系统都是分布式的,入职一个月且写了点东西上线以后我才勇于写写这个分布式主题,否则怕本身没有生产经验误人子弟了。面试

今天呢,主要是和你们聊一聊分布式系统的相关概念及其常见分布式组件和设计思想(不涉及计算机科学中分布式系统的技术理论之类的东西),以前为了准备此次的面试我是把市面上的不少分布式组件都看了一遍,咱们公司所用的分布式组件基本也没出我了解的那个知识圈(公司用了Apollo我没提早了解,大E了),若是对分布式相关技术栈不太了解,也能够当我这篇征文作你的扫盲贴,不过别忘了点赞👍算法

单体应用与集群

单体应用、集群和微服务,这个标题一出大家可能就知道我想说啥了,emm,就是架构的演进过程,不少人可能都看过相关知识,不过我为了文章的完整性仍是打算简单讲一讲。spring

首先是单体应用,在一个业务的起步阶段,每每是用户量不大且访问请求少的阶段,这个时候咱们通常只须要部署一个Web应用和一台数据库就能知足咱们的业务需求,且随着SpringBoot的流行,Web服务器能够内置在应用里面,可以更加方便快捷的部署应用。数据库

同时由于项目规模小,业务流程简单,维护和迭代起来也很方便,因此在当前这个阶段单体应用是很是适合的。编程

可是随着业务增加,单体应用不可避免的会出现瓶颈,我举个例子:后端

假如咱们如今的单体Tomcat应用只能支撑QPS200,随着用户量的增大并发随之增大,慢慢超出了单台应用能承受的极限,假如如今达到了QPS300,那么多出来的100请求就只能等着前面的请求处理完了以后才能请求进去,这样带来的后果就是响应时间变长,影响用户体验。设计模式

或者咱们应用中的业务比较复杂,单次请求响应时间比较长,这样的话大量请求挤压也会致使用户的体验不好,他们能明显的感受到点击某个按钮以后隔了1~2s才有结果返回。服务器

这个时候咱们就能够引入集群架构了,咱们能够将单体应用同时部署两份,并经过Nginx进行反向代理和负载均衡进行流量分流,这样每一个单体应用承受的QPS就是150了,就在能够接受的范围内,并且维护集群应用和维护单机应用区别不大,只是在涉及到锁的时候可能要借助分布式锁来作。网络

至此,每当访问量增大系统到达瓶颈时咱们就能够经过加机器这种方式进行横向扩容,不断的扩大应用的负载能力,可是若是这种方式天衣无缝,咱们也就不须要微服务的架构了~~~

从单体应用过渡到集群架构,解决的实际上是性能的问题,单台机器已经没法知足人民日益增加的访问需求,因此出现了集群架构。

那么从集群过渡到微服务架构的更多缘由确定就不在性能了,这里我说说我本身的见解与感悟:

  1. 首先既然项目已是集群了证实业务量也不会很是小,这也就表明了代码必定有一些规模了,这时候要面临的第一个问题就是全部开发人员都会在这一个项目里面修改代码,极大状况下是冲突不断。

  2. 其次这么多代码聚合在一块,当你进行一处功能修改的时候,若是须要进行全量回归测试的话那简直太要命了。

  3. 再者说,全部业务块都在一个系统这会致使资源没法最大化利用,好比一个电商系统确定是商品搜索/推荐系统为最经常使用的系统,理所固然在资源方面他们应该占有更多的机器资源,可是业务不进行拆分想进行横向扩展只能将全部业务一块儿扩展。

  4. 最后是有可能会引发雪崩效应,举个例子你的系统中假若有一块很是不重要的业务(好比签到)代码写的有问题在生产环境中引起了OOM,那么它必然会连累到整个系统中的全部业务都变成不可用,由于不一样业务之间并无物理隔离。

经过这几条能够知道过渡到微服务更多的考虑的已经不是性能瓶颈,而是人,是业务,也是应用系统最重要的高可用。

微服务与分布式

微服务是一种面向服务的软件架构模式,自2014年Martin FowlerJames Lewis写了一篇微服务架构的文章以后(微服务这个概念在此以前就有),微服务就被大量的讨论以及实践到生产项目中:Netflix、Amazon这些商业公司都有微服务的成功案例,商业公司最会考虑的一件事就是成本,他们不会由于Martin Fowler是软件工程的名人(巨佬)就对他提出的某个概念迅速披挂上马,必定是通过了不少权衡以后,才对他们的项目使用微服务的架构模式。

上一节中我已经简要说了说集群架构的缺点,微服务则是解决了那些缺点才变得如此受欢迎,微服务的相关定义,这里我引用一段Martin Fowler原文的配图和翻译来讲明:

简而言之,微服务架构风格,就像是把一个单独的应用程序开发为一套小服务,每一个小服务运行在本身的进程中,并使用轻量级机制通讯,一般是 HTTP API。

这些服务围绕业务能力来构建,并经过彻底自动化部署机制来独立部署。这些服务使用不一样的编程语言书写,以及不一样数据存储技术,并保持最低限度的集中式管理。

若是非要我用本身的语言来理解一下就是:将一个大型系统分为一个个的小型服务系统,共同支撑大型系统,每一个小服务系统均可以独立开发/测试/迭代/部署/扩容。

将大系统拆分为小服务以后既拥有了小服务的相关优势(利于团队协做/测试/迭代),又能在面对大流量时进行集群扩容,能够说是集二者优势于一身,可能这就是所谓的”天下大势,合久必分,分久必合。”

我新入职的这家公司也是在今年初全面转入微服务架构,咱们部门中全部的业务都已经拆成了微服务在跑,微服务拆分这事算是见仁见智把,要根据具体业务具体分析,咱们的拆分过程当中感受比较好的一点是:有一些在将来一两年内将要中止运营的业务也单独拆出来放在一个服务里跑。

其实微服务的概念不难理解,但真正动手起来作的话遇到的则通常不是微服务的问题而是分布式问题,有不少人常常把这两个概念搞混淆,认为他俩说的是一个东西,实际上是两个东西,咱们作出来的东西每每是涵盖了这两个概念。

微服务是指的一种面向服务的软件架构方式,而分布式则是一种为了某个共同目标而协调多台计算机节点进行工做的软件系统。

在上一节的讲解中,有一句话一直出现:随着业务量/访问量增大,这个日益增加的访问量/业务量/数据量是咱们使用微服务和分布式系统的主要缘由:

  1. 业务的增长咱们经过业务拆分来解决其带来的问题,这能够算是微服务的范畴。

  2. 不一样的服务部署在不一样的机器上,可是对于用户来讲却和访问一个系统没什么区别,依靠网络将多个计算机节点组成一个统一的总体,这能够算是分布式系统的范畴。

  3. 因为数据量的不断增长咱们能够经过增长机器节点来分摊数据量,这算是分布式系统中分布式存储的范畴。好比咱们的Redis数据一台机器已经存不下了,就要考虑使用RedisCluster将数据分散到多台机器上面,其余例如Kafaka、ES都是分布式架构的中间件均可以进行分布式存储。

  4. 若是应用中某些计算量比较大的任务使用一台机器执行会耗时过长,这时咱们能够拆分任务给多台节点同时执行,这算是分布式系统中分布式计算的范畴。最近我在接手项目的时候就遇到了相似的问题,原任务单机执行时间太久,让我改成全部在线节点同时执行,共同分摊任务,而且要能动态根据在线节点数量进行任务拆分。

经过上面四点的说明,我想你们对微服务和分布式应该有个简单的区分了把,再次总结一下:

微服务是指的一种面向服务的软件架构方式,而分布式则是一种为了某个共同目标而协调多台计算机节点进行工做的软件系统。

那为何微服务和分布式系统老放在一块讨论,致使不少人对他俩的定义模糊不清呢,由于每每咱们要实现一个微服务架构的应用时,咱们就在实现一个分布式系统。

若是你不明白我这句话,请好好想一想使用微服务架构组成的应用是否是也同时符合分布式的定义。

Tips: 分布式计算/存储也是一门计算机科学中的研究方向,因此它们其实仍是能够挺深奥的一堆东西。

分布式与CAP

看了上一节你们应该已经明白了微服务和分布式的关系了吧,我这篇文章的重点实际上是分布式,由于微服务只是一个面向服务的软件架构概念,让我理解起来它的主要做用就是提出了服务拆分、独立开发部署这些概念,emm~概念,可是一个分布式系统却有不少各类各样的实际问题须要解决,因此个人重点是在分布式。

先来讲说分布式的CAP原则,但凡对分布式有点了解的,都不能不知道这个CAP,先来看看它的定义:

CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。

CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。

分区容错性: 是指在分布式系统中部署在不一样地点的机器可能出现网络链接失败的状况,这就像个人推荐服务会请求商品服务里面的数据,但有可能发生了网络波动致使我推荐服务发起的请求网络链接超时。

可用性: 是指用户的请求必须返回结果,要作到这个程度就须要咱们在不一样机房部署应用避免出现某些地方机房遭遇了事故致使服务宕机的状况。

一致性: 是指数据被修改后,以后读到的数据必定是最新的数据。

上面的定义已经说了,CAP只能最多同时实现两点,由于咱们是分布式系统,因此多台服务节点是没法避免的,也就是分区容错性咱们必需要保证,因此咱们只能保证明现CP或者AP。

为何不能同时实现CAP呢?缘由很简单,由于可用性这个要求须要每一个节点的数据都要有几个冗余的副本,用来保证有一个节点挂掉以后副本能顶上去。然而副本节点和主机节点之间由于有网络通讯因此每每这个数据的传输是有延迟的,这也就不能保证主机的数据被修改后副本能当即收到修改,而是通过一顿延迟后才能收到主机修改的数据。

为了方便你们理解,我再举一个例子来讲明一下,好比说分布式中间件Redis

它在单机的状况下能够保证CP,由于只有一台Redis节点因此数据被修改后以后的请求所访问到的数据都是最新的。

它在集群的状况下能够保证AP,AP是强调可用性,集群架构下若是主节点挂掉以后,副本节点还能够接着响应请求。


既然CAP没法同时保证,那咱们就要退而求其次,这里将会引出一个新的理论:BASE

BASE是Basically Available(基本可用)、Soft state(软状态)和Eventually consistent(最终一致性)的简写。

BASE是对CAP中一致性和可用性权衡的结果,契合性思想是即便没法作到强一致性,但每一个应用均可以根据自身的业务特色,采用适当的方式来使得系统达到最终一致性。

基本可用: 是指某些状况下容许部分可用性的丢失,好比咱们的双十一大促,可能会因为下单量激增致使你下不了单,这就属于下单服务不可用了,可是并不会持久过久,而是短暂的。

软状态: 是指容许副本同步过程当中出现延迟而致使副本不一致的状况。

最终一致性: 是指系统的全部系统数据副本能够通过一段延迟后最终达到数据的一致性,不须要保证明时的数据一致。

咱们既想要可用性也想要一致性,然而两者没法兼得,因此BASE理论就提出了这样一种兼顾的思想,代价是强可用和强一致的损失。

现实中的不少系统中都是BASE理论这种思想,达到系统的一个基本可用和最终一致。

分布式开发与组件

这节咱们来聊聊咱们分布式系统的常见的各类组件以及相关特性,你们接触过度布式开发的话就会发现分布式开发中有一大箩筐的名词等着你:注册中心、配置中心、网关、熔断、远程调用等等。

初来乍到,不要被这些名词吓住,别人能会的你也能,这一节我会自顶向下的讲解一下分布式开发的基本组成,你能够先忘记这些名词,慢慢看个人讲解,看完这一章后我相信对这些都不会再迷茫。

前面我已经说过,分布式系统是多个节点组成一个总体,那不一样节点的IP确定不一样,想要感受像是一个总体,就得有一个部件在全部节点的最前面承担一个请求分发的做用,这个东西就叫:网关

通常的网关有两层,第一层是服务器的Nginx+LVS这种,第二层是分布式应用的网关,我这里说的是分布式应用的网关。

这个网关的做用有点像Nginx,能够帮你作反向代理帮你作负载均衡,可是比它更强大,分布式应用的全部请求第一站就是应用的网关层,在这里能够校验请求是否合法,阻挡网络攻击,也能够进行动态的请求分发。

请求被网关转发到对应的服务以后,就由对应的服务来处理了,这个时候问题又来了,咱们同一个服务可能部署了三四台节点,这个时候我该往哪一个服务器转发呢?

咱们要想转发首先要知道各个节点的IP和端口号,这个信息咱们不能写死,写死的话不利于动态加机器,因此这个时候咱们须要用到一个中间价:注册中心

咱们全部的服务都会注册到注册中心上面去,固然这个注册中心也要是一个集群,这样能够保证高可用。

举个例子:我有一个商品服务给它起了个名字叫作goods-service,我给他起了三台服务器,这三台服务器都会注册到注册中心上去,而后咱们就能够在注册中心上看到有一个叫goods-service的东西下面又三台节点,每台节点的IP端口号都会在注册中心上面保存。

这时候咱们网关来转发的时候是经过goods-service这个名称去注册中心拿到三台节点的地址,而后根据不一样的策略最终决定咱们是要将请求发到哪一台节点。

请求发送到服某某服务的这个过程,咱们能够称做为服务通讯,这个通讯方式通常有两种:HTTP和RPC,这个其实我以为没啥好说的,主要就是通讯的协议不同,协议的不一样也形成了效率的不一样。

上面说了三个比较重要的组件,还有两个比较重要的听我娓娓道来。

第一个是配置中心,这个实际上是属于用不用都行的东西,可是用起来仍是更方便的,它的主要做用是将分布式应用的配置都放在一个地方管理,咱们须要更改的时候就可让全部引用这些配置的应用感知到并在运行的过程当中动态加载到这些被修改的配置。

好比咱们有六个微服务应用,咱们能够统一的把配置都放在配置中心中间件上,这个数据通常是放在配置中心所连的数据库里,因此等于把咱们全部项目的配置抽出来都放在数据库了,一旦线上运行有什么须要动态修改的配置,咱们均可以直接在中间件上修改而后全部应用都会收到修改的通知,就会对修改的配置进行从新加载。

它对于某些公共的配置也很方便,好比六个微服务用的是一个Redis集群,咱们只须要配置一份就够了,并且集群配置有变化咱们也只须要修改一次,六个微服务应用都能感知到。

第二个是熔断器,所谓熔断器,就是为了保护应用而设计的中间件,好比淘宝双十一下单服务器顶不住的时候就会给你提示一个哎呀,服务器太火爆了,请稍后再试呢” 这种提示,这个东西就是为了保护淘宝服务不被冲垮而使用的一种限流措施,这种措施叫作服务降级。

使用熔断器还有一些场景,好比下单经历了商品服务和下单服务和库存服务,走到最后一步时库存服务崩掉了,这个时候下单服务这里会报错,进而引发羊群效应,全部和崩掉的节点有通讯的节点都会发生错误,这个时候就须要熔断器出场了,发现那个服务不会响应以后会给一个提示,防止羊群效应的产生。

这两个概念表现方式很像,可是不要被表象迷惑,他俩很主要的一个区别是引发的内因不同,你们有机会写一次相关的代码就能明白了。

以上介绍的这些都是分布式开发中比较基础的中间件,还有其余可选的中间件链路追踪我会在下一节提一下,在这就很少说了。

SpringCloud与Alibaba

上一节大概讲了五个分布式相关的组件,通常也就这五种:微服务网关、注册中心、配置中心、服务通讯组件、熔断组件。

这一节要给你们说说相关的实现,给你们认认脸熟,由于咱们搞Java应用开发的通常都是用Spring全家桶的,在微服务开发这块Spring推出了它的SpringCloud全家桶用来作微服务分布式开发。

通过这几年的发展其实大体能够分为两套开发套件:SpringCloud开发套件和SpringCloudAlibaba开发套件,这个只是我我的的分法,还有一些其余家的我也会提一下。

咱们先来看看SpringCloud这一套,这一套相关的组件一开始基本都是Netflix公司开发的,这是一个作流媒体应用的,能够理解为国外的爱奇艺。

这张导图右边的是三个注册中心中间件,Eureka就是Netflix公司开发的,Zookeeper这个功能比较强不是简简单单只作注册中心,它还能够作注册中心和分布式锁,Consul则是一个Go语言开发的注册中心中间件(也能够用做配置中心),这几个里面Eureka是这两年用的比较多的,更早以前国内可能Zookeeper用的更多。

左边第一个SpringCloudGateway则是网关中间件,由Spring开发,以前Netflix还有一个Zuul,也是用来作网关中间件的。

Feign/OpenFeign/Rabbon这三个我放在一块说,Feign和OpenFeign实际上是一个东西,OpenFeign是在Feign停更以后在其基础上开发的,都是用来作服务间通讯的,他们使用HTTP作通讯协议,其实就是Spring中的RestTemplate,而Rabbon是一个作服务转发策略的中间件,前文咱们提到网关进行服务转发时能够根据必定的策略好比:轮询、随机、权重这些策略,这块其实就是Rabbon在起效,咱们用Eureka的时候如今都是自带Rabbon不须要额外去引入相关JAR包了,毕竟都是Netflix一家的东西。

SpringCloudConfig是Spring开发的配置中心中间件,功能比起其余的后起之秀好比携程的Apollo,阿里的Nacos稍弱,因此不推荐用。

Hystrix也是Netflix公司开发的中间件,它的做用就是熔断器,是一款很是经典的熔断器中间件,这些中间件里面它是相对来讲最复杂的。

Sleuth是一款链路追踪中间件,能够记录你的请求会通过哪些链路,Zipkin则能够以可视化的形式将其表现出来。

上面这一套东西在我如今的公司里面除了配置中心用的Apollo以外其余都用到了,算是比较流行的套件了。


不一样于上面的基本都是由Netflix开发的套件,下面我要介绍的套件是SpringCloudAlibaba套件,由于是由Alibaba开发的因此通常都这样称呼。

上面这幅图相比上一张就要简单的多了。

Nacos是一个多功能中间件,同时能够作注册中心和配置中心,这个组件我本身也用过感受仍是蛮好用的,并且自带一套比较美观的可视化界面。

Duubo这个可能你们比较熟悉,原来是由阿里开发后来捐给Apache,如今是Apache的顶级项目之一,它是一个服务通讯的组件,使用RPC通讯方式。

Sentinel阿里开发的熔断器,名字翻译过来就是哨兵能够说是很贴切了,而且拥有链路追踪的功能,还配有配套的可视化界面,能够说是一我的干了Hystrix+Sleuth+Zipkin的活。


像阿里这套中间件我是比较推荐的,由于第一套Netflix公司基本都已经宣布中止更新了,好比Feign不更新以后Spring又接手进行二次开发搞了一个OpenFeign。

这里在提一下Apollo,携程开发的配置中心中间件,如今也有不少公司在用,咱们公司也在用我的用起来感受仍是能够的,很方便上手也简单。

其实别看这里罗列了这么多的中间件,每中学一种,剩下的看看文档也就上手了,大同小异吧,开源界的东西就是喜欢弄的简单易上手,这对你们来讲也是减小学习成本。

框架学的越多用的越多,你越会发现其实大部分都是大同小异,越能明白学好Java基础的做用,越能知道设计模式、算法才是一个软件工程师必备的技能。

下个月我应该会把这些中间件也逐一写文章写个入门够用的程度吧,你们一块儿加油🎉。

我是和耳朵,欢迎关注个人公众号,加入后端相关交流群:

相关文章
相关标签/搜索