深入理解 Spring Cloud 核心组件与底层原理

点击上方“Java基基”,选择“设为星标”

做积极的人,而不是积极废人!

源码精品专栏

 

来源:blog.csdn.net/qq_40378034/article/details/86552677

  • 一,Spring Cloud核心组件:Eureka

    • Netflix尤里卡

    • 尤里卡详解

    • 1,服务提供者

    • 2,服务消费者

    • 3,服务注册中心

  • 二,Spring Cloud核心组件:Ribbon

  • 三,Spring Cloud核心组件:假装

  • 四,Spring Cloud核心组件:Hystrix

  • 五,Spring Cloud核心组件:Zuul

  • 六,总结


之前一直在看Spring Cloud及微服务架构对Spring Cloud的主要组件的原理有了更深入一点的理解,特地做一下总结。

一,Spring Cloud核心组件:Eureka

Netflix尤里卡

1,Eureka服务端:也称服务注册中心,同其他服务注册中心一样,支持高可用配置。如果Eureka以分配模式部署,当发生中有分片出现故障时,那么Eureka就转入自我保护模式。它允许在分片故障期间继续提供服务的发现和注册,当故障分片恢复运行时,可用中其他分片会把它们的状态再次同步回来

2,Eureka客户端:主要处理服务的注册与发现。客户端服务通过注解和参数配置的方式,嵌入在客户端应用程序的代码中,在应用程序运行时,Eureka客户端想注册中心注册自身提供同时,它也能从服务端查询当前注册的服务信息并把它们缓存到本地并替换地刷新服务状态

3,Eureka Server的高可用实际上就是将自己作为服务向其他注册中心注册自己,这样就可以形成各个相互注册的服务注册中心,以实现服务清单的相互同步,达到高可用效果

尤里卡详解

1,服务提供者

A.服务注册

服务提供者在启动的时候会通过发送REST请求的方式将自己注册到Eureka Server上,同时带上了自己的服务的一些元数据信息。EurekaServer接收到这个REST请求之后,将元数据信息存储在一个双层结构地图中,其中第一层的键是服务名,第二层的键是具体服务的实例名

B.服务同步

两个服务提供者分别注册到了两个不同的服务注册中心上,然后,它们的信息分别被两个服务注册中心所维护。此时,由于服务注册中心之间因互相注册为服务,当服务提供者发送注册请求到一个服务注册中心时,它会调用请求转发给转化中相连的其他注册中心,从而实现注册中心之间的服务同步。通过服务同步,两个服务提供者的服务信息就可以通过两个台服务注册中心中的任意一台获取到

C.服务续约

在注册完服务之后,服务提供者会维护一个心跳到持续告诉Eureka Server:“我还活着”,以防止Eureka Server的剔除任务转到服务实例从服务列表中排除出来,我们称该操作为服务续约

# 定义服务续约任务的调用间隔时间,默认30秒eureka.instance.lease-renewal-interval-in-seconds=30# 定义服务失效的时间,默认90秒eureka.instance.lease-expiration-duration-in-seconds=90

2,服务消费者

A.获取服务

当我们启动服务消费者的时候,它会发送一个REST请求给服务注册中心,来获取上面注册的服务清单。为了性能考虑,Eureka Server会维护一份替代的服务清单来给给客户端,同时该缓存清单会每隔30秒更新一次

# 缓存清单的更新时间,默认30秒eureka.client.registry-fetch-interval-seconds=30

B.服务调用

服务消费者在获取服务清单后,通过服务名获得更多具体提供的服务的实例名称和该实例的元数据信息。在ribbon中会交替采用交替的方式进行调用,从而实现客户端的负载均衡

对于访问实例的选择,Eureka中有Region和Zone的概念,一个Region中可以包含多个Zone,每个服务客户端需要被注册到一个Zone中,所以每个客户端对应一个Region和一个Zone。在进行服务调用的时候,优先访问同处一个一个Zone中的服务提供方,若访问不到,就访问其他的Zone

C.服务下线

当服务实例进行正常的关闭操作时,它会触发一个服务下线的REST请求给Eureka Server,告诉服务注册中心:“我要下线了”。服务端在接收到请求之后,进入服务状态置为下线(DOWN),并把该下线事件传播出去

3,服务注册中心

无效剔除

Eureka Server在启动的时候会创建一个定时任务,每隔一次间隔(更改为60秒)将当前清单中超时(至少为90秒)没有续约的服务剔除出去

B.自我保护

在服务注册中心的信息面板中出现红色警告信息:

该警告就是触发了Eureka Server的自我保护机制。EurekaServer在运行期间,会统计心跳失败的比例在15分钟之内是否超过85%,如果出现低于的情况,Eureka Server可能会导致当前的实例注册信息保护起来,让这些实例不会过期,恢复保护这些注册信息。但是,在此之后,内部实例若出现问题,那么客户端很容易拿到实际已经不存在的服务实例,会出现调用失败的情况,所以客户端必须要有容错机制,某些可以使用请求重试,断路器等机制

