Eureka:Spring Cloud 服务注册与发现组件

什么是 Eureka

Eureka是Netflix公司开源的一款服务发现组件,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。
SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能

Eureka 组成部分

Eureka 两大组件

Eureka 采用 CS(Client/Server,客户端/服务器) 架构,它包括以下两大组件

  • Eureka Server:Eureka 服务注册中心
    主要用于提供服务注册功能;各个微服务节点启动后,将会在Eureka Server中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用微服务节点的信息,微服务节点的信息可以在界面中直观的看到。
  • Eureka Client:Eureka 客户端
    通常指的是微服务系统中的各个微服务,主要用于简化与Eureka Server的交互;各个微服务节点启动后,将会向Eureka Server发送心跳,默认周期为30秒,如果Eureka Server在多个心跳周期内没有接收到微服务节点的心跳,Eureka Server将会从服务注册表中把这个微服务节点移除(默认90秒)。
    Eureka Client 会拉取、更新和缓存 Eureka Server 中的信息。因此当所有的 Eureka Server 节点都宕掉,服务消费者依然可以使用缓存中的信息找到服务提供者,但是当服务有更改的时候会出现信息不一致。

Eureka 集群原理

在这里插入图片描述
从图中可以看出 Eureka Server 集群相互之间通过 Replicate 来同步数据,相互之间不区分主节点和从节点,所有的节点都是平等的。在这种架构中,节点通过彼此互相注册来提高可用性,每个节点需要添加一个或多个有效的 serviceUrl 指向其他节点。

如果某台 Eureka Server 宕机,Eureka Client 的请求会自动切换到新的 Eureka Server 节点。当宕机的服务器重新恢复后,Eureka 会再次将其纳入到服务器集群管理之中。当节点开始接受客户端请求时,所有的操作都会进行节点间复制,将请求复制到其它 Eureka Server 当前所知的所有节点中。

另外 Eureka Server 的同步遵循着一个非常简单的原则:只要有一条边将节点连接,就可以进行信息传播与同步。所以,如果存在多个节点,只需要将节点之间两两连接起来形成通路,那么其它注册中心都可以共享信息。每个 Eureka Server 同时也是 Eureka Client,多个 Eureka Server 之间通过 P2P 的方式完成服务注册表的同步。

Eureka Server 集群之间的状态是采用异步方式同步的,所以不保证节点间的状态一定是一致的,不过基本能保证最终状态是一致的。

  • Application Service:服务提供者

  • Application Client:服务消费者

  • Register:服务注册
    服务的提供者将自身注册到注册中心,服务提供者也是一个 Eureka Client。当 Eureka Client 向 Eureka Server 注册时,它提供自身的元数据,比如 IP 地址、端口,运行状况指示符 URL,主页等

  • Renew:服务续约
    Eureka Client 会每隔 30 秒发送一次心跳来续约。 通过续约来告知 Eureka Server 该 Eureka Client 运行正常,没有出现问题。 默认情况下,如果 Eureka Server 在 90 秒内没有收到 Eureka Client 的续约,Server 端会将实例从其注册表中删除,此时间可配置,一般情况不建议更改。
    服务续约的两个重要属性

    #服务续约任务的调用间隔时间,默认为30秒
    eureka.instance.lease-renewal-interval-in-seconds=30
    #服务失效的时间,默认为90秒。
    eureka.instance.lease-expiration-duration-in-seconds=90
    
  • Cancel: 服务下线
    Eureka Client 在程序关闭时向 Eureka Server 发送取消请求。 发送请求后,该客户端实例信息将从 Eureka Server 的实例注册表中删除

  • GetRegisty: 获取注册列表信息
    Eureka Client 从服务器获取注册表信息,并将其缓存在本地。客户端会使用该信息查找其他服务,从而进行远程调用。该注册列表信息定期(每30秒钟)更新一次。每次返回注册列表信息可能与 Eureka Client 的缓存信息不同,Eureka Client 自动处理。
    如果由于某种原因导致注册列表信息不能及时匹配,Eureka Client 则会重新获取整个注册表信息。 Eureka Server 缓存注册列表信息,整个注册表以及每个应用程序的信息进行了压缩,压缩内容和没有压缩的内容完全相同。Eureka Client 和 Eureka Server 可以使用 JSON/XML 格式进行通讯。在默认情况下 Eureka Client 使用压缩 JSON 格式来获取注册列表的信息。
    获取服务是服务消费者的基础,所以必有两个重要参数需要注意:

    # 启用服务消费者从注册中心拉取服务列表的功能
    eureka.client.fetch-registry=true
    # 设置服务消费者从注册中心拉取服务列表的间隔
    eureka.client.registry-fetch-interval-seconds=30
    
  • Make Remote Call:远程调用
    当 Eureka Client 从注册中心获取到服务提供者信息后,就可以通过 Http 请求调用对应的服务;服务提供者有多个时,Eureka Client 客户端会通过 Ribbon 自动进行负载均衡。

Eureka 分区

Eureka 提供了 Region 和 Zone 两个概念来进行分区
region:可以理解为地理上的不同区域,比如亚洲地区,中国区或者深圳等等。没有具体大小的限制。根据项目具体的情况,可以自行合理划分 region。
zone:可以简单理解为 region 内的具体机房,比如说 region 划分为深圳,然后深圳有两个机房,就可以在此 region 之下划分出 zone1、zone2 两个 zone。

上图中的 us-east-1c、us-east-1d、us-east-1e 就代表了不同的 Zone。Zone 内的 Eureka Client 优先和 Zone 内的 Eureka Server 进行心跳同步,同样调用端优先在 Zone 内的 Eureka Server 获取服务列表,当 Zone 内的 Eureka Server 挂掉之后,才会从别的 Zone 中获取信息。

