赞
踩
和Zookeeper 类似,Eureka 是一个服务注册和发现的组件,最开始主要应用于亚马逊公司的云计算服务平台AWS,Eureka 分为 Eureka Server 和 Eureka Client,Eureka Server 为Eureka 服务注册中心,Eureka Client 为 Eureka 客户端。
服务注册是指:各个微服务启动时,将自己的网络地址等信息注册到Eureka,服务提供者将自己的信息如服务名,服务ip告知服务注册中心。
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 会将该服务从服务列表中删除,即服务剔除
https://www.processon.com/view/62a18bee1efad401a17b4eec
(一般部署三个结点)
从图中可以看出 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节点,在客户端实际操作中有如下几点规律:
服务端:server本身依赖于客户端,也就是每一个server是作为其他server的客户端存在。
1、客户端高可用原理
(1)在client启动之前,如果没有eureka server,则通过配置eureka.client.back-registry-impl从备份的registry读取关键服务的信息。
(2)在client启动后,如果运行时候server全部挂掉了,本地内存有localRegion之前获取的数据。
(3)如果是server部分挂了。如果预计恢复时间比较长,可以人工介入,通过配置中心人工摘除服务(但是基本不用这样做)。在client中会维护一份不可用的server列表,一旦心跳时候失败,当该列表的大小超过指定的阈值时候就会进行重新清空,重新清空后,client会进行重试(默认3次)
2、服务端高可用原理
同时服务端采用renew租约和定时心跳的方式保护注册信息(self preservation机制)
为了保证高可用和高性能,Eureka Server 中设计了三级缓存。
对象中的数据;
在 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 分钟左右才会感知到下线的服务,这个情况在生产环境将是非常严重的。我们可以通过参数的调优来缩短这个时间:
下面是服务端和客户端参数的默认值。
# 开启响应缓存
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.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 主机,每台主机的 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 服务器集群配置成功
部分资料参考:
https://www.techgrow.cn/posts/be1e11c7.html#Eureka-%E9%9B%86%E7%BE%A4%E9%85%8D%E7%BD%AE
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。