Spring Cloud explain (a) Eureka implementation overview mechanism

In the micro-services architecture is the core part of the service management, the most basic component of governance is a registered service center. Spring Cloud support Zookeeper, Consul and Euraka, officially recommended as a registration center with Eureka.

Eureka pure Java implementation, registry addition to achieving basic service registration and discovery, great to meet the availability registry, even if only one server is available, it can ensure the availability of registry.

Eureka is a design principle AP, namely availability and fault tolerance partition. It ensures the availability of registration centers, but abandoned the strong consistency of the data, the data on each node may be inconsistent (support eventual consistency).

1. Eureka overall architecture

1.1 Eureka deployment architecture

The figure is Eureka registry deployed in more room architecture diagram, here embodies the advantages of high availability

Look from the assembly function

  • Yellow cluster registry, deployed in Beijing, Tianjin, Qingdao room;
  • Red service provider, deployed in Beijing and Qingdao room;
  • Light green consumer services were deployed in Beijing and Tianjin room.

From the engine room distribution

  • Beijing room to deploy the registry, service providers and service consumers
  • Tianjin deployed registry and room service consumers
  • Qingdao room has deployed registration centers and service providers

1.2 calls relation component

1.2.1 Service Provider

  1. After the start, register a request to initiate a registration center, registration services;
  2. During operation, periodically it sends a heartbeat to renew registration center, to prove "I am alive";
  3. Stop service provider, to initiate a request to cancel the registry, clear the current service registration information.

1.2.2 Consumer Services

  1. After starting from the pull service registry registration information;
  2. During operation, regularly updated service registration information;
  3. Service consumer initiates a remote call:

           a) Consumer Services (Beijing) will choose from the service provider registration information with room service (Beijing), initiate a remote call, just hang up with room service provider will choose a service provider other room (Qingdao) .

           b) Consumer Services (Tianjin) because there is no service provider within the same room, according to the load balancing algorithm will choose Beijing or Qingdao service provider, to initiate a remote call.

1.2.3 Registration Center

  1. After starting, pull service from another node registration information;
  2. During operation, the timing task running evict, without excluding time renew services (including irregular stop of tasks and network failures);
  3. During operation, received register, renew and cancel the request, the registry will be synchronized to the other nodes.

Data storage structure 1.3

Eureka is a figure data storage structure. Eureka data storage into two layers: data storage layer and the buffer layer. When pulling Eureka Client service information acquisition start buffer layer, if not acquired, the data is loaded into the first data storage layer cache, then retrieved from the cache. Notably, the data structure of the data storage layer is service information, and is stored in the cache treated processed, may be transmitted directly to the data structure of the Eureka Client.

1.3.1 Data storage layer

registry data storage layer is a bilayer ConcurrentHashMap, data stored in memory.

  • The first layer is a key spring.application.name, value is ConcurrenthashMap second layer;
  • ConcurrentHashMap second layer is InstanceId service key, value Lease is subject;
  • Lease object contains properties related service information and service governance.

According to this storage structure we can find, Eureka Server is the first layer stores all the service name, service name and the corresponding instance information. The second layer is an example of a unique ID to store

Data storage layer data structure as shown below:

在这里插入图片描述

1.3.2 secondary cache layer

Eureka realizes the secondary cache to hold the external service information transmission.

Level cache (readOnlyCacheMap):

ConcurrentHashMap <Key, Value> readOnlyCacheMap, no expiration date, save the output data structure of foreign service information. Data-dependent timing synchronization from readWriteCacheMap, the default time of 30 seconds.

Secondary cache (readWriteCacheMap):

Loading<Key, Value> readWriteCacheMap,本质上是Google的guava缓存,包含失效机制,保存服务信息的对外输出数据结构。当获取缓存时判断缓存中是否没有数据,如果不存在此数据,则通过 CacheLoader 的 load 方法去加载,加载成功之后将数据放入缓存,同时返回数据。readWriteCacheMap 缓存过期时间,默认为 180 秒,当服务下线、过期、注册、状态变更,都会来清除此缓存中的数据。

