Eureka 作为 Spring Cloud 体系中最核心、默认的注册中心组件,研究它的运行机制,有助于我们在工作中更好地使用它。
Eureka 核心概念
Eureka(注册中心)包含两个组件:Eureka Server和Eureka Client。服务提供者和服务的消费者。
Eureka负责管理、记录服务提供者的信息。服务调用者无需自己寻找服务,而是把自己的需求告诉Eureka,然后Eureka会把符合你需求的服务告诉你。
同时,服务提供方与Eureka之间通过“心跳”
机制进行监控,当某个服务提供方出现问题,Eureka自然会把它从服务列表中剔除。
这就实现了服务的自动注册、发现、状态监控。基本架构如下:
概念详情及其参数配置
Eureka:就是服务注册中心(可以单独,也可以是一个集群),对外暴露自己的地址,
同时注册中心服务端(Eureka Server)主要对外提供三个功能
(1)服务注册:提供者启动后,向Eureka注册自己信息(地址,提供什么服务),ureka Server 会存储该(Eureka Server 内部有二层缓存机制来维护整个注册表)服务的信息。
(2)提供注册表:消费者向Eureka订阅服务,Eureka会将对应服务的所有提供者地址列表发送给消费者,并且定期更新。
(3)同步状态:通过注册,心跳(续约)机制,和 Eureka Server 同步当前客户端的状态。
心跳(续约就是提供者定期通过http方式向Eureka刷新自己的状态
注册中心客户端(Eureka Client)
Eureka Client 会拉取、更新和缓存 Eureka Server 中的信息。因此当所有的 Eureka Server 节点都宕掉,服务消费者依然可以使用缓存中的信息找到服务提供者,但是当服务有更改的时候会出现信息不一致。
服务注册(Register)
服务的提供者,将自身注册到注册中心,服务提供者也是一个 Eureka Client。当 Eureka Client 向 Eureka Server 注册时,它提供自身的元数据,比如 IP 地址、端口,运行状况指示符 URL,主页等。yml配置如下
eureka:
client:
service-url:
defaultZone: http://localhost:10086/eureka/
register-with-eureka: true #服务启动方启动时,会检测该参数是否为true,true会注册给eureka
服务获取(GetRegisty)
Eureka Client 从服务器获取注册表信息,并将其缓存在本地。客户端会使用该信息查找其他服务,从而进行远程调用。该注册列表信息定期(每30秒钟)更新一次。每次返回注册列表信息可能与 Eureka Client 的缓存信息不同,Eureka Client 自动处理。
Eureka Client 定时全量或者增量从注册中心获取服务注册表,并且将获取到的信息缓存到本地 这里应该为第一次全量,后面为定时增量。
如果由于某种原因导致注册列表信息不能及时匹配,Eureka Client 则会重新获取整个注册表信息。 Eureka Server 缓存注册列表信息,整个注册表以及每个应用程序的信息进行了压缩,压缩内容和没有压缩的内容完全相同。Eureka Client 和 Eureka Server 可以使用 JSON/XML 格式进行通讯。在默认情况下 Eureka Client 使用压缩 JSON 格式来获取注册列表的信息。获取服务的参数示例如下:
eureka:
client:
service-url:
defaultZone: http://localhost:10086/eureka/
fetch-registry: true #开启拉取注册后的服务
服务续约(Renew)
Eureka Client 会每隔 30 秒发送一次心跳来续约。 通过续约来告知 Eureka Server 该 Eureka Client 运行正常,没有出现问题。 默认情况下,如果 Eureka Server 在 90 秒内没有收到 Eureka Client 的续约,Server 端会将实例从其注册表中删除,此时间可配置,一般情况不建议更改。服务续约中油两个重要的参数是lease-renewal-interval-in-seconds和lease-expiration-duration-in-seconds,参数配置如下
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
instance:
lease-renewal-interval-in-seconds: 5 # 每隔5秒发送一次心跳,服务续约任务的调用间隔时间,默认为30秒
lease-expiration-duration-in-seconds: 10 # 10秒不发送就过期,服务失效的时间,默认为90秒。
服务剔除(Eviction)
当 Eureka Client 和 Eureka Server 不再有心跳时,Eureka Server 会将该服务实例从服务注册列表中删除,即服务剔除
服务下线(Cancel)
Eureka Client 在程序关闭时向 Eureka Server 发送取消请求。 发送请求后,该客户端实例信息将从 Eureka Server 的实例注册表中删除。该下线请求不会自动完成,需要以下代码来进行手动完成。
DiscoveryManager.getInstance().shutdownComponent();
远程调用(Remote Call)
当 Eureka Client 从注册中心获取到服务提供者信息后,就可以通过 Http 请求调用对应的服务;服务提供者有多个时,Eureka Client 客户端会通过 Ribbon 自动进行负载均衡。
自我保护机制
默认情况下,如果 Eureka Server 在一定的 90s 内没有接收到某个微服务实例的心跳,会注销该实例。但是在微服务架构下服务之间通常都是跨进程调用,网络通信往往会面临着各种问题,比如微服务状态正常,网络分区故障,导致此实例被注销。
固定时间内大量实例被注销,可能会严重威胁整个微服务架构的可用性。为了解决这个问题,Eureka 开发了自我保护机制,那么什么是自我保护机制呢?
Eureka Server 在运行期间会去统计心跳失败比例在 15 分钟之内是否低于 85%,如果低于 85%,Eureka Server 即会进入自我保护机制。Eureka Server会将当前的实例注册信息保护起来,同时提示一个警告,一旦进入保护模式,Eureka Server将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据。也就是不会注销任何微服务。eureka默认开启自我保护,参数如下
eureka:
instance:
hostname: localhost
server:
enable-self-preservation: false #关闭自我保护机制
当注册中心进入进入自我保护后,页面会出现如下的字样
同时服务会出现以下的情况:
(1 Eureka 不再从注册列表中移除因为长时间没收到心跳而应该过期的服务
(2 Eureka 仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上(即保证当前节点依然可用)
(3 当网络稳定时,当前实例新的注册信息会被同步到其它节点中
Eureka 自我保护机制是为了防止误杀服务而提供的一个机制。当个别客户端出现心跳失联时,则认为是客户端的问题,剔除掉客户端;当 Eureka 捕获到大量的心跳失败时,则认为可能是网络问题,进入自我保护机制;当客户端心跳恢复时,Eureka 会自动退出自我保护机制。
如果在保护期内刚好这个服务提供者非正常下线了,此时服务消费者就会拿到一个无效的服务实例,即会调用失败。对于这个问题需要服务消费者端要有一些容错机制,如重试,断路器等。
建议开发环境关闭自我保护,生产开启自我保护。
一个有关eureka的图送给大家。
借鉴博客链接:https://blog.youkuaiyun.com/qwe86314/article/details/94552801