Eureka 自我保护机制

默认情况下,如果 Eureka Server 在一段时间内(默认为 90 秒)没有接收到某个服务提供者(Eureka Client)的心跳,就会将这个服务提供者提供的服务从服务注册表中移除。 这样服务消费者就再也无法从服务注册中心中获取到这个服务了,更无法调用该服务。

但在实际的分布式微服务系统中,健康的服务(Eureka Client)也有可能会由于网络故障(例如网络延迟、卡顿、拥挤等原因)而无法与 Eureka Server 正常通讯。若此时 Eureka Server 因为没有接收心跳而误将健康的服务从服务列表中移除,这显然是不合理的。而 Eureka 的自我保护机制就是来解决此问题的。

所谓 “Eureka 的自我保护机制”,其中心思想就是“好死不如赖活着”。如果 Eureka Server 在一段时间内没有接收到 Eureka Client 的心跳,那么 Eureka Server 就会开启自我保护模式,将所有的 Eureka Client 的注册信息保护起来,而不是直接从服务注册表中移除。一旦网络恢复,这些 Eureka Client 提供的服务还可以继续被服务消费者消费。

综上,Eureka 的自我保护机制是一种应对网络异常的安全保护措施。它的架构哲学是:宁可同时保留所有微服务(健康的服务和不健康的服务都会保留)也不盲目移除任何健康的服务。通过 Eureka 的自我保护机制,可以让 Eureka Server 集群更加的健壮、稳定。

Eureka 的自我保护机制也存在弊端。如果在Eureka自我保护机制触发期间,服务提供者提供的服务出现问题,那么服务消费者就很容易获取到已经不存在的服务进而出现调用失败的情况,此时,我们可以通过客户端的容错机制来解决此问题。

通过在 Eureka Server 配置如下参数开启或者关闭保护机制,生产环境建议打开:

eureka:
  server:
    enable-self-preservation: false # false 关闭 Eureka 的自我保护机制,默认是开启,一般不建议大家修改

Eureka基本工作流程

  1. Eureka Server 启动成功,等待服务端注册。在启动过程中如果配置了集群,集群之间定时通过 Replicate 同步注册表,每个 Eureka Server 都存在独立完整的服务注册表信息
  2. Eureka Client 启动时根据配置的 Eureka Server 地址去注册中心注册服务
  3. Eureka Client 会每 30s 向 Eureka Server 发送一次心跳请求,证明客户端服务正常
  4. 当 Eureka Server 90s 内没有收到 Eureka Client 的心跳,注册中心则认为该节点失效,会注销该实例
  5. 单位时间内 Eureka Server 统计到有大量的 Eureka Client 没有上送心跳,则认为可能为网络异常,进入自我保护机制,不再剔除没有上送心跳的客户端
  6. 当 Eureka Client 心跳请求恢复正常之后,Eureka Server 自动退出自我保护模式
  7. Eureka Client 定时全量或者增量从注册中心获取服务注册表,并且将获取到的信息缓存到本地
  8. 服务调用时,Eureka Client 会先从本地缓存找寻调取的服务。如果获取不到,先从注册中心刷新注册表,再同步到本地缓存
  9. Eureka Client 获取到目标服务器信息,发起服务调用
  10. Eureka Client 程序关闭时向 Eureka Server 发送取消请求,Eureka Server 将实例从注册表中删除

Eureka保证AP

Eureka优先保证可用性。Eureka各个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。而Eureka的客户端在向某个Eureka注册或时如果发现连接失败,则会自动切换至其它节点,只要有一台Eureka还在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的(不保证强一致性)

Eureka P2P复制模式

  1. 客户端
  • 代码里支持preferSameZoneEureka,即有多个分区的话,优先选择与应用实例所在分区一样的其他服务的实例,如果没有找到则默认使用defaultZone。
  • 客户端使用quarantineSet维护了一个不可用的Eureka Server列表,进行请求时,优先从可用列表中进行选择,如果请求失败则切换到下一个Eureka Server进行重试,重拾次数默认为3
  • 另外为了防止每个Client端都按配置文件指定的顺序进行请求造成Eureka Server节点请求分布不均衡,Client端有个定时任务(默认5分钟执行一次)来刷新并随机化Eureka Server的列表。
  1. 服务端
  • syncUp:在Eureka Server重启或新的Eureka Server节点加进来时,会执行初始化,从集群其他节点中获取所有的实例注册信息,从而能够正常提供服务。当Eureka Server启动时,它会从其它节点获取所有的注册信息,如果获取同步失败,它在一定时间(此值由决定)内拒绝服务。
  • replicate:Eureka Server同步以下操作到所有的集群节点:服务注册(Registers)、服务更新(Renewals)、服务取消(Cancels),服务超时(Expirations)和服务状态变更(Status Changes)。Eureka Server在执行复制操作的时候,使用HEADER_REPLICATION的http header来将复制操作与普通应用实例的正常请求操作区分开来,通过HEADER_REPLICATION来标识是复制请求。

Eureka 解决P2P复制冲突问题**

  1. lastDirtyTimestamp标识:
    如果请求参数的lastDirtyTimestamp参数大于server本地instance的lastDirtyTimestamp值,则response返回404,要求应用实例重新进行register操作;
    如果是server本地大于请求参数的lastDirtyTimestamp参数,不是replication模式则返回200,replication模式,则返回409 Conflict,要求其同步自己最新的数据信息。
    2.heartbeat:
    节点之间的相互复制并不能保证所有操作都能成功,因此Eureka还通过应用实例与Server之间的heartbeat也就是renewLease操作进行数据的最终修复。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值