Eureka Client 获取全量或者增量的数据时,会先从一级缓存中获取;如果一级缓存中不存在,再从二级缓存中获取;如果二级缓存也不存在,这时候先将存储层的数据同步到缓存中,再从缓存中获取。

通过 Eureka Server 的二层缓存机制,可以非常有效地提升 Eureka Server 的响应时间,通过数据存储层和缓存层的数据切割,根据使用场景来提供不同的数据支持。

1.3.3 缓存更新机制

既然是缓存,那必然要有更新机制,来保证数据的一致性。下面是缓存的更新机制。更新机制包含删除和加载两个部分,黑色箭头表示删除缓存的动作,绿色表示加载或触发加载的动作。:

删除二级缓存:

  1. Eureka Client发送register、renew和cancel请求并更新registry注册表之后,删除二级缓存;

  2. Eureka Server自身的Evict Task剔除服务后,删除二级缓存;

  3. 二级缓存本身设置了guava的失效机制,隔一段时间后自己自动失效;

加载二级缓存:

  1. Eureka Client发送getRegistry请求后,如果二级缓存中没有,就触发guava的load,即从registry中获取原始服务信息后进行处理加工,再加载到二级缓存中。

  2. Eureka Server更新一级缓存的时候,如果二级缓存没有数据,也会触发guava的load。

更新一级缓存:

  1. Eureka Server内置了一个TimerTask,定时将二级缓存中的数据同步到一级缓存(这个动作包括了删除和加载)。

2. 服务注册机制

服务提供者、服务消费者、以及服务注册中心自己,启动后都会向注册中心注册服务。下图是介绍如何完成服务注册的:

注册中心服务接收到register请求后:

  1. 保存服务信息,将服务信息保存到registry中;

  2. 更新队列,将此事件添加到更新队列中,供Eureka Client增量同步服务信息使用。

  3. 清空二级缓存,即readWriteCacheMap,用于保证数据的一致性。

  4. 更新阈值,供剔除服务使用。

  5. 同步服务信息,将此事件同步至其他的Eureka Server节点。

3. 服务续约机制

服务注册后,要定时(默认30S,可自己配置)向注册中心发送续约请求,告诉注册中心“我还活着”。

注册中心收到续约请求后:

  1. 更新服务对象的最近续约时间,即Lease对象的lastUpdateTimestamp;
  2. 同步服务信息,将此事件同步至其他的Eureka Server节点。

注:剔除服务之前会先判断服务是否已经过期,判断服务是否过期的条件之一是续约时间和当前时间的差值是不是大于阈值。

4. 服务注销机制

服务正常停止之前会向注册中心发送注销请求,告诉注册中心“我要下线了”。

注册中心服务接收到cancel请求后:

  1. 删除服务信息,将服务信息从registry中删除;
  2. 更新队列,将此事件添加到更新队列中,供Eureka Client增量同步服务信息使用。
  3. 清空二级缓存,即readWriteCacheMap,用于保证数据的一致性。
  4. 更新阈值,供剔除服务使用。
  5. 同步服务信息,将此事件同步至其他的Eureka Server节点。

注:服务正常停止才会发送Cancel,如果是非正常停止,则不会发送,此服务由Eureka Server主动剔除。

5. 服务剔除机制

Eureka Server提供了服务剔除的机制,用于剔除没有正常下线的服务。

服务的剔除包括三个步骤,首先判断是否满足服务剔除的条件,然后找出过期的服务,最后执行剔除。

5.1 判断是否满足服务剔除的条件

有两种情况可以满足服务剔除的条件:

  1. 关闭了自我保护
  2. 如果开启了自我保护,需要进一步判断是Eureka Server出了问题,还是Eureka Client出了问题,如果是Eureka Client出了问题则进行剔除。

这里比较核心的条件是自我保护机制,Eureka自我保护机制是为了防止误杀服务而提供的一个机制。Eureka的自我保护机制“谦虚”的认为如果大量服务都续约失败,则认为是自己出问题了(如自己断网了),也就不剔除了;反之,则是Eureka Client的问题,需要进行剔除。而自我保护阈值是区分Eureka Client还是Eureka Server出问题的临界值:如果超出阈值就表示大量服务可用,少量服务不可用,则判定是Eureka Client出了问题。如果未超出阈值就表示大量服务不可用,则判定是Eureka Server出了问题

