当前位置: 首页 > news >正文

初识微服务技术栈

认识微服务

  • 随着互联网行业的发展,对服务的要求也越来越高,服务架构也从单体架构逐渐演变为现在流行的微服务架构,这些架构之间有怎样的差别呢? 

导学:

  • 了解微服务的优缺点;
  • 了解微服务架构的演变过程;
  • 认识微服务的一种实现:Spring Cloud 

微服务架构的演变 

单体架构

单体架构:将业务的所有功能都集中在一个项目中开发,打成一个包去部署,整个项目/系统的所有服务都部署在一台服务器上面,由一台服务器组成的系统。 

单体架构
单体架构的优缺点如下:

优点:

  • 架构简单
  • 部署成本低

缺点:

  • 耦合度高,扩展性差,因为所有代码写在一个项目里(维护困难、升级困难) ,适合小型项目,比如:学生管理系统
  • 单机资源有限
  • 存在单点故障的问题:如果这台服务器出现问题,整个系统就会出现问题,解决方案:搞服务集群:将相同的服务,分别部署到多台服务器中,由多台服务器来共同承担系统压力,其中一台服务器挂掉,也不会影响整个系统。

分布式架构

分布式架构:根据业务功能对系统做拆分,每个业务功能模块作为独立项目开发,称为一个服务,说白了就是按照业务垂直划分,每个业务都是单体架构,通过API互相调用  =>  分散部署在多台服务器上面,多台机器组成的一个运行环境/系统,一个系统中的多个服务部署在不同的服务器上,由多台服务器组成的系统。

分布式架构
分布式架构的优缺点:

优点:

  • 降低服务耦合
  • 扩展性好,有利于服务升级和拓展

缺点:

  • 难度大,服务调用关系错综复杂(只能远程调用:跨越机器、跨越服务的调用) ,适合大型互联网项目,比如:淘宝、京东
  • 分布式也并不能解决单点故障的问题,分布式跟单点问题没有关系,真正解决单点故障的方式是在分布式下面再继续搞集群,采用集群的方案
  • 分布式架构下所带来的分布式Session问题
分布式架构虽然降低了服务耦合,但是服务拆分时也有很多问题需要思考:
  • 服务拆分的粒度如何界定?
  • 服务集群的地址如何维护?
  • 服务之间如何实现远程调用?
  • 服务的调用关系如何管理?
  • 服务健康状态如何感知?万一你这个服务都挂了我还来调你,导致我这里也调用失败 - 级联失败

人们需要指定一套行之有效的标准来约束分布式架构,因此就出现了微服务~! 

知识补充:热更新(Hot Reload)
  • 热更新指的是应用程序运行时,修改程序代码后无需重启整个应用程序,而是只需要重新加载修改后的部分代码,使得修改的代码可以立即生效,通过这种方式,可以避免每一次修改后都需要重新启动应用程序,等待整个应用程序重新加载的情况出现,使得开发人员可以更加方便地进行代码调试和修改。

什么是微服务?

  • 微服务是一种经过良好架构设计的分布式架构方案
  • 微服务的架构它是属于一种分布式系统的架构。
微服务的优缺点:

优点:

  • 拆分粒度更小、服务更独立、耦合度更低

缺点:

  • 架构非常复杂,运维、监控、部署难度提高 

微服务的架构特征:

  • 单一职责:微服务的拆分粒度更小,每一个服务都对应唯一的业务能力,每个服务都围绕着具体业务进行构建,做到单一职责,避免重复业务开发

  • 面向服务:微服务要对外暴露业务接口(这样服务之间就可以做一些相互的调用了),服务提供统一标准的接口,与语言和技术无关

  • 自治:指的就是独立:团队独立、技术独立、数据独立(是指每个服务可以有自己独立的数据库)、部署独立(能够被独立的部署到生产环境)和交付独立

  • 隔离性强:服务调用要做好隔离、容错、降级,避免出现级联问题

