SpringCloud封装了Netfix公司开发的Eureka模块来实现服务治理。

什么是服务治理?

在传统的rpc远程调用框架中,管理每个服务与服务之间依赖关系比较复杂,管理比较复杂,所以需要使用服务治理,管理服务与服务之间的依赖关系,可以实现服务调用、服务均衡、容错等,实现服务发现与注册。

Eureka核心概念

Eureka是spring cloud中的一个负责服务注册与发现的组件。遵循着CAP理论中的A(可用性)P(分区容错性)。

一个Eureka中分为eureka server和eureka client。其中eureka server是作为服务的注册与发现中心。eureka client既可以作为服务的生产者,又可以作为服务的消费者。具体结构如下图:

 上图中首先会启动一个或多个eureka server,这些eureka server同步保留着所有的服务信息。然后启动不同的eureka client,向服务端发起服务注册和服务查询。无论是向哪个eureka server进行的注册,最终都会同步给所有配置好的eureka server。获取的服务信息,也同样都是一致的。

Eureka Server:注册中心服务端

注册中心服务端主要对外提供了三个功能:

1,服务注册

服务提供者启动时,会通过Eureka Client向Eureka Server注册信息,Eureka Server会存储该服务的信息,Eureka Server内部有二层缓存机制来维护整个注册表。

2,提供注册表

服务消费者在调用服务时,如果Eureka Client没有缓存注册表的话,会从Eureka Server获取最新的注册表。

3,同步状态

Eureka Client通过注册、心跳机制和Eureka Server同步当前客户端的状态。

Eureka Client:注册中心客户端

Eureka Client是一个java客户端,用于简化与Eureka Server的交互。Eureka Client会拉取、更新和缓存Eureka Server中的信息。因此当所有的Eureka Server节点都宕掉,服务消费者依然可以使用缓存中的信息找到服务提供者,但是当服务有更改的时候会出现信息不一致。

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

Eviction:服务剔除

当Eureka Client和Eureka Server不再有心跳时,Eureka Server会将该服务实例从服务注册列表中删除,即服务剔除。

Cancel:服务下线

Eureka Client在程序关闭时向Eureka Server发送取消请求。发送请求后,该客户端实例信息将从Eureka Server的实例注册表中删除。该下线请求不会自动完成,它需要调用一下内容:

DiscoveryManager.getInstance().shutdownComponent();

GetRegistry:获取注册列表信息

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

Remote Call:远程调用

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

自我保护机制

默认情况下,如果Eureka Server在一定的90s内没有接受到某个服务实例的心跳,会注销该实例。但是在微服务架构下服务之间通常都是跨进程调用,网络通信往往会面临着各种问题,比如微服务状态正常,网络分区故障,导致此实例被注销。固定时间内大量实例被注销,可能会验证威胁整个微服务架构的可用性。为了解决这个问题,Eureka 开发了自我保护机制。

Eureka Server在运行期间会统计心跳失败比例在15分钟之内是否低于85%,如果低于85%,Eureka Server即会进入自我保护机制。

Eureka Server触发自我保护机制后,页面会出现提示:

 

 Eureka Server进入自我保护机制,会出现以下几种情况:

1)Eureka不再从注册列表汇总移除因为长时间没收到心跳而应该过期的服务。

2)Eureka仍然能能接收新服务的注册和查询请求,但是不会被同步到其它节点上(即保证当前节点依然可用)。

3)当网络稳定时,当前实例新的注册信息会被同步到其它节点中。

Eureka自动保护机制是为了防止误杀服务而提供的一个机制。当个别客户端出现心跳失联时,则认为是客户端的问题,剔除客户端;当Eureka捕获到大量的心跳失败时,则认为可能是网络问题,进入自我保护机制;当客户端心跳恢复时,Eureka会自动退出自我保护机制。

如果在保护期内刚好这个服务提供者非正常下线了,此时服务消费者就会拿到一个无效的服务实例,即调用失败。对于这个问题需要服务消费者端要有一些容错机制,如重试、断路器等。

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

eureka.server.enable-self-preservation=true

Eureka集群原理

假设有三台Eureka Server组成的集群,第一台Eureka Server在北京机房,另两台在深圳和西安机房。这样三台Eureka Server就组建成了一个跨区域的高可用集群,只要三个地方的任意一个机房不出现问题,都不会影响整个框架的稳定性。

 

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

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

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

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

Eureka 分区

Eureka提供了Region和Zone两个概念来进行区分,着两个概念均来自于亚马逊的AWS。

region:可以理解为地理上的不同区域,比如亚洲地区,中国区或者深圳等等,没有具体大小的限制。根据项目具体的情况,可以自行合理划分region。

zone:可以简单理解为region内的具体机房,比如说region划分为深圳,然后深圳有两个机房,就可以在此region之后划分zone1,zone2两个zone。

Zone内的Eureka Client优先和Zone内的Eureka Server进行心跳同步,同样调用端优先在Zone内的Eureka Server获取服务列表,当Zone内的Eureka Server挂掉之后,才会从别的Zone中获取信息。

Eureka 保证AP

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

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将实例从注册表中删除。

 

 posted on 2020-12-29 08:32  会飞的金鱼  阅读(155)  评论(0)    收藏  举报