SpringCloud六大组件分别为
- 注册中心: Eureke(ZooKeeper)
- 服务远程调用:Feign (Dubbo)
- 负载均衡:Ribbon
- 配置中心:Spring Cloud Config
- 服务网关:SpirngCloudGateway,Zuul
- 服务监控和保护: Hystrix (Sentinel)
为了方便理解假设一个业务场景
假设现在开发一个电商网站,要实现支付订单功能:流程如下
-
创建一个订单后,如果用户立刻支付了这个订单,我们需要将这个订单状态更新为(已经支付)
-
扣减相对应的商品库存
-
通知仓储中心,进行发货
-
给用户这次购物怎加相对应的积分
针对上述流程,我们需要有订单服务、库存服务、仓储服务、积分服务,整个流程的大体思路如下:
-
用户针对一个订单完成支付后,就回去找订单服务,更新订单状态
-
订单服务调用库存服务,完成相应的功能
-
订单服务调用仓储服务,完成相应的功能
-
订单服务调用积分服务,完成相应的功能
整个过程可以如下图所示:
一、注册中心 Eureka
首先考虑一个问题,订单服务要调用库存服务、仓储服务、积分服务,如何调用呢?
答:订单服务根本不知道上述服务在哪台服务器上,所以没法调用,而Eureka的作用就是来告诉订单服务它想调用的服务在哪台服务器上,Eureka有客户端和服务端,每一个服务上面都有Eureka客户端,可以把本服务的相关信息注册到Eureka服务端上,那么我们的订单服务就可以就可以找到库存服务、仓储服务、积分服务了。
我们上述的业务使用Eureka后如下图:
总结:
-
Eurake客户端:负责将这个服务的信息注册到Eureka服务端中
-
Eureka服务端:相当于一个注册中心,里面有注册表,注册表中保存了各个服务所在的机器和端口号,可以通过Eureka服务端找到各个服务
二、服务远程调用 Feign
通过上面的Eureka,现在订单服务确实知道库存服务、积分服务、仓储服务在哪了,但是我们如何去调用这些服务呢,如果我们自己去写很多代码调用那就太麻烦了,而SpringCloud已经为我们准备好了一个核心组件:Feign。
接下来看如何通过Feign让订单服务调用库存服务,注意Feign也是用在消费者端的;
订单服务:
库存服务:
没有底层的建立连接、构造请求、解析响应的代码,直接就是用注解定义一个 FeignClient接口,然后调用那个接口就可以了。
Feign Client会在底层根据你的注解,跟你指定的服务建立连接、构造请求、发起靕求、获取响应、解析响应,等等。
问题来了,Feign是如何做到的呢?其实Feign的一个机制就是使用了动态代理:
-
首先,如果你对某个接口定义了
@FeignClient
注解,Feign就会针对这个接口创建一个动态代理 -
接着你要是调用那个接口,本质就是会调用 Feign创建的动态代理,
-
Feign的动态代理会根据你在接口上的
@RequestMapping
等注解,来动态构造出你要请求的服务的地址 -
最后针对这个地址,发起请求、解析响应
三:服务网关 SpirngCloudGateway,Zuul
类似于服务器端的nginx
该组件是负责网络路由的,假设你后台部署了几百个服务,现在有个前端兄弟,人家请求是直接从浏览器那儿发过来的。打个比方:人家要请求一下库存服务,你难道还让人家记着这服务的名字叫做inventory-service
,并且部署在5台机器上,就算人家肯记住这一个,那你后台可有几百个服务的名称和地址呢?难不成人家请求一个,就得记住一个?哈哈哈
上面这种情况,压根儿是不现实的。所以一般微服务架构中都必然会设计一个网关在里面,像android、ios、pc前端、微信小程序、H5等等,不用去关心后端有几百个服务,就知道有一个网关,所有请求都往网关走,网关会根据请求中的一些特征,将请求转发给后端的各个服务。
四:配置中心: Spring Cloud Config
在分布式微服务系统中,几乎所有服务的运行都离不开配置文件的支持,这些配置文件通常由各个服务自行管理,以 properties 或 yml 格式保存在各个微服务的类路径下,例如application.properties 或 application.yml 等。
这种将配置文件散落在各个服务中的管理方式,存在以下问题:
- 管理难度大:配置文件散落在各个微服务中,难以管理。
- 安全性低:配置跟随源代码保存在代码库中,容易造成配置泄漏。
- 时效性差:微服务中的配置修改后,必须重启服务,否则无法生效。
- 局限性明显:无法支持动态调整,例如日志开关、功能开关。
为了解决这些问题,通常我们都会使用配置中心对配置进行统一管理。
Spring Cloud Config
Spring Cloud Config 是由 Spring Cloud 团队开发的项目,它可以为微服务架构中各个微服务提供集中化的外部配置支持。
简单点说就是,Spring Cloud Config 可以将各个微服务的配置文件集中存储在一个外部的存储仓库或系统(例如 Git 、SVN 等)中,对配置的统一管理,以支持各个微服务的运行。
Spring Cloud Config 包含以下两个部分:
- Config Server:也被称为分布式配置中心,它是一个独立运行的微服务应用,用来连接配置仓库并为客户端提供获取配置信息、加密信息和解密信息的访问接口。
- Config Client:指的是微服务架构中的各个微服务,它们通过 Config Server 对配置进行管理,并从 Config Sever 中获取和加载配置信息。
Spring Cloud Config 默认使用 Git 存储配置信息,因此使用 Spirng Cloud Config 构建的配置服务器天然就支持对微服务配置的版本管理。我们可以使用 Git 客户端工具方便地对配置内容进行管理和访问。除了 Git 外,Spring Cloud Config 还提供了对其他存储方式的支持,例如 SVN、本地化文件系统等。
Spring Cloud Config 工作原理
Spring Cloud Config 工作原理如下图。
Spring Cloud Config 工作流程如下:
- 开发或运维人员提交配置文件到远程的 Git 仓库。
- Config 服务端(分布式配置中心)负责连接配置仓库 Git,并对 Config 客户端暴露获取配置的接口。
- Config 客户端通过 Config 服务端暴露出来的接口,拉取配置仓库中的配置。
- Config 客户端获取到配置信息,以支持服务的运行。
五:负载均衡 Ribbon
上面可以通过Eureka可以找到服务,然后通过Feign去调用服务,但是如果有多台机器上面都部署了库存服务,我应该使用Feign去调用哪一台上面的服务呢,这个时候就需要Ribbon闪亮登场了,它在服务消费者端配置和使用,它的作用就是负载均衡。
服务间发起请求的时候,服务消费者方基于Ribbon服务做到负载均衡,从服务提供者存储的多台机器中选择一台,如果一个服务只在一台机器上面,那就用不到Ribbon选择机器了,如果有多台机器,那就需要使用Ribbon选择之后再去使用
然后默认使用的负载均衡算法是轮询算法,Ribbon会从Eureka服务端中获取到对应的服务注册表,然后就知道相应服务的位置,然后Ribbon根据设计的负载均衡算法去选择一台机器,Feigin就会针对这些机器构造并发送请求
六:服务监控和保护: Hystrix (Sentinel)
在微服务架构里,一个系统会有多个服务,以本文的业务场景为例:订单服务在一个业务流程里需要调用三个服务,现在假设订单服务自己最多只有100个线程可以处理请求,如果积分服务出错,每次订单服务调用积分服务的时候,都会卡住几秒钟,然后抛出—个超时异常。
分析下这样会导致什么问题呢?如果系统在高并发的情况下,大量请求涌过来的时候,订单服务的100个线程会卡在积分服务这块,导致订单服务没有一个多余的线程可以处理请求,这种问题就是微服务架构中恐怖的服务器雪崩问题,这么多的服务互相调用要是不做任何保护的话,某一个服务挂掉会引起连锁反应,导致别的服务挂掉
上述描述如下图所示:
但是我们想一下,即使积分服务挂了,那订单服务也不应该挂掉啊,我们只要让存储服务和仓储服务正常工作就可以了,至于积分服务我们后期可以手动给用户加上积分,这个时候就轮到Hystrix闪亮登场了,Hystrix是隔离、熔断以及降级的一个框架,说白了就是Hystrix会搞很多小线程池然后让这些小线程池去请求服务,返回结果。
Hystrix相当于是个中间过滤区,如果我们的积分服务挂了,那我们请求积分服务直接就返回了,不需要等待超时时间结束抛出异常,这就是所谓的熔断,但是也不能啥都不干就返回啊,不然我们之后手动加积分咋整啊,那我们每次调用积分服务就在数据库里记录一条消息,这就是所谓的降级,Hystrix隔离、熔断和降级的全流程如下:
服务隔离、熔断、降级
九、简单总结
-
Eureka:服务启动的时候,服务上的Eureka客户端会把自身注册到Eureka服务端,并且可以通过Eureka服务端知道其他注册的服务
-
Ribbon:服务间发起请求的时候,服务消费者方基于Ribbon服务做到负载均衡,从服务提供者存储的多台机器中选择一台,如果一个服务只在一台机器上面,那就用不到Ribbon选择机器了,如果有多台机器,那就需要使用Ribbon选择之后再去使用
-
Feign:Feign使用的时候会集成Ribbon,Ribbon去Eureka服务端中找到服务提供者的所在的服务器信息,然后根据随机策略选择一个,拼接Url地址后发起请求
-
Hystrix:发起的请求是通过Hystrix的线程池去访问服务,不同的服务通过不同的线程池,实现了不同的服务调度隔离,如果服务出现故障,通过服务熔断,避免服务雪崩的问题 ,并且通过服务降级,保证可以手动实现服务正常功能
-
Zuul:如果前端调用后台系统,统一走zull网关进入,通过zull网关转发请求给对应的服务
-
Spring Cloud Config: 可以为微服务架构中各个微服务需要的(application.properties 或 application.yml )配置文件提供集中化的外部配置支持。
更多推荐
【SpringCloud】六大组件及作用
发布评论