SpringCloud原理详解
之前⼀直在看《Spring Cloud微服务实战》,最近⼜看了架构笔记的《拜托!⾯试请不要再问我Spring Cloud底层原理》,对Spring Cloud的主要组件的原理有了更深的理解,特地做⼀下总结
⼀、Spring Cloud核⼼组件:Eureka
springcloud难学吗(1)Netflix Eureka
1)、Eureka服务端:也称服务注册中⼼,同其他服务注册中⼼⼀样,⽀持⾼可⽤配置。如果Eureka以集模式部署,当集中有分⽚出现故障时,那么Eureka就转⼊⾃我保护模式。它允许在分⽚故障期间继续提供服务的发现和注册,当故障分⽚恢复运⾏时,集中其他分⽚会把它们的状态再次同步回来
2)、Eureka客户端:主要处理服务的注册与发现。客户端服务通过注解和参数配置的⽅式,嵌⼊在客户端应⽤程序的代码中,在应⽤程序运⾏时,Eureka客户端想注册中⼼注册⾃⾝提供的服务并周期性地发送⼼跳来更新它的服务租约。同时,它也能从服务端查询当前注册的服务信息并把它们缓存到本地并周期性地刷新服务状态
3)、Eureka Server的⾼可⽤实际上就是将⾃⼰作为服务向其他注册中⼼注册⾃⼰,这样就可以形成⼀组互相注册的服务注册中⼼,以实现服务清单的互相同步,达到⾼可⽤效果
(2)Eureka详解
1)、服务提供者
A.服务注册
服务提供者在启动的时候会通过发送REST请求的⽅式将⾃⼰注册到Eureka Server上,同时带上了⾃⼰服务的⼀些元数据信息。Eureka Server接收到这个REST请求之后,将元数据信息存储在⼀个双层结构Map中,其中第⼀层的key是服务名,第⼆层的key是具体服务的实例名
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秒
istry-fetch-interval-seconds=30
B.服务调⽤
服务消费者在获取服务清单后,通过服务名可以获得具体提供服务的实例名和该实例的元数据信息。在Ribbon中会默认采⽤轮询的⽅式进⾏调⽤,从⽽实现客户端的负载均衡
对于访问实例的选择,Eureka中有Region和Zone的概念,⼀个Region中可以包含多个Zone,每个服务客户端需要被注册到⼀个Zone中,所以每个客户端对应⼀个Region和⼀个Zone。在进⾏服务调⽤的时候,优先访问同处⼀个⼀个Zone中的服务提供⽅,若访问不到,就访问其他的Zone
C.服务下线
当服务实例进⾏正常的关闭操作时,它会触发⼀个服务下线的REST请求给Eureka Server,告诉服务注册中⼼:“我要下线了”。服务端在接收到请求之后,将该服务状态置为下线(DOWN),并把该下线事件传播出去
3)、服务注册中⼼
A.失效剔除
Eureka Server在启动的时候会创建⼀个定时任务,默认每隔⼀段时间(默认为60秒)将当前清单中超时(默认为90秒)没有续约的服务剔除出去
B.⾃我保护
在服务注册中⼼的信息⾯板中出现红⾊警告信息:
该警告就是触发了Eureka Server的⾃我保护机制。Eureka Server在运⾏期间,会统计⼼跳失败的⽐例在15分钟之内是否低于85%,如果出现低于的情况,Eureka Server会将当前的实例注册信息保护起来,让这些实例不会过期,尽可能保护这些注册信息。但是,在这段保护期间内实例若出现问题,那么客户端很容易拿到实际已经不存在的服务实例,会出现调⽤失败的情况,所以客户端必须要有容错机制,⽐如可以使⽤请求重试、断路器等机制
# 关闭保护机制,以确保注册中⼼可以将不⽤的实例正确剔除(本地调试可以使⽤,线上不推荐)
able-self-preservation=false
⼆、Spring Cloud核⼼组件:Ribbon
Ribbon是⼀个基于HTTP和TCP的客户端负载均衡器,它可以在通过客户端中配置的ribbonServerList服务端列表去轮询访问以达到服务均衡的作⽤。当Ribbon和Eureka联合使⽤时,Ribbon的服务实例清单RibbonServerList会被DiscoveryEnabledNIWSServerList重写,扩展成从Eureka注册中⼼中获取服务端列表。同时它也会⽤NIWSDiscoveryPing来取代IPing,它将职责委托给Eureka来去定服务端是否已经启动
在客户端负载均衡中,所有客户端节点都维护着⾃⼰要访问的服务端清单,⽽这些服务端的清单来⾃于服务注册中⼼(⽐如Eureka)。在客户端负载均衡中也需要⼼跳去维护服务端清单的健康性,只是这个步骤需要与服务注册中⼼配合完成
通过Spring Cloud Ribbon的封装,我们在微服务架构中使⽤客户端负载均衡调⽤只需要如下两步:
服务提供者只需要启动多个服务实例并且注册到⼀个注册中⼼或是多个相关联的服务注册中⼼
服务消费者直接通过调⽤被@LoadBalanced注解修饰过的RestTemplate来实现⾯向服务的接⼝调⽤
三、Spring Cloud核⼼组件:Fegin
Fegin的关键机制是使⽤了动态代理
1)、⾸先,对某个接⼝定义了@FeginClient注解,Fegin就会针对这个接⼝创建⼀个动态代理
2)、接着调⽤接⼝的时候,本质就是调⽤Fegin创建的动态代理
3)、Fegin的动态代理会根据在接⼝上的@RequestMapping等注解,来动态构造要请求的服务的地址
4)、针对这个地址,发起请求、解析响应
Fegin是和Ribbon以及Eureka紧密协作的
1)、⾸先Ribbon会从Eureka Client⾥获取到对应的服务注册表,也就知道了所有的服务都部署在了哪些机器上,在监听哪些端⼝
2)、然后Ribbon就可以使⽤默认的Round Robin算法,从中选择⼀台机器
3)、Fegin就会针对这台机器,构造并发起请求
四、Spring Cloud核⼼组件:Hystrix
在微服务架构中,存在着那么多的服务单元,若⼀个单元出现故障,就很容易因依赖关系⽽引发故障的蔓延,最终导致整个系统的瘫痪,这样的架构相较传统架构更加不稳定。为了解决这样的问题,产⽣了断路器等⼀系列的服务保护机制
在分布式架构中,当某个服务单元发⽣故障之后,通过断路器的故障监控,向调⽤⽅返回⼀个错误响应,⽽不是长时间的等待。这样就不会使得线程因调⽤故障服务被长时间占⽤不释放,避免了故障在分布式系统中的蔓延
Hystrix具备服务降级、服务熔断、线程和信号隔离、请求缓存、请求合并以及服务监控等强⼤功能
Hystrix使⽤舱壁模式实现线程池的隔离,它会为每⼀个依赖服务创建⼀个独⽴的线程池,这样就算某个依赖服务出现延迟过⾼的情况,也只是对该依赖服务的调⽤产⽣影响,⽽不会拖慢其他的依赖服务
五、Spring Cloud核⼼组件:Zuul
Spring Cloud Zuul通过与Spring Cloud Eureka进⾏整合,将⾃⾝注册为Eureka服务治理下的应⽤,同时从Eureka中获得了所有其他微服务的实例信息
对于路由规则的维护,Zuul默认会将通过以服务名作为ContextPath的⽅式来创建路由映射
Zuul提供了⼀套过滤器机制,可以⽀持在API⽹关⽆附上进⾏统⼀调⽤来对微服务接⼝做前置过滤,已实现对微服务接⼝的拦截和校验
六、⼩结
Eureka:各个服务启动时,Eureka Client都会将服务注册到Eureka Server,并且Eureka Client还可以反过来从Eureka Server拉取注册表,从⽽知道其他服务在哪⾥
Ribbon:服务间发起请求的时候,基于Ribbon做负载均衡,从⼀个服务的多台机器中选择⼀台
Feign:基于Feign的动态代理机制,根据注解和选择的机器,拼接请求URL地址,发起请求
Hystrix:发起请求是通过Hystrix的线程池来⾛的,不同的服务⾛不同的线程池,实现了不同服务调⽤的隔离,避免了服务雪崩的问题
Zuul:如果前端、移动端要调⽤后端系统,统⼀从Zuul⽹关进⼊,由Zuul⽹关转发请求给对应的服务
总结
以上就是这篇⽂章的全部内容了,希望本⽂的内容对⼤家的学习或者⼯作具有⼀定的参考学习价值,谢谢⼤家对的⽀持。如果你想了解更多相关内容请查看下⾯相关链接
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论