Spring Cloud Eureka基本概述
记一次Eureka的进一步学习。
百科描述:Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。SpringCloud 将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能。
Eureka 包括 Eureka Server 和 Eureka Client,Eureka Server 即注册中心,Eureka Client 启动后会向 Eureka Server 注册自己,这样其他的 Eureka Client 访问 Eureka Server 即可拿到注册了的 Eureka Client 的信息。
上图是官网给的基于集群部署的 Eureka 架构图,先看一下图上各个部件的表示含义以及它们之间的交互:
- Eureka Server:Eureka 服务端,多个 Eureka Server 可构成集群,集群中各节点完全对等。
- Eureka Client:Eureka 客户端,业务服务依赖它实现服务注册和服务发现功能。
- Application Service:服务提供者,依赖 Eureka Client 实现服务注册功能。
- Application Client:服务消费者,依赖 Eureka Client 实现服务发现功能。
- Register:Eureka Client 启动时会发起 Register 请求向 Eureka Server 注册自己。
- Renew:Eureka Client 会周期性的向 Eureka Server 发送心跳来续约,默认30s。
- Cancel:Eureka Client 关闭时会发送 Cancel 下线请求。
- Get:Eureka Client 会周期性的发送 Get 请求,从 Eureka Server 获取注册表信息,默认30s。
- Make Remote Call:服务消费者通过 Make Remote Call 访问服务提供者。
- Replicate:Eureka Server 之间通过 Replicate 实现数据同步。当 Eureka Client 有请求(Heartbeat, Register, Cancel, StatusUpdate, DeleteStatusOverride)到某一个 Eureka Server 节点,该节点完成自身对应的操作后,会通过 Replicate 将本次请求同步到其他节点。
上面说了,Eureka Client 默认每30s会向 Eureka Server 发送一次心跳来实现续约,默认情况下,Eureka Server 超过90s没有收到该 Eureka Client 的心跳,则会注销该 Eureka Client。自我保护机制正是一种针对网络异常波动的安全保护措施,Eureka Server 在运行期间会去统计续约数量,如果在 15 分钟之内续约数量低于 85%,Eureka Server 则会进入自我保护模式,停止实例过期将当前的实例注册信息保护起来,同时提示一个警告,Eureka 的 web 页面这个红色告警语句应该很眼熟:
进入自我保护模式时,此时会出现以下几种情况:
- Eureka Server 不再从注册列表中移除因为长时间没收到心跳而应该过期的服务。
- Eureka Server 仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上,保证当前节点依然可用。
- 当网络稳定时,当前Eureka Server新的注册信息会被同步到其它节点中。
自我保护机制通过配置 eureka.server.enable-self-preservation 来开启/关闭,默认开启。
- 注册表的存储结构
先来看一下注册表的存储结构,上图 ConcurrentHashMap<String, Map<String, Lease>> register 就是注册表。ConcurrentHashMap 的 key 存储的是服务名称,value 的这个 Map 存储的是该服务对应的多个实例信息,Map 的 key 存储的是服务实例的id,value 的 Lease 就是实例信息,InstanceInfo 就代表了服务实例的具体信息,比如机器的ip地址、hostname 以及端口号,Lease 可以理解为 InstanceInfo 的包装类,维护了服务实例的一些动态数据,比如最近的心跳时间。另外,从源码中可以看到,register 是完全基于内存的,服务的注册、下线、故障,全部会在内存里维护和更新这个注册表。
- 多级缓存机制
上图其实已经很清晰了,简单理一下注册和获取注册表的流程:
- 注册:
- Eureka Client 发起 Register 请求。
- Eureka Server 将 Eureka Client 信息添加到注册表,同时使 ReadWriteCacheMap 缓存失效。
- 一段时间后(默认30s),Eureka Server 的后台线程发现 ReadWriteCacheMap 被清空了,就会清空 ReadOnlyCacheMap 缓存。
- 获取注册表:
- Eureka Client 发起Get请求。
- 首先,从 ReadOnlyCacheMap 缓存查询,有就返回。
- 如果没有,从 ReadWriteCacheMap 缓存查询,有就返回。
- 如果还没有,就查询内存中的注册表,同时将结果填充到 ReadWriteCacheMap 缓存和 ReadOnlyCacheMap 缓存。
这就是 Eureka Server 端的缓存机制,通过 ReadWriteCacheMap 缓存和 ReadOnlyCacheMap 缓存减少了注册表的读写冲突,起到了类似于读写分离的效果,进一步保证了 Eureka 的性能。
同时 Eureka Client 端也缓存了一份注册表信息,周期性的从 Eureka Server 拉取最新的数据。
本文只记录了Eureka的一些基本概念,后面再针对每个具体功能的源码实现做个详细记录。
参考:https://mp.weixin.qq.com/s/qjMphuPiihBmU2QtFMIfzw