2.SpringCloud

2.1 Eureka的服务注册和发现

2.1.1什么是Spring Cloud Eureka?

Spring Cloud Eureka是Spring Cloud Netflix的一个子模块,也是核心模块之一。Eureka是一个基于REST的服务,用于定位服务,以实现云端中间层服务发现和故障转移,只需要使用服务的标识符,就可以访问到服务,而不需要修改服务调用的配置文件,功能类似于dubbo的注册中心,比如Zookeeper.它主要负责完成各个微服务实例的自动化注册和发现功能。

1.与zookeeper的对比,作为服务注册中心,Eureka比Zookeeper好在哪里?

著名CAP理论指出,一个分布式系统不可能同时满足C(一致性),A(可用性)和P(分区容错性)。由于分区容错性P是分布式系统中必须保证的,因此我们只能在A与C之间权衡。

所以Zookeeper保证的是CP,Euraka保证的是AP。

当向注册中心查询服务列表时,我们可以容忍注册中心返回的是几分钟之前的信息,但不能接受服务直接挂掉不可用,也就是说,服务注册功能对可用性的要求高于一致性。

Zookeeper保证CP

但是zookeeper会出现一种情况,当master节点因为网络故障与其他节点失去联系时,剩下节点会重新进行leader选举。但是选举leader的时间太长了,30~12

0s,且选举期间将不能向zk注册服务,也不能获取服务,当zookeeper集群超过半数机器不可用,因为无法选出master,也就处于瘫痪状态。在云部署的环境下,因网络问题使得zk集群失去master节点是较大概率发生的事,虽然服务能最终恢复,但是漫长的选举时间导致的注册长期不可用是不能容忍的。

Eureka保证的是AP

Eureka在设计时就优先保证可用性,Eureka各个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。而Eureka的客户端在向某个Eureka注册有时会连接失败,则会自动切换至其他节点,只要有一台Eureka存在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的(不保证强一致性)。除此之外,Eureka还有一种自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现网络故障,此时会出现如下情况:

  1. Eureka不再从注册列表中移除因为长时间没收到心跳而应该过期的服务。
  2. Eureka仍然能够接收新服务的注册和查询请求,但是不会被同步到其他节点(即保证当前节点依然可用)
  3. 当网络稳定时,当前实例新的注册信息会被同步到其他节点中

因此,Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像zookeeper那样使整个注册服务瘫痪。

 

2.1.2服务提供者

1.服务注册

服务在启动的时候会通过发送REST请求的方式将自己注册到Eureka Server上, 同时带上了自身服务的一些元数据信息。注册中心Eureka Server通过与服务之间的心跳来保持通信,当某个服务实例在超时时间内没有与注册中心保持会话,那么该服务实例将会从注册中心正常移除。

Eureka Server 接收到这个REST请求之后,将元数据信息存储在一个双层结构Map中, 其中第一层的key是服务名, 第二层的key是具体服务的实例名。

2.服务同步

两个服务提供者分别注册到了两个不同的服务注册中心上,它们的信息分别被两个服务注册中心所维护。由于服务注册中心之间因互相注册为服务, 当服务提供者发送注册请求到一个服务注册中心时, 它会将该请求转发给集群中相连的其他注册中心, 从而实现注册中心之间的服务同步。通过服务同步,两个服务提供者的服务信息就可以通过这两台服务注册中心中的任意一台获取到。

3.服务续约

在注册完服务之后,服务提供者会维护一个心跳用来保持与EurekaServer 的会话,以防止Eureka Server 的剔除任务将该服务实例从服务列表中移除掉,那么这个心跳保持就叫做服务续约(Renew)。关于服务续约有两个重要属性,我们可以关注并根据需要来进行调整:

服务续约任务的调用间隔时间,默认为30eureka.instance.lease-renewal-interval-in-seconds=30

服务失效的时间,默认为90秒。eureka.instance.lease-expiration-duration-in-seconds=90

2.1.3服务消费者

1.获取服务

当启动服务消费者的时候,它会发送一个REST请求给服务注册中心,来获取上面注册的服务列表。Eureka Server会维护一份只读的服务列表来返回给客户端,同时服务消费者会在本地缓存服务列表的清单并每隔30秒更新一次。

获取服务是服务消费者的基础,所以必有两个重要参数需要注意:

# 启用服务消费者从注册中心拉取服务列表的功能

eureka.client.fetch-registry=true

# 设置服务消费者从注册中心拉取服务列表的间隔

eureka.client.registry-fetch-interval-seconds=30

2.服务调用

服务消费者在获取服务清单后,通过服务名可以获得具体提供服务的实例名和该实例的元数据信息。因为有这些服务实例的详细信息, 所以客户端可以根据自己的需要决定具体调用哪个实例,在ribbon中会默认采用轮询的方式进行调用,从而实现客户端的负载均衡。

以下为负载均衡的 区域敏感性策略

对于访问实例的选择,Eureka中有Region和Zone的概念, 一个Region中可以包含多个Zone, 每个服务客户端需要被注册到一个Zone中, 所以每个客户端对应一个Region和一个Zone。在进行服务调用的时候,优先访问同处一个Zone 中的服务提供方,若访问不到,就访问其他的Zone。

eureka通过region和zone来进行分区。region:可以简单理解为地理上的分区,比如亚洲地区、华北地区等等,没有具体大小的限制。zone:可以简单理解为region内的具体机房,比如说region划分为上海,然后上海有两个机房,就可以在此region之下划分出zone1,zone2两个zone。

 

3.服务下线

在客户端程序中,当服务实例进行正常的关闭操作时,它会触发一个服务下线的REST请求给Eureka Server, 告诉服务注册中心自己要下线了。服务端在接收到请求之后,将该服务状态置为下线(DOWN), 并把该下线事件传播出去。

2.1.4服务注册中心

1.失效剔除

服务实例并不一定会正常下线,可能由于内存溢出、网络故障等原因使得服务不能正常工作,而服务注册中心并未收到“服务下线” 的请求。为了从服务列表中将这些无法提供服务的实例剔除, Eureka Server在启动的时候会创建一个定时任务,默认每隔一段时间(默认为60秒) 将当前清单中超时(默认为90秒)没有续约的服务剔除出去。

2.自我保护机制

当我们在本地调试基于Eureka的程序时, 基本上都会碰到这样一个问题, 在服务注册中心的信息面板中出现类似下面的红色警告信息:

 

事实上,该警告就是触发了EurekaServer的自我保护机制。当服务注册到EurekaServer之后,会维护一个心跳连接,告诉EurekaServer自己还活着。EurekaServer在运行期间,会统计心跳失败的比例在15分钟之内是否低于85%, 如果出现低于该值,Eureka Server会将当前的实例注册信息保护起来,让这些实例不会过期,尽可能保护这些注册信息。但是,在这段保护期间内实例若出现问题,那么客户端很容易拿到实际已经不存在的服务实例, 会出现调用失败的清况,所以客户端必须要有容错机制,比如可以使用请求重试、断路器等机制。

由于本地调试很容易触发注册中心的保护机制,这会使得注册中心维护的服务实例不那么准确。所以,我们在本地进行开发的时候, 可以使用eureka.server.enableself-preservation=false 参数来关闭保护机制, 以确保注册中心可以将不可用的实例正确剔除。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值