Eureka入门

Eureka 简介

和Zookeeper 类似,Eureka 是一个服务注册和发现的组件,最开始主要应用于亚马逊公司的云计算服务平台AWS,Eureka 分为 Eureka Server 和 Eureka Client,Eureka Server 为Eureka 服务注册中心,Eureka Client 为 Eureka 客户端。
服务注册是指:各个微服务启动时,将自己的网络地址等信息注册到Eureka,服务提供者将自己的信息如服务名,服务ip告知服务注册中心。

Eureka 相关概念

  • Register — 服务注册
    当Eureka Client 向Eureka server 注册时,Eureka Client 提供自身的元数据,比如 ip 地址、端口、运行状况指标的URL,主页 地址信息。

  • Renew — 服务续约
    Eureka Client 在默认情况下,会每隔30s 发送一次心跳续约,通过服务续约来告知Eureka Server 该Eureka Client 依然可用,正常情况下,如果Eureka Server 90 s 内没有收到 EurekaClient 的心跳,Eureka Server 会将Eureka Client 从注册列表中删除,注意:官网建议不要更改服务续约的间隔时间

  • Fetch Registries — 获取服务注册列表信息
    Eureka Client 从Eureka Server获取服务注册表信息,并将其缓存到本地。Eureka Client会使用服务注册列表信息查找其他服务信息,从而进行远程调用,该注册列表信息定时(每隔30s)更新一次,每次返回的注册列表信息可能与EurekaClient 缓存信息不同,Eureka Client 会重新获取整个注册表的信息。Eureka Server缓存了所有的服务注册表信息,并进行了压缩。Eureka Server 和 Eureka Client 可以使用json 和 xml的数据格式进行通信,默认,Eureka Client 使用 JSON 的方式来获取注册列表的信息

  • Remote Call — 远程调用
    当 Eureka Client 从注册中心获取到服务提供者信息后,就可以通过 Http 请求调用对应的服务;服务提供者有多个时,Eureka Client 客户端会通过 Ribbon 自动进行负载均衡。

  • Cancel — 服务下线
    Eureka Client 在程序关闭时可以向Eureka Server发送下线请求,发送请求后,该客户端的实例信息将从 Eureka Server的服务注册列表中删除。该下线请求不会自动完成,需要在程序关闭时调用以下代码:DiscoveryManager.getInstance().shudownComponent()

  • Eviction — 服务剔除
    在默认的情况下,Eureka Client 连续 90s 没有向 Eureka Server
    发送服务续约(心跳)时,Eureka Server 会将该服务从服务列表中删除,即服务剔除

Eureka 基础架构

https://www.processon.com/view/62a18bee1efad401a17b4eec
在这里插入图片描述

  • Eureka 包含两个组件:Eureka Server 和 Eureka Client
  • Eureka Client是⼀个Java客户端,⽤于简化与Eureka Server的交互
  • Eureka Server提供服务发现的能⼒,各个微服务启动时,会通过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 集群之间的状态是采用异步方式同步的,所以不保证节点间的状态一定是一致的,不过基本能保证最终状态是一致的。

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

Peer to Peer(对等网络)设计

一般而言在分布式系统的数据有多个副本之间的复制方式,可以分为主从复制和对等复制

  • 主从复制:Master-Slave模式,一个主副本和多个从副本,所有数据的写操作都是提交到主副本,最后由主副本更新到其他的从副本(常采用异步更新),通常写是整个系统的瓶颈所在。

  • 对等复制:副本之间不分主从,任何的副本都可以接受写数据,然后副本之间进行数据更新。在对等复制中,由于每一个副本都可以进行写操作,各个副本之间的数据同步及冲突处理是一个比较难解决的问题。

eureka中的对等复制机制

客户端:在客户端中配置相应的服务端的多个peer节点,在客户端实际操作中有如下几点规律:

  1. 有多个分区时候,优先选择与应用实例所在分区一样的其他服务实例,如果没有的话选择默认是defaultZone
  2. 客户端会维护一个可用的server列表,请求的时候优先从可用的列表中进行选择,如果请求失败切换到下一个server进行重试,重试次数为3次
  3. 为了防止客户端请求服务端的节点不均匀现象,客户端有一个定时任务来刷新并随机化eureka server的列表。

服务端:server本身依赖于客户端,也就是每一个server是作为其他server的客户端存在。

  1. 在一个server启动的时候,有一个synvUp操作,通过客户端请求其他的server节点中的一个节点获取注册的应用实例信息,然后复制到其他的peer节点。
  2. eureka中采用版本号(lastDirtyTimestamp)和心跳机制(renewLease从新租约方式)的方式来解决数据复制过程中的冲突问题。