# 关闭保护机制,以确保注册中心可以将不用的实例正确剔除(本地调试可以使用,线上不推荐)eureka.server.enable-self-preservation=false

二,Spring Cloud核心组件:Ribbon

Ribbon是一个基于HTTP和TCP的客户端负载均衡器,它可以在通过客户端中配置的ribbonServerList服务端列表去进行访问以达到服务均衡的作用。当Ribbon和Eureka联合使用时,Ribbon的服务实例清单RibbonServerList会被DiscoveryEnabledNIWSServerList改写,扩展成从Eureka注册中心中获取服务端列表。同时它也会用NIWSDiscoveryPing来取代IPing,并强制委托给Eureka来去定服务端是否已经启动

在客户端负载均衡中,所有客户端上游都维护着自己要访问的服务端清单,而这些服务端的清单来自于服务注册中心(称为Eureka)。在客户端负载均衡中也需要心跳去维护服务端清单的健康性,只是这个步骤需要与服务注册中心配合完成。整编:微信公众号,搜云库技术团队,ID:souyunku

通过Spring Cloud Ribbon的封装,我们在微服务架构中使用客户端负载均衡初始化只需要如下两步:

1,服务提供者只需要启动多个服务实例和注册到一个注册中心或多个相关联的服务注册中心

2,服务消费者直接通过调用被@LoadBalanced注解修饰过的RestTemplate来实现面向服务的接口调用

三,Spring Cloud核心组件:假装

Feign的关键机制是使用了动态代理

1,首先,对某个接口定义了@FeignClient注解,Feign就会针对这个接口创建一个动态代理

2,接着调用接口的时候,本质就是调用Feign创建的动态代理

3, Feign的动态代理会根据在接口上的@RequestMapping等注解,来动态构造要请求的服务的地址

4,针对这个地址,发起请求,解析响应

Feign是和丝带以及Eureka紧密协作的

1,首先Ribbon会从Eureka Client里获取到对应的服务记录,也就知道了所有的服务都部署在了其中机器上,在监听到的端口上

2,然后丝带就可以使用交替的Round Robin算法,从中选择一台机器

3, Feign就会针对这台机器,构造并发起请求

四,Spring Cloud核心组件:Hystrix

在微服务架构中,存在着那么多的服务单元,如果一个单元出现故障,就很容易因依赖关系而引发故障的蔓延,最终导致整个系统的崩溃,这样的架构相较传统架构更加复杂。这样的问题,产生了断路器等类别的服务保护机制

在分布式架构中,当某个服务单元发生故障之后,通过断路器的故障监控,向调用方返回一个错误响应,而不是连续的等待。占用不释放,避免了故障在分布式系统中的蔓延

Hystrix具有服务降级,服务熔断,线程和信号隔离,请求缓存,请求合并以及服务监控等强大功能

Hystrix使用舱壁模式实现线程池的隔离,它会为每一个依赖服务创建一个独立的线程池,这样就算是某个依赖服务出现重复过高的情况,也只是该依赖服务的调用会产生影响,而不会拖慢其他的依赖服务

五,Spring Cloud核心组件:Zuul

Spring Cloud Zuul通过与Spring Cloud Eureka进行整合,将自身注册为Eureka服务治理下的应用,同时从Eureka中获得了所有其他微服务的实例信息

对于路由规则的维护,Zuul替代通过以服务名作为ContextPath的方式来创建路由映射

Zuul提供了一套过滤器机制,可以支持在API网关无附上进行统一调用来对微服务接口做初始过滤,已实现对微服务接口的拦截和校正。整编:微信公众号,搜云库技术团队,ID:souyunku

六,总结

Eureka:各个服务启动时,Eureka Client都会将服务注册到Eureka Server,并且Eureka Client还可以反过来从Eureka Server拉取到,从而知道其他服务在哪里

功能区:服务间发起请求的时候,基于丝带做负载均衡,从一个服务的多台机器中选择一台

Feign:基于Feign的动态代理机制,根据注解和选择的机器,分割请求URL地址,发起请求

Hystrix:发起请求是通过Hystrix的线程池来走的,不同的服务走不同的线程池,实现了不同服务调用的隔离,避免了服务雪崩的问题

Zuul:如果前端,移动端要调用约会系统,统一从Zuul网关进入,由Zuul网关转发请求给对应的服务



欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢

已在知识星球更新源码解析如下:

最近更新《芋道 SpringBoot 2.X 入门》系列,已经 20 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。

提供近 3W 行代码的 SpringBoot 示例,以及超 4W 行代码的电商微服务项目。

获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值