微服务的上述特征其实是在给分布式架构制定一个标准,这些特征其实最终的目的就是为了实现高内聚、低耦合,降低服务之间的耦合度,(降低服务它所能产生影响的范围),提高服务的独立性和灵活性,避免整个集群的故障! 

因此,可以认为微服务是一种经过良好架构设计的分布式架构方案。 

  • 微服务它一种其实是分布式架构的一种,所谓分布式架构就是要把服务做拆分,而拆分的过程中其实会产生各种各样的问题需要去解决,而Spring Cloud其实仅仅是解决了服务拆分时的服务治理问题,至于其它的一些分布式的更复杂的一些问题,并没有给出解决方案,所以一个完整的微服务技术,要包含的不仅仅是Spring Cloud。

  • 微服务要做的第一件事情就是拆分因为传统的单体结构,所有的业务功能全部写在一起,随着业务越来越复杂,代码也变得耦合的越来越多,将来你想升级、维护就会很困难所以像一些大型的互联网项目,就必须去做拆分;
  • 微服务在做拆分的时候,会根据业务功能模块把一个单体的项目拆分成许多个独立的项目,每个项目完成一部分业务功能,将来独立开发和部署,我们把这样一个独立的项目称为一个服务;
  • 一个大型的互联网项目往往会包含数百甚至上千的服务,最终形成一个服务集群,而集群中的每个服务都要遵循单一职责的原则,并且要面向服务,对外暴露业务接口,这样服务之间就可以做一些相互的调用,只不过不同技术在实现这些接口的时候,可能会有差异;
  • 一个业务往往需要有多个服务共同来完成,比如说一个请求来了,它可能先去调了服务A,而服务A可能又调了服务B,然后又去调了服务C,当业务越来越多,越来越复杂的时候,这些服务之间的调用关系就会越来越复杂,这么复杂的一个调用关系一定需要我们去维护,想靠人去记录和维护,这是不可能的所以在微服务里,一定会有一个组件,叫做注册中心:它可以去维护微服务里面每个节点的信息,并且去监控这些节点的状态:它可以去记录微服务中每一个服务的IP、端口以及它能干什么事这些信息,当有一个服务需要调用另外的服务时,它不需要自己去记录对方的IP,只需要去找注册中心就行了,由注册中心去拉取对应的服务信息;
  • 并且将来随着服务越来越多,每一个服务都有自己的配置文件,如果将来有一些配置需要去做修改,将来如果要更改配置,难道我们手动的去微服务里面逐一去修改吗?这就太麻烦了,所以在微服务里还会有一个配置中心:它可以去统一的管理整个服务群体成千上百的这个配置信息,如果以后有配置需要变更,只需要去找到配置中心就可以了它会去通知相关的微服务,利用通知的方式去让对应的服务服务监控到配置的变化,从而实现配置的热更新;
  • 将来当我们的微服务一旦部署上线,用户就可以来访问我们了,但这个时候,还需要有一个网关组件,因为你这里有这么多的微服务,用户怎么知道该访问哪一个呢?而且也不是说你随便什么人都能来访问我们的服务吧,所以这些服务集群还需要有一个统一的服务网关作为入口,我们的服务网关一方面就是对用户身份对校验,另一方面就是由网关把用户的请求路由到我们的具体的服务当然在路由过程中,也可以去做一些负载均衡,并且路由的时候或者服务之间的调用过程中,我们还要做好服务的容错处理,避免因为服务故障带来级联失败,还要做好服务保护、隔离、降级等等这些措施;
  • 这时候呢,服务进入到你的请求去处理业务,该访问数据库的时候就去访问数据库,最后再把查询到的数据返回给用户,将来数据库肯定要做集群,但是你集群再庞大,也不可能有用户多把,所以数据库将来肯定无法抗住高并发的场景因此还会加入缓存,缓存就是把数据库数据放入到内存当中,内存查询效率肯定要比数据库快很多,而且这种缓存还不能是单体缓存,为了应对高并发,还要做成分布式缓存,也是一个集群:用户请求先到缓存,缓存未命中,再去查询数据库
  • 以后我们的业务中还会有一些复杂的搜索功能,简单查询可以走缓存,一些海量数据的复杂的搜索、统计和分析,缓存也做不了,这个时候就需要用到分布式搜索功能数据库将来主要的职责其实就是做一种数据的写操作,还有一些事务类型、对数据安全要求较高的一些数据存储;
  • 最后在微服务里边,还需要一种异步通信的消息队列组件因为对于这种分布式的服务或者微服务里面,它的业务往往会跨越多个服务,一个请求来了,先调的服务A,A再调B,B再去调C,整个业务的链路就很长,调用时长就会等于每个服务的执行时长之和所以其实性能是有一定的下降的,而异步通信的意思就是,请求来了,我调了服务A,服务A我不是去调你服务B和C,而是通知你们,发一条消息,你们两个赶紧干活去,于是,那两个哥们去干了,而服务A直接结束了,所以它的业务链路就会变短了,响应时间也缩短了,自然吞吐能力也就变强了,所以异步通信可以提高我们服务的并发,在一些类似于秒杀这样的高并发场景下就可以去利用了。

