加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

微服务注册中心 Eureka 架构深入解读

发布时间:2019-08-24 08:18:22 所属栏目:建站 来源:Java从算法到架构
导读:微服务架构中最核心的部分是服务治理,服务治理最基础的组件是注册中心。随着微服务架构的发展,出现了很多微服务架构的解决方案,其中包括我们熟知的 Dubbo 和 Spring Cloud。 关于注册中心的解决方案,dubbo 支持了 Zookeeper、Redis、Multicast 和 Simp
副标题[/!--empirenews.page--]

微服务架构中最核心的部分是服务治理,服务治理最基础的组件是注册中心。随着微服务架构的发展,出现了很多微服务架构的解决方案,其中包括我们熟知的 Dubbo 和 Spring Cloud。

微服务注册中心 Eureka 架构深入解读

关于注册中心的解决方案,dubbo 支持了 Zookeeper、Redis、Multicast 和 Simple,官方推荐 Zookeeper。Spring Cloud 支持了 Zookeeper、Consul 和 Eureka,官方推荐 Eureka。

两者之所以推荐不同的实现方式,原因在于组件的特点以及适用场景不同。简单来说:

  • ZK 的设计原则是 CP,即强一致性和分区容错性。他保证数据的强一致性,但舍弃了可用性,如果出现网络问题可能会影响 ZK 的选举,导致 ZK 注册中心的不可用。
  • Eureka 的设计原则是 AP,即可用性和分区容错性。他保证了注册中心的可用性,但舍弃了数据一致性,各节点上的数据有可能是不一致的(会最终一致)。
  • Eureka 采用纯 Java 实现,除实现了注册中心基本的服务注册和发现之外,极大的满足注册中心的可用性,即使只有一台服务可用,也可以保证注册中心的可用性。
  • 本文将聚焦到 Eureka 的内部实现原理,先从微服务架构的部署图介绍 Eureka 的总体架构,然后剖析服务信息的存储结构,最后探究跟服务生命周期相关的服务注册机制、服务续约机制、服务注销机制、服务剔除机制、服务获取机制、和服务同步机制。

Eureka 总体架构

下面是 Eureka 注册中心部署在多个机房的架构图,这正是他高可用性的优势(Zookeeper 千万别这么部署)。

微服务注册中心 Eureka 架构深入解读

从组件功能看:

  • 黄色注册中心集群,分别部署在北京、天津、青岛机房;
  • 红色服务提供者,分别部署北京和青岛机房;
  • 淡绿色服务消费者,分别部署在北京和天津机房;

从机房分布看:

  • 北京机房部署了注册中心、服务提供者和服务消费者;
  • 天津机房部署了注册中心和服务消费者;
  • 青岛机房部署了注册中心和服务提供者;

组件调用关系

服务提供者

  • 启动后,向注册中心发起 register 请求,注册服务
  • 在运行过程中,定时向注册中心发送 renew 心跳,证明“我还活着”。
  • 停止服务提供者,向注册中心发起 cancel 请求,清空当前服务注册信息。

服务消费者

  1. 启动后,从注册中心拉取服务注册信息
  2. 在运行过程中,定时更新服务注册信息。
  3. 服务消费者发起远程调用:
  4. a> 服务消费者(北京)会从服务注册信息中选择同机房的服务提供者(北京),发起远程调用。只有同机房的服务提供者挂了才会选择其他机房的服务提供者(青岛)。
  5. b> 服务消费者(天津)因为同机房内没有服务提供者,则会按负载均衡算法选择北京或青岛的服务提供者,发起远程调用。

注册中心

启动后,从其他节点拉取服务注册信息。

运行过程中,定时运行 evict 任务,剔除没有按时 renew 的服务(包括非正常停止和网络故障的服务)。

运行过程中,接收到的 register、renew、cancel 请求,都会同步至其他注册中心节点。

本文将详细说明上图中的 registry、register、renew、cancel、getRegistry、evict 的内部机制。

数据存储结构

既然是服务注册中心,必然要存储服务的信息,我们知道 ZK 是将服务信息保存在树形节点上。而下面是 Eureka 的数据存储结构:

微服务注册中心 Eureka 架构深入解读

Eureka 的数据存储分了两层:数据存储层和缓存层。

Eureka Client 在拉取服务信息时,先从缓存层获取(相当于 Redis),如果获取不到,先把数据存储层的数据加载到缓存中(相当于 Mysql),再从缓存中获取。值得注意的是,数据存储层的数据结构是服务信息,而缓存中保存的是经过处理加工过的、可以直接传输到 Eureka Client 的数据结构。

Eureka 这样的数据结构设计是把内部的数据存储结构与对外的数据结构隔离开了,就像是我们平时在进行接口设计一样,对外输出的数据结构和数据库中的数据结构往往都是不一样的。

数据存储层

这里为什么说是存储层而不是持久层?因为 rigistry 本质上是一个双层的 ConcurrentHashMap,存储在内存中的。

  • 第一层的 key 是spring.application.name,value 是第二层 ConcurrentHashMap;
  • 第二层 ConcurrentHashMap 的 key 是服务的 InstanceId,value 是 Lease 对象;
  • Lease 对象包含了服务详情和服务治理相关的属性。

二级缓存层

Eureka 实现了二级缓存来保存即将要对外传输的服务信息,数据结构完全相同。

  • 一级缓存:ConcurrentHashMap<Key,Value> readOnlyCacheMap,本质上是 HashMap,无过期时间,保存服务信息的对外输出数据结构。
  • 二级缓存:Loading<Key,Value> readWriteCacheMap,本质上是 guava 的缓存,包含失效机制,保存服务信息的对外输出数据结构。

既然是缓存,那必然要有更新机制,来保证数据的一致性。下面是缓存的更新机制:

微服务注册中心 Eureka 架构深入解读

更新机制包含删除和加载两个部分,上图黑色箭头表示删除缓存的动作,绿色表示加载或触发加载的动作。

删除二级缓存:

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

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

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

加载二级缓存:

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

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

更新一级缓存:

  • Eureka Server 内置了一个 TimerTask,定时将二级缓存中的数据同步到一级缓存(这个动作包括了删除和加载)。
  • 关于缓存的实现参考 ResponseCacheImpl

服务注册机制

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读