Eureka 启动流程

  • Eureka Server 集群相互之间通过 Replicate 来同步数据,相互之间不区分主节点和从节点,所有的节点都是平等的
  • Eureka Server 集群之间的状态是采用异步方式同步的,所以不保证节点间的状态一定是一致的,不过基本能保证最终状态是一致的。
  • Eureka Client 随机注册到一个server上,Eureka Client 在默认情况下,会每隔30s 发送一次心跳续约,通过服务续约来告知Eureka Server 该Eureka Client 依然可用,正常情况下,如果Eureka Server 90 s 内没有收到 EurekaClient 的心跳,Eureka Server 会将Eureka Client 从注册列表中删除
  • Eureka Client 从Eureka Server获取服务注册表信息,并将其缓存到本地。Eureka Client会使用服务注册列表信息查找其他服务信息,从而进行远程调用,该注册列表信息定时(每隔30s)更新一次,每次返回的注册列表信息可能与EurekaClient 缓存信息不同,Eureka Client 会重新获取整个注册表的信息。
  • 如果某台 Eureka Server 宕机,Eureka Client 的请求会自动切换到新的 Eureka Server 节点。

Eureka 自我保护

  • 当有一个新的Eureka Server 出现时,他尝试从相邻的Peer 节点获取所有的服务实例注册信息。如果从相邻的Peer 节点获取信息出现了故障,Eureka Server 会尝试其他的 Peer 节点。
  • 如果 Eureka Server 能够成功获取所有的服务实例信息。则根据配置信息设置服务续约的阈值。
  • 在任何时间,如果Eureka Server 接收到服务续约低于为该值配置的百分比(默认15分钟内低于85%),则服务器开启自我保护模式,即不在剔除注册列表的信息。这样做的好处在于,如果Eureka Server 自身的网络问题而导致 Eureka Client 无法续约,Eureka Client 注册列表信息不在被删除,也就是Eureka Client 还可以被其他服务消费。

Eureka高可用原理分析

1、客户端高可用原理
(1)在client启动之前,如果没有eureka server,则通过配置eureka.client.back-registry-impl从备份的registry读取关键服务的信息。
(2)在client启动后,如果运行时候server全部挂掉了,本地内存有localRegion之前获取的数据。
(3)如果是server部分挂了。如果预计恢复时间比较长,可以人工介入,通过配置中心人工摘除服务(但是基本不用这样做)。在client中会维护一份不可用的server列表,一旦心跳时候失败,当该列表的大小超过指定的阈值时候就会进行重新清空,重新清空后,client会进行重试(默认3次)

2、服务端高可用原理

  • 服务端采用peer to peer的架构模式,原则上就是高可用的。
  • 同时服务端还可以通过配置remoteRegionUrlsWithName来支持拉取远程的region实例,如果当前的region挂了,会自动fallback到远程的region获取数据

同时服务端采用renew租约和定时心跳的方式保护注册信息(self preservation机制)

Eureka 客户端已经成功下线,为什么还会有请求流入?

在这里插入图片描述
为了保证高可用和高性能,Eureka Server 中设计了三级缓存。

  • registry 缓存,新注册的服务信息会保存到 registry 对象中;
  • readWriteCacheMap 会实时同步registry 对象中的数据;
  • readOnlyCacheMap 默认每 30 秒去同步一次 readWriterCacheMap

对象中的数据;
在 Eureka UI 页面看到的信息避开了响应缓存 readOnlyCacheMap,直接从 registry 对象获取的,所以我们能够在 Eureka UI 页面实时的看到注册的新服务。

但是 Eureka Client 拉取的数据是从响应缓存 readOnlyCacheMap 中获取到的,这个数据不是实时拉取的,而是默认每 30 秒更新一次,所以就会出现 UI 页面看到服务已经注册好了,但是调用时却出现没有有效服务的错误。

服务下线也存在同样的问题,服务已经下线了,但是还是有客户端在调用已经下线的服务,这时就会出现连接拒绝的错误。

Spring Cloud 通过负载均衡器 Ribbon 从 Eureka Client 中获取被调用服务实例的信息,然后通过获取到的实例来调用对应的服务,Ribbon 从 Eureka Client 中获取到的服务列表也不是实时的,默认 30s 更新一次。

极端情况,在服务下线后的 90s 内,流入的请求都会调用失败。这是在服务 graceful shutdown 的前提下,如果服务异常终止或者被 kill -9 强制杀死,这个时间会更长。

