从本节开始,我开了一个新的专栏,叫做微服务技术栈。我进入到了微服务的学习阶段。这一小节就先来学习一下微服务的基础入门知识。这一节是一个过渡章节 ,所以会涉及到比较多的概念 ,以理解为主,比较短小 。主要目的是让我们对微服务以及其技术栈有一个具体的认识,方便后续学习更高级的知识。
- 一.微服务的基本概念
- 1.什么是微服务
- 2.微服务的特点
- 3.微服务的优缺点
- 4.微服务有两大门派
- 二.微服务的拆分、拓展与技术栈
- 1.微服务的拆分
- 2.服务拓展的方式
- 3.微服务的技术栈
一.微服务的基本概念
1.什么是微服务
微服务在诞生之前,我们的架构主要是单体架构。那么单体架构有什么痛点呢?
单体应用的痛点
第一点就是我们的项目会很庞大,可能会有几十张表。如果团队有新人加入进来了。她看到这些表的时候也是比较懵逼的,因为她可能也不知道这个表是怎么关联的,有什么含义,数据量怎么怎么样。她都需要花很长时间去理解。所以单体应用可能就会存在这样一个问题,表和表之间到项目越来越大的时候,很多表是废弃的,同时很难去维护。
第二点就是单体应用容易出现一个”尾大不掉“的情况。尾大不掉就是说我们的项目太大了,也很难去把它的整体进行一个调整,但同时它又大而不倒。
第三个痛点就是代码风格、组件不统一。
第四个痛点就是技术难以升级,升级成本高。
什么是服务化
服务化的一个很重要的特点就是拆分,它把大而全的一个项目拆分成小而美的项目。把原来聚集在一起的功能拆分为不同的功能。
比如举一个例子啊,就以电商为例。我们看到下面这个图:
在单体的时候,我们的内部是包含了商品模块、商品分类模块等等的模块。这些相当于是以类的形式,以功能的形式写在单体里面的,但作为项目而言呢,它还是一整个项目。后面,我们如果对他进行拆分的话,你可以这样拆分,比如说我分为商品与分类服务、订单与购物车服务、用户服务等等,我们可以看到,这样的一个拆分,它主要的方向是什么呢?就是从垂直领域的业务功能进行拆分的,这就是我们服务化的一个特点。我们的每一个服务只专注于一块功能,这就是关于拆分的一个特点。
服务化的第二个特点就是独立开发、独立部署、职责明确。独立说的是什么呢?就是说虽然每一个模块,它自己不能去支撑所有的功能,但是至少我们可以做到独立开发和独立部署的。每一个开发人员,对自己开发的部分不但是分工明确,而且是责任明确。
服务化的第三个特点就是通信,不关心接口的具体实现。通信一定不能是强耦合的,必须要通过调用来实现,而且一个重点是说,不管你是什么方式调用,我不能把它代码的整体实现给引进来,只能调用它定义的接口。
什么是微服务
维基百科是这样定义微服务的:微服务以专注于单一责任与功能的小型功能区块为基础,利用模块化的方式组合出复杂的大型应用程序。各功能区块使用与语言无关的API相互通信。
2.微服务的特点
微服务的特点之一就是技术栈自由,不管你是代码语言层面还是说存储系统的层面,这些配套设施都是可以不一样的。他们之间仅仅是通过接口来相互调用的,至于你具体怎么实现,是根本不用管的。
其次就是可以按需的弹性扩容,这个非常重要,因为比如说我们的订单服务,还有商品服务等,他们的流量非常大,那我们就可以对这几个专门的微服务进行多部署。原来你可能一个两个不够,那多几个就够了对吧,这样就可以应对高流量了。
除此之外呢,就是它的能力复用率高,比如说,你开发的不是商品服务,但是你需要商品服务来给你提供一些功能,那你一定会去找负责商品开发的人,让她来开发,而不是自己开发。
下一个微服务的特点就是它的部署和回滚的成本低。它不会再牵一发而动全身了,假设你这一块部署有问题,没有关系嘛。你立刻进行回滚,回滚就是说部署上一个可用的版本。这样不至于整个大项目都不可用。
其次还涉及到康威定律:组织结构跟着变动,这个康威定律就是说组织方式决定了整个系统的设计。什么意思呢?就是说,我们可能是一个大团队,大团队大家都是一起的,然后排工作量的时候,看谁比较空闲,谁就来开发。到后面呢,去进行微服务的改造,某一个大的模块,比如说订单模块,由3个人负责,那么以后就不是看谁有空闲来开发了。我们的组织结构,比如说内部的成员是一个组织的,无论他们是三个人一个小群体,还是七八个人一个团队,这个结构和我们的系统的架构是保持一致的。
3.微服务的优缺点
前面讲了很多微服务的特点,更多是对比了单体架构的缺点来说的优点。下面总结一下它的其他优点和缺点。
优点: 技术栈不受限,新技术有发展空间。可用性强,一个宕机不会整体都宕机。代码和机器的整体利用率都提高了。
缺点: 运维成本过高。原来我们的单体应用,可能虽然部署和调试要好几十分钟,但只要部署一次就好了,剩下的就是等待。而拆成多个服务后,部署的次数就多了。接口可能不匹配。如果一个服务改了接口,那其他服务调用会出问题。架构复杂度提升。
4.微服务有两大门派
这两大门派一个是Spring Cloud(由众多子项目组成) ,另一个是Dubbo(官网定义:高性能、轻量级的开源服务框架)。
先来看Spring Cloud,上面写到,是由很多的子项目组成的。这是一整个大的生态,他的组件可能有十几个之多。
然后是Dubbo,先来看官网的图片:
上面就是Dubbo的特点了。
但是,Dubbo提供的能力Spring Cloud都有,Dubbo可以说是Spring Cloud的一个子集。并且Dubbo以前是阿里巴巴的,后来变成了Apache的了。
下面这两个门派做一下对比:
通信协议上对比:spring cloud使用的更多的是http这样的通信方式,使用的是restful的api,而Dubbo更倾向于RPC的方式。这两种反思会有什么差别呢?在通信效率方面,RPC更胜一筹,但是Restful更加的灵活。
生态和社区活跃度:Spring Cloud的一直以来迭代速度快,虽然写在也在迭代更新,但是Dubbo的以前在很长的一段时间却没有维护。
其实还有一个微服务技术就是SpringCloudAlibaba ,它是在SpringCloud的基础上把它之前的Dubbo给整合进来了,支持了Dubbo的协议,同时也引进了一些新的技术。三者的对比如下图所示:
二.微服务的拆分、拓展与技术栈
1.微服务的拆分
需要拆分的信号:事故频发,且原因是由于耦合导致,就要考虑进行拆分了。第二个信号就是:服务的启动和部署越来越慢,甚至不可忍受了,要想到拆分了。第3个就是流量增加,需要扩容。
不适合拆分的情况:为了拆分而拆分。团队规模小的话也没必要拆分。
如何拆分:领域拆分、流量热点大小拆分。业务优先,逐步迭代。统筹安排,全盘考虑。
2.服务拓展的方式
单体集群:水平复制。是成本比较低的一种方式。 微服务:功能解耦。 数据拆分:分库分表 按需扩展:CPU、内存、网络负载程度、使用率。
3.微服务的技术栈
微服务是分布式架构的一种 , 微服务不仅仅是Spring Cloud和Dubbo 。Spring Cloud 其实仅仅解决了服务拆分时的服务治理问题,其他的一些分布式的一些更复杂的一些问题并没有给出解决方案。所以呢,一个完整的微服务技术栈要包含的不仅仅是Spring Cloud。
下面总结介绍一下微服务技术栈:
微服务要做的第一件事情就是拆分,因为传统的单体架构,所有的业务功能全部写在一起,随着业务功能越来越复杂,代码也变得越来越多,将来呢影响升级维护。所以一些大型的互联网项目,都必须去做拆分。
微服务在做拆分的时候会根据功能模块,把一个单体项目拆分成许多独立的项目,每个独立的项目完成一部分业务功能,将来独立开发和部署,每一个独立的项目都是一个服务。一个大型的互联网项目往往会包含成百甚至上千的服务,形成一个服务集群。而一个业务往往需要有多个服务共同来完成,比如说一个请求来了,它可能先去调了服务A,然后A调了服务B,B调了C…,当服务越来越复杂的时候,它的调用关系会越来越复杂,靠人来管理和维护是不可能的。所以在微服务里面,一定会有一个组件,叫注册中心。它可以记录微服务的每一个服务的IP、端口号以及他能干什么事情的一些信息。当有一个服务需要调用另外一个服务时,它不用自己去记录对方的IP、端口等信息,只需要去注册中心找就行了,从它那里去拉取对应的服务信息。同时,随着服务越来越多,每一个服务都有自己的配置文件,将来我们要去更改配置,不可能逐一去修改,这太麻烦了。所以在微服务里,会有一个配置中心 , 它可以统一去管理整个服务集群里成百上千的配置,如果你某一天哪些服务的配置需要变更的话,只需要找到配置中心就可以了,它会去通知相关的微服务,实现配置的热更新。
当我们的微服务运行起来以后,用户就可以来访问我们的服务了。但是这个时候呢,还需要一个服务网关的组件,因为你有这么多的微服务,用户怎么知道该访问哪一个呢?而且也不是说随便什么人都能来访问我们的服务。这就像是我们的小区,小区往往有一个看门的大爷,不能随便什么人来了都让进吧。实现得看看要进来的人是谁,是不是不法分子是吧。我们的服务网关,一方面可以对用户身份做校验,另一方面可以把用户的请求路由到我们具体的服务。当然在路由的过程中,也可以去做一些负载均衡。而在这时候,服务接收到你的请求去处理业务,该访问数据库的时候就去访问数据库集群,最后再把查询到的数据返回给用户就可以了。
当流量高峰期的时候,数据库集群在大也很难抗住如此高并发的访问,这时候,就要加入分布式缓存 。缓存就是把数据库高访问量的数据放到内存当中,内存的查询效率肯定要比数据库快非常多。而且这种缓存还不能是单体换成,为了应对高并发,还要做成分布式的缓存,这也是一个集群。请求先到缓存,缓存再去查询数据库。
业务中,还可能会有一些复杂的搜索功能,简单查询可以做缓存,一些复杂的搜索,统计分析,缓存也做不了。这时候,我们就要用到分布式搜索 , 数据库主要的职责就变成了数据的写操作。
最后还需要一种异步通信的消息队列组件,微服务它的业务往往会跨越多个服务,一个服务来了,先调用了服务A,A再调用B,B再调用其他服务。这个业务的链路就很长。此时,调用时长就会等于每一个服务的执行时长之和,其实性能会有一定的下降的。而异步通信的意思就是,请求来了,它调用了服务A,而服务A不是去调用服务B或C,而是去通知要被调用的那些服务,发一条消息,叫他们干活去,于是那几个服务就去干活了,而服务A直接结束了。所以他的业务链路就变短了,显然吞吐能力也就变强了。在一些秒杀的高并发场景下就可以利用到了。
当然,我们如此庞大和复杂的服务体系在运行的过程当中如果出现了什么问题,不太好排查了。所以,在微服务的运行当中。我们还会引入两个新的组件,第一个就是分布式日志服务,它可以去统计整个系统当中成百上千的服务的日志进行统一的存储、统计和分析,将来出现问题就比较好定位了。还有第二个组件就是系统监控链路追踪 ,它可以实时监控我们整个系统体系中每一个节点的运行状态、CPU的负载,内存的占用等等的情况。一旦出现任何的问题,直接可以对应到每一个具体的异常所在。
那么如此庞大的一个微服务集群,将来达到成百上千甚至上万的服务,之后我们部署该怎么办呢?如果还是靠以前人工去部署,肯定不现实。所以将来这些微服务集群,需要自动化的部署,我们可以使用Jenkins这个工具。它可以帮助你,对这些服务项目进行自动化编译,而基于docker再去做一些打包,形成镜像,再基于kubernetes 或者是 rancher这样的技术去实现自动化的部署。这一套操作叫做持续集成。
左边微服务的技术结合右边的持续集成的技术这才是完整的微服务技术栈!