条件1中如果关闭了自我保护,则统统认为是Eureka Client的问题,把没按时续约的服务都剔除掉(这里有剔除的最大值限制)。

5.1.1 自我保护阀值

自我保护阈值是区分Eureka Client还是Eureka Server出问题的临界值:如果超出阈值就表示大量服务可用,少量服务不可用,则判定是Eureka Client出了问题。如果未超出阈值就表示大量服务不可用,则判定是Eureka Server出了问题。

阈值的计算公式如下:

  • 自我保护阈值 = 服务总数 * 每分钟续约数 * 自我保护阈值因子。
  • 每分钟续约数 =(60S/客户端续约间隔)
  • 最后自我保护阈值的计算公式为:自我保护阈值 = 服务总数 * (60S/客户端续约间隔) * 自我保护阈值因子。

举例

如果有100个服务,续约间隔是30S,自我保护阈值0.85。

自我保护阈值=100 * 60 / 30 * 0.85 = 170。

如果上一分钟的续约数=180>170,则说明大量服务可用,是服务问题,进入剔除流程;

如果上一分钟的续约数=150<170,则说明大量服务不可用,是注册中心自己的问题,进入自我保护模式,不进入剔除流程。

5.2 找出过期的服务

遍历所有的服务,判断上次续约时间距离当前时间大于阈值就标记为过期。并将这些过期的服务保存到集合中。

5.3 剔除服务

在剔除服务之前先计算剔除的数量,然后遍历过期服务,通过洗牌算法确保每次都公平的选择出要剔除的任务,最后进行剔除。

执行剔除服务后:

  1. 删除服务信息,从registry中删除服务。
  2. 更新队列,将当前剔除事件保存到更新队列中。
  3. 清空二级缓存,保证数据的一致性。

6. 服务获取机制

Eureka Client获取服务有两种方式,全量同步和增量同步。获取流程是根据Eureka Server的多层数据结构进行的:

无论是全量同步还是增量同步,都是先从缓存中获取,如果缓存中没有,则先加载到缓存中,再从缓存中获取。(registry只保存数据结构,缓存中保存ready的服务信息。)

6.1 从一级缓存中获取

  1. 先判断是否开启了一级缓存
  2. 如果开启了则从一级缓存中获取,如果存在则返回,如果没有,则从二级缓存中获取
  3. 如果未开启,则跳过一级缓存,从二级缓存中获取

6.2 从二级缓存中获取

  1. 如果二级缓存中存在,则直接返回;
  2. 如果二级缓存中不存在,则先将数据加载到二级缓存中,再从二级缓存中获取。注意加载时需要判断是增量同步还是全量同步,增量同步从recentlyChangedQueue中load,全量同步从registry中load。

7. 服务同步机制

服务同步机制是用来同步Eureka Server节点之间服务信息的。它包括Eureka Server启动时的同步,和运行过程中的同步。

7.1 启动时同步

Eureka Server启动后,遍历eurekaClient.getApplications获取服务信息,并将服务信息注册到自己的registry中。

注:这里是两层循环,第一层循环是为了保证已经拉取到服务信息,第二层循环是遍历拉取到的服务信息。

7.2 运行过程中同步

当Eureka Server节点有register、renew、cancel请求进来时,会将这个请求封装成TaskHolder放到acceptorQueue队列中,然后经过一系列的处理,放到batchWorkQueue中。

TaskExecutor.BatchWorkerRunnable是个线程池,不断的从batchWorkQueue队列中poll出TaskHolder,然后向其他Eureka Server节点发送同步请求。

这里省略了两个部分:

  • 一个是在acceptorQueue向batchWorkQueue转化时,省略了中间的processingOrder和pendingTasks过程。
  • 另一个是当同步失败时,会将失败的TaskHolder保存到reprocessQueue中,重试处理。

 

 

 

 

 

 

发布了8 篇原创文章 · 获赞 0 · 访问量 7274

Guess you like

Origin blog.csdn.net/fedorafrog/article/details/104125488