在非 graceful shutdown 情况下,客户端不会调用 Eureka API 来更新 registry 注册列表,而是只能等 Eureka Server 的 evict 线程定时清理无效节点,这个周期默认是 60s,客户端默认的续约超时时间是 90s。

续约周期是 30s,在连续 3 次丢失心跳后会被 Eureka Server 的 evict 线程清理,也就是说服务下线后,可能需要延迟 180s 之后,Eureka Server 中的 registry 对象才会被更新。

总的加起来,在非 graceful shutdown 情况下,Ribbon 中的缓存需要 4 分钟左右才会感知到下线的服务,这个情况在生产环境将是非常严重的。我们可以通过参数的调优来缩短这个时间:

  • 缩短 Eureka Server 多层缓存同步的周期
  • 缩短服务消费者 Client 拉取服务列表的周期
  • 保证服务是以 graceful shutdown 方式销毁的

下面是服务端和客户端参数的默认值。

  • eureka-server 端
# 开启响应缓存
use-read-only-response-cache: true

# readOnlyCacheMap 从 readWriterCacheMap 同步数据的时间间隔
eureka.server.response-cache-update-interval-ms = 30000

# eureka server 清理无效节点的时间间隔
eureka.server.eviction-interval-timer-in-ms = 60
  • eureka-client 端
# 客户端续约的频率
eureka.instance.lease-renewal-interval-in-seconds = 30

# 续约超时时间
eureka.instance.lease-expiration-duration-in-seconds = 90

# 客户端拉取服务列表周期
eureka.client.registry-fetch-interval-seconds = 30

主要的业务逻辑在eureka-server端,通过前面两篇文章,其实我们已经知道eureka-server大概要做哪些工作了,比如:从注册表中删除下线的服务、将缓存数据过期、把变动的服务实例信息加入到Queue中。

Eureka 故障会发生什么?

Eureka 服务端故障

  • 在 Eureka Server 集群中,如果某个节点宕机,Eureka Client 会自动切换到新的 Eureka Server 上。

Eureka 客户端故障

  • Eureka Client 注册到 Eureka Server ,注册成功后,默认情况下,Eureka Client 每隔 30 秒就要向
  • Eureka Server 发行一条心跳信息,告诉 Eureka Server 我还在运行。如果 Eureka Server 连续 90秒都没有收到 Eureka Client 的续约消息(连续 3 次都没发送),它会认为 Eureka Client 已经掉线了,会将掉线的 Eureka Client 从当前的服务注册表中剔除。

Eureka 集群配置

假设现有三台 Eureka Server 主机,每台主机的 IP 与端口分别是: 192.168.1.105:8005、192.168.1.106:8006、192.168.1.107:8007

Eureka Server1 配置

server:
  port: 8005

eureka:
  instance:
    hostname: 192.168.1.105
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://192.168.1.106:8006/eureka/,http://192.168.1.107:8007/eureka/

Eureka Server2 配置

server:
  port: 8006

eureka:
  instance:
    hostname: 192.168.1.106
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://192.168.1.105:8005/eureka/,http://192.168.1.107:8007/eureka/

Eureka Server3 配置

server:
  port: 8007

eureka:
  instance:
    hostname: 192.168.1.107
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://192.168.1.105:8005/eureka/,http://192.168.1.106:8006/eureka/

client配置:

server:
  port: 9090

spring:
  application:
    name: demo-client

eureka:
  client:
    service-url:
      defaultZone: http://192.168.1.105:8005/eureka/,http://192.168.1.106:8006/eureka/,http://192.168.1.107:8007/eureka/
  instance:
    instance-id: demo-client-9090
    prefer-ip-address: true

启动三台 Eureka Server,分别访问三台 Eureka Server 的管理界面,若界面上的 DS Replicas 项可以正常显示其他 Eureka Server 节点(如下图),则说明 Eureka 服务器集群配置成功
在这里插入图片描述

Eureka 对比 ZooKeeper

  • ZooKeeper 保证的是 CP,Eureka 保证的是 AP
  • Eureka 本质上是一个工程,而 ZooKeeper 只是一个进程
  • ZooKeeper 有 Leader 和 Follower 角色,Eureka 各个节点是平等关系
  • ZooKeeper 在选举期间注册服务瘫痪,虽然服务最终会恢复,但是选举期间不可用;Eureka 只要有一实例就可以保证服务可用,但查询到的数据可能并不是最新的
  • ZooKeeper 采用过半数存活原则,Eureka 采用自我保护机制解决分区问题

部分资料参考:
https://www.techgrow.cn/posts/be1e11c7.html#Eureka-%E9%9B%86%E7%BE%A4%E9%85%8D%E7%BD%AE

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值