前言:从现在微服务框架的使用来看,毫无疑问,Spring Cloud 是目前微服务架构领域的翘楚。那么,对于他,你了解多少呢?
概述:实际上,Spring Cloud 是一个全家桶式的技术栈,基于Spring Boot进行开发,它包含了很多组件。其中有5个最核心的组件 Eureka、Ribbon、Feign、Hystrix、Zuul 。本文主讲Eureka。
《1、Spring Cloud核心组件:Eureka》
首先,讲到Spring Cloud,我们必然需要先了解他的5大核心组件,先来讲讲Eureka ,Eureka是Netflix 开源的服务发现组件,Spring Cloud 将其集成在 Spring CloudNetflix中,主要负责完成微服务架构中的服务治理功能。它主要包括两个组件:Eureka Server(注册中心服务端) 和 Eureka Client(注册中心客户端), 那么Eureka服务治理基础架构基于这两个组件衍生出哪些核心要素呢?
《2.Eureka服务治理基础架构的三大核心要素》
Eureka Server(服务注册中心)
Eureka Server是Eureka提供的服务端,提供服务注册与发现的功能。此服务可以为集群,(集群就是两个或以上),形成高可用的eureka注册中心。
Service Provider(服务提供者)
Service Provider是提供服务的应用,可以是Spring Boot应用,也可以是其他技术平台且遵循Eureka通信机制的应用。它将自己提供的服务注册到Eureka,以供其他应用发现。
Service Consumer(服务消费者)
Service Consumer是服务的消费者,消费者从服务注册中心获取服务列表,通过客户端负载均衡某种算法轮询服务列表,然后调用其所需要的服务,也即调用对应的服务提供者。 上述就是Eureka服务治理基础架构的三大核心要素。但是上述的三个核心要素遵守的都是逻辑角色的原则,意思是上述三个核心要素在实际运行中,可能是两个,甚至有可能是同一个实例。Eureka客户端通常包括Service Provider(服务提供者)与Service Consumer(服务消费者),那么在实际的运行中,这三个角色又是怎样交互的呢?
《3.服务治理机制方式》
在实际的运行中,Service Provider会向Eureka Server做Register(服务注册)、Renew(服务续约)、Cancel(服务下线)等操作,Eureka Server之间会做注册服务的同步,从而保证状态一致,Service Consumer会向Eureka Server获取注册服务列表,并消费服务。每个角色都有着自己独特的运行方式,来完成整个服务治理,下面,我们就通过探索者的角度一步步详细的梳理一下整个服务治理机制。
服务注册
在微服务启动时,首先,服务提供者需要将自己的服务注册到服务注册中心,服务提供者在启动的时候会发送REST请求将自己注册到服务注册中心上,并带上一些元信息。
服务注册中心接收到REST请求,会将元信息存储在一个双层Map中,第一层key是服务名,第二层key是具体服务的实例名。
注意:在服务注册时,需要确认一下eureka.client.register-with-eureka=true是否正确,如果为false是禁止向服务注册中心注册的。
服务同步
当服务成功的注册到了注册中心之后,由于注册中心可能是高可用的集群,那么我们的服务可能只注册到了一个集群中的一个注册中心上,被一个注册中心所维护,而不被另外一个注册中心所维护,那么这个时候,我们就需要将这个注册中心的信息同步给集群中其他的注册中心,这就叫服务同步。那么他是如何实现的呢?
由于在集群中,一个注册中心互为其他注册中心的服务,当服务提供者请求到一个服务注册中心后,它会将请求转发到其他服务注册中心,实现注册中心之间的服务同步。
通过服务同步,服务提供者的服务信息可以通过集群中的任何一个服务注册中心获取。
服务续约
在注册完成后。服务提供者会维护一个心跳告诉注册中心服务,心跳间隔大约是30S,防止注册中心剔除服务, 正常情况下,如果Eureka Server在90秒没有收到Eureka客户的续约,它会将实例从其注册表中删除。这个过程称为服务续约。
服务获取
当一切的注册相关工作完成后,我们自然要获取服务清单,那么如何获取服务呢? 启动服务消费者后,消费者会发送一个REST请求给服务注册中心,来获取上面注册的服务清单。 而服务注册中心会维护一份只读清单返回给消费者客户端,该缓存清单30s更新一次。
服务调用
消费者获取服务清单后,可以通过服务名获取到具体服务实例与实例的元数据信息。这个时候,我们可以通过Ribbon调用我们的目标服务,默认采用轮询的方式,从而实现负载均衡。
服务下线
当我们需要对服务实例进行正常的关闭操作时,它会触发一个服务下线的REST请求给服务端。注册中心接收到请求后,将该服务状态置为DOWN,并把下线时间传播出去。
失效剔除
有的时候,我们的服务意外挂掉了,那么Eureka如何识别出我们异常的服务,并将其剔除呢?
服务注册中心启动时会创建定时任务,默认60s一次,将当前清单中超时(90s)没有续约的服务剔除。
自我保护
当失效剔除机制引入的时候,就会有一个问题,如果一个地区网络特别不稳定,那么服务可能不会续约,但我们还需要这个服务存在。这个时候,我们怎么解决呢?
还好,Eureka拥有自我保护机制,可以很好的解决这个问题。Eureka Server在运行期间,会统计心跳失败的比例在15分钟之内是否低于85%,如果低于,就会将当前实例注册信息保护起来,同时提示一个警告,一旦进入保护模式,Eureka Server将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据。也就是不会注销任何微服务。 但是保护机制也有可能会出现问题,导致服务实例不能够被正确剔除。比如在保护期间,实例出现问题,那么客户端很容易拿到实际已经不存在的服务实例,会出现调用失败。 建议:除非网络情况真的非常不可控,不然请尽量关闭自我保护机制。 可使用:eureka.server.enable-self-preservation=false关闭保护机制,使不可用实例能够正常下线。
上面就是一些Spring Cloud五大核心组件之一“Eureka”的一些基本工作原理。如果有读者想深入了解一下,可以去跟着源码进行学习。