当然,我们如此庞大和复杂的一个服务,在运行的过程当中,如果出现了什么问题,就不太好排查所以在微服务运行过程中,我们还会引入两个新的组件来去解决服务的异常定位:

  1. 第一个是分布式日志服务它可以去统计整个集群当中成千上百的这些服务,它们的运行日志,统一的去做一个存储、统计和分析,将来如果出现问题,就比较好定位了;
  2. 而且还有第二个东西,叫做系统监控和链路追踪它可以去实时监控我们整个群体中每一个服务节点的一个运行状态、CPU的负载、内存的占用等等的情况,一旦出现任何的问题,直接可以定位到具体的某一个方法(栈信息),那么你就能够很快速的定位到异常所在了。
微服务技术  + 持续集成 = 完整的微服务技术栈(微服务的全套技术栈)

那么如此庞大、复杂的一个微服务集群,将来很有可能会达到成千上万的服务,这个时候,我们部署该怎么办呢?

  • 如果还是靠以前,人工去部署,显然不太现实,所以将来这些微服务集群还需要去做一种自动化的部署,我们就会利用Jenkins这样的工具,它可以对这些微服务项目进行自动化的编译,基于docker再去一些打包,形成镜像再基于kubernetes(K8s)或RANCHER这样的技术去实现自动化的部署,这一套我们称之为持续集成。

结合微服务的这些技术再加上持续集成,这才是完整的微服务技术栈!

  • DevOps:开发运维 

微服务技术对比

目前最流行的两种微服务解决方案是Spring Cloud和Dubbo。 

  • 微服务这种方案也需要技术框架来落地,全球的互联网公司都在积极尝试开发自己的微服务落地技术,在国内最知名的就是Spring Cloud和阿里巴巴的Dubbo  =>  不管是Spring Cloud还是Alibaba的Dubbo,都是微服务方案的实现,所以它们所包含的组件实现的功能基本是一致的,首先它们都需要去做微服务的拆分,形成微服务集群,而集群中的每个服务都要遵循单一职责的原则,并且要面向服务,对外暴露业务接口,这样服务之间就可以做一些相互的调用了...
  • 微服务这种分布式架构方案的落地,其实在Java领域最引人注目的就是SpringCloud提供的方案了。

Spring Cloud和Dubbo其实它们在实现的过程中,其实是有一些差异的:

微服务技术对比

Dubbo技术它早在2012年左右就已经开源出来了,是Alibaba公司开源的,但是那个时候微服务技术在国内可能连听都没听过,所以说Dubbo并不是严格意义上的一个微服务技术,Dubbo最开始只是一个简单的RPC调用框架,在那个时候,它的核心就是服务的远程调用以及注册发现所以在Dubbo里面技术体系并不完整,而且注册中心也不是Dubbo里面自己实现的,而是依赖于zookeeper、Redis去做的这些并不是专业的注册中心(半吊子),像Redis是做缓存的,zookeeper是做集群管理的所以Dubbo并不具备完善的注册中心功能而服务的这种远程调用才是Dubbo的核心Dubbo它最开始的优势是在于自定义的Dubbo通信协议,效率要比HTTP协议高不少在当时,Dubbo专门基于这种TCP的协议定义了一套标准,也就是Dubbo协议,Dubbo协议是一种基于TCP协议的RPC协议,所以遵循Dubbo这种远程调用,必须得定义Dubbo这种标准的接口。而且配置中心和服务网关Dubbo都没有实现,至于服务监控Dubbo里面只提供了一个非常基本的dubbo-admin功能,只是来统计一下服务调用时的一个响应时间、QPS等等,功能非常单一,所以Dubbo所实现的这个服务的治理,其实是非常不完善的。

而到了2015年~2017年这段时间,可以说是微服务技术井喷的时候,各种各样的微服务技术层出不穷,但是一直没有一个一统江湖的,直到Spring Cloud的出现,Spring Cloud它并不是发明了什么东西,而是整合,它把全球各个公司的开源的这种微服务技术都给整合起来了,而后形成了一套完整的微服务技术体系,是一个集大成者,它里面的功能是非常完善的,它首先有完善的注册中心,里面包含了Eureka、Consul这种专业的注册中心并且Spring Cloud的服务调用它并没有去整一种全新的协议和标准,它用的是直接基于HTTP协议的标准的Feign客户端,由它来去发送HTTP的请求(不用它也行,只要遵循Restful风格 => 基于HTTP协议的RESTful API)Spring Cloud还提供了专业的配置中心,叫做SpringCloudConfig,另外Spring Cloud还提供了SpringCloudGetway以及Zuul两个不同的网关,在目前比较流行的是SpringCloudGetway网关,因为它里面基于了最新的响应式编程,吞吐能力非常强,还有服务监控和保护 - Hystrix,Hystrix它是一个非常强大的服务保护技术,但是它里面也带有一些监控的功能,但核心是保护,主要就是实现了服务的隔离和熔断等等一些相关技术,功能也是十分强大。

由于Dubbo和Spring Cloud相比还是存在比较大的差距,Dubbo它不是一个完善的微服务的技术栈,所以阿里巴巴也认识到了这一点,因此阿里巴巴为了追赶Spring Cloud的脚步,形成了一套能够与Spring Cloud无缝衔接的开源组件和工具,也就是Spring Cloud Alibaba,Spring Cloud Alibaba本质上是实现了Spring Cloud标准的,所以可以认为Spring Cloud Alibaba是Spring Cloud的一部分,Spring Cloud Alibaba是Spring Cloud的子项目,Spring Cloud Alibaba是Spring Cloud的拓展,用于构建云原生微服务应用。

Spring Cloud和Spring Cloud Alibaba在概念和功能上有很大的相似性,都致力于构建和管理微服务架构,但Spring Cloud Alibaba更加专注于阿里巴巴云生态,并提供了一些额外的功能和针对云原生应用的支持。

企业需求

Spring Cloud 

  • Spring Cloud是目前国内使用最广泛的微服务框架。
  • Spring Cloud是微服务架构的一站式解决方案,集成了各种优秀的微服务功能组件。

官网地址:Spring Cloud

中文网站:Spring Cloud中文网-官方文档中文版 

Spring Cloud集成了各种微服务功能组件,并基于Spring Boot实现了这些组件的自动装配,从而提供了良好的开箱即用体验。

其中常见的组件包括:

另外,Spring Cloud底层是依赖于Spring Boot的,Spring Cloud是一个基于Spring Boot实现的服务治理工具包,Spring Boot专注于快速、方便的开发单个微服务(单体架构应用的开发),而Spring Cloud关注于全局的微服务整合和管理,Spring Cloud是构建在Spring Boot之上的一个服务治理框架,并且有版本的兼容关系,如下:

微服务架构的项目结构

最左边为客户端:
  • IoT:物联网设备
  • Mobile:移动端
  • Browser:浏览器

API Getway:API网关

Service registry:服务注册中心     registry:注册,注册表

Config server:配置服务,配置中心

Microservices:微服务

Distributed:分布式   trace:追踪    分布式追踪:追踪每个请求的流向/走向

一些专业术语

  • 服务器:用于运行服务的计算机,这些计算机可以是虚拟机/物理机/云服务器等,服务器分为软件服务器与硬件服务器软件服务器:类似于Tomcat这种跑项目的程序硬件服务器:物理设备,用来部署项目的电脑(一般性能要比个人电脑好)
  • 服务:成品软件,可以独立运行起来,一个能够对外提供功能的程序,比如MySQL、Redis以及我们写好的程序
  • 框架:半成品的软件,用于帮助开发人员快速开发系统功能,需要借助其他服务来运行应用
  • 微服务:小的服务一个完整项目可以拆分为N个子项目,这些子项目能够独立运行,独立对外提供功能
  • 节点:一台服务器;一个虚拟机;一个容器(Docker => 轻量级的虚拟机?)
  • 实例:描述的是具体某一个服务,运行了几个进程
  • 垂直扩展:纵向的扩展能力,垂直扩展是指增强单机(单台机器)的硬件性能
  • 水平扩展:横向拓展,增加系统的规模,通过增加更多的服务器或者程序实例来分散负载,从而提升存储能力和计算能力
  • 容错率:允许出错的比例,允许服务器集群(一堆服务器)错误(异常/故障)出现的范围和概率。
  • 高内聚,低耦合:内聚 - 模块或组件内部的元素之间的联系紧密程序,程序功能独立    耦合 - 模块或组件之间的相互依赖程序,程序间交互  以Java为例,高内聚,低耦合:设计类时尽量边界清晰,功能简单,类与类之间的交互尽可能少,减少类与类之间的相互调用 
  • 流量:访问量,请求次数
  • 服务间的依赖:项目与项目间的调用,程序与程序间的调用
  • 资源调度:调度 - 负责分配资源    开发中的资源:服务器,内存,CPU,IO,网络等
  • 单点(Signle Point):指的就是一个(这个服务只运行了一个实例:一个MySQL只运行了一份;这个服务器只有一个节点),系统或架构中的单个组件、服务或资源
  • 单点故障(Signle Point of Failure,简称SPoF):如果项目或程序部署在唯一的一个服务器上,如果这个服务器挂了,那么整个系统也就挂了,单点故障会导致整个系统或应用无法正常工作
  • 宕机(Downtime):服务器挂掉了
  • 负载(Load):是指系统正在处理或等待处理的工作量或任务数,它通常用于衡量系统资源的使用情况或性能状况。比如CPU负载:指系统中正在使用CPU资源的工作量。

集群(Cluster)

  • 我们通常讲的集群指的是分布式下的集群,集群是属于分布式下的一个子的概念
  • 集群就是把一个服务实例变成多个服务实例,集群中的每台服务器就叫做这个集群的一个"节点"(Nodes),所有节点就构成了一个集群,每个节点都提供相同的服务。
现在的问题是用户的请求究竟由哪个节点来处理呢?
  • 最好能够让此时此刻负载较小的节点来处理,这样使得每个节点的压力都比较平均;

  • 要实现这个功能,就需要在所有节点之前增加一个 "调度者" 的角色,用户的所有请求都先交给它,然后它根据当前所有节点的负载情况,决定将这个请求交给哪个节点处理,这个"调度者"叫做负载均衡服务器。

注意:

  • 集群不一定是分布式,反例:我在一台机器上运行多个相同的服务,比如我在一台机器上面运行三个Redis实例,它是集群,但是它不是分布式(伪集群或伪分布式) 
集群的优点:
  • 资源可以横向扩展,可以解决单点故障问题
集群的缺点:
  • 维护成本较高,且会有本地缓存(Session属于本地缓存)数据无法共享问题分布式Session问题 - Session无法共享:由于Session是存储在服务器内存中的,当对服务器进行横向扩展时,无法将服务器内存中的Session一起共享,因此用户访问另一台服务器时没有数据,此时产生分布式Session问题) 
分布式Session的解决方案:
  • 解决方案一:负载均衡均衡算法,保障用户只会访问到某一个服务器;
  • 解决方案二:远端缓存(Redis):将缓存信息不存储到服务器,而是存储到另外的服务中,所有的服务都去访问远端缓存获取数据,从而实现数据共享。 

  

相关文章:

  • iOS 让界面元素的文字随着语言的更改而变化——本地化文字跟随
  • 如何在 Unbuntu 下安装配置 Apache Zookeeper
  • 一触即发!拓世法宝商业数字人一体机,化身数字员工,助你开拓连锁餐饮市场
  • 工程车云管家|叉车智能管家安卓主板方案
  • FPGA配置采集AR0135工业相机,提供2套工程源码和技术支持
  • 算法题:33. 搜索旋转排序数组(二分法)
  • sqli-labs-1
  • nacos配置中心docker部署、配置及 goLang 集成使用
  • Kafka(消息队列)--简介
  • 单基因泛癌+实验简单验证,要素丰富,没研究方向的赶紧上车
  • Nginx 实现负载均衡
  • java数据结构(红黑树)set集合 HashSet HashSet三个问题 LinkedHashSetTreeSet TreeSet集合默认规则排序规则
  • 软件测试面试怎样介绍自己的测试项目?会问到什么程度?
  • Zookeeper经典应用场景实战(一)
  • 11月9日,每日信息差
  • 「前端早读君006」移动开发必备:那些玩转H5的小技巧
  • 30秒的PHP代码片段(1)数组 - Array
  • CSS进阶篇--用CSS开启硬件加速来提高网站性能
  • httpie使用详解
  • Java 最常见的 200+ 面试题:面试必备
  • Java反射-动态类加载和重新加载
  • js算法-归并排序(merge_sort)
  • Redis中的lru算法实现
  • webpack4 一点通
  • Work@Alibaba 阿里巴巴的企业应用构建之路
  • Zsh 开发指南(第十四篇 文件读写)
  • 从零到一:用Phaser.js写意地开发小游戏(Chapter 3 - 加载游戏资源)
  • 翻译:Hystrix - How To Use
  • 给Prometheus造假数据的方法
  • 构造函数(constructor)与原型链(prototype)关系
  • 每天一个设计模式之命令模式
  • 排序算法学习笔记
  • 如何在 Tornado 中实现 Middleware
  • 推荐一个React的管理后台框架
  • 我与Jetbrains的这些年
  • 因为阿里,他们成了“杭漂”
  • 正则与JS中的正则
  • ​LeetCode解法汇总1276. 不浪费原料的汉堡制作方案
  • $.ajax()方法详解
  • (C语言)fread与fwrite详解
  • (强烈推荐)移动端音视频从零到上手(下)
  • (四)库存超卖案例实战——优化redis分布式锁
  • (一)SpringBoot3---尚硅谷总结
  • (一)搭建springboot+vue前后端分离项目--前端vue搭建
  • (转)fock函数详解
  • (转)四层和七层负载均衡的区别
  • /usr/local/nginx/logs/nginx.pid failed (2: No such file or directory)
  • @Validated和@Valid校验参数区别
  • @我的前任是个极品 微博分析
  • [ffmpeg] 定制滤波器
  • [HackMyVM]靶场Crossbow
  • [hive] posexplode函数
  • [IE技巧] 使IE8以单进程的模式运行
  • [Linux]使用CentOS镜像与rpm来安装虚拟机软件
  • [ndss 2023]确保联邦敏感主题分类免受中毒攻击