微服务(组件篇)[Eureka]

Eureka 原理

Eureka 的服务注册机制

服务注册机制

  • 新的服务部署完成后,会访问 Eureka Server,来给自己注册。
  • 每个 Eureka Client,每隔 30 秒,会从 Eureka Server 获取注册表的变化,以便及时得知哪些服务已经挂了。
  • 每个 Eureka Client,每隔 30 秒,会发送心跳给 Eureka Server,证明自己还活着。

Eureka Server 的访问频率

假设现在有 100 个服务,每个服务部署到 20 台服务器上,机器是标准的 4 核 8G 配置。相当于 100 * 20 = 2000 个服务,也就是 2000 台服务器。每台服务器上都有一个 Eureka Client 组件,他们每隔 30 秒都会访问 2 次 Eureka Server,一次是获取注册表的变化,一次是发送心跳。

  • 每分钟:一台服务器获取 2 次注册表的变化,发送 2 次心跳,2000 台服务器,Eureka Server 就要被访问 8000 次。
  • 每秒:8000 / 60 ≈ 133 次,算上其它一些额外操作,我们算作 200 次左右。
  • 每天:8000 * 60 * 24 = 1152 万次。

对于上述情况,Eureka Server 将要面对日千万级的访问量。

Eureka Server 的存储方式

首先,我们来看看 Eureka 存储注册表的源码。

public abstract class AbstractInstanceRegistry implements InstanceRegistry {
	private final ConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>> registry = new ConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>>();
}
  • registry:以 ConcurrentHashMap 作为核心结构,说明注册表是基于纯内存的。key
    是服务名称,如:user-service。value 是服务的多个实例。
  • Map<String, Lease<InstanceInfo>>:key 是服务实例的 id,InstanceInfo
    存储服务实例的具体信息,如 IP 地址、端口、hostname 等。
  • Lease:维护服务实例的最近心跳时间。

结论:维护注册表、获取注册表的变化、更新心跳时间的操作,全部都发生在内存里,速度快也就不难理解了。

Eureka 的多级缓存机制

多级缓存尽可能保证注册表的数据不会频繁的出现读写冲突问题。也提高了速度,性能很高。
多级缓存

  • 当 Eureka Client 获取注册表时,先读取 ReadOnlyCacheMap,如果没有,就去读 ReadWriteCacheMap,还没有,就直接读取注册表。
  • 当注册表发生变化时,会过期掉 ReadWriteCacheMap,不影响读取 ReadOnlyCacheMap(30 秒内)。
  • 30 秒后,Eureka Server 发现 ReadWriteCacheMap 已经被清空了,就会清空 ReadOnlyCacheMap。
  • Eureka Client 再次获取注册表时,发现两个 CacheMap 都是空的,就会直接读取注册表,同时填充缓存。

Eureka 的特点总结

  • 请求频率:每 30 秒获取一次注册表,每 30 秒发送一次心跳。保证了每秒处理几百次请求的能力。
  • 纯内存注册表:所有请求都可以在内存中处理。保证了高性能。
  • 多级缓存机制:避免发生频繁的读写冲突,进一步提升性能。

Eureka 与 Zookeeper

相同点

Eureka 和 Zookeeper 都在分布式系统中,充当着服务注册中心的角色。
作为服务管理组件,都需要具备以下三个能力:

  • 熔断:当检测到某个服务异常时,要及时把它断掉,以防整个项目被拖垮。
  • 降级:在业务高峰期,为了保障核心服务,把不重要的服务暂时停掉。
  • 限流:面对突然的大量请求,为了保障服务节点的正常运行,要每隔一段时间,再放一批请求进去。

不同点

Zookeeper 作为第三方组件,被 Dubbo 使用;而 Eureka,是 Spring Cloud 中的自带组件。
说到这儿,我们有必要看看 Dubbo 与 Spring Cloud 的区别:

  • 服务调用方式:Dubbo 是基于 RPC 调用的;Spring Cloud 是基于 HTTP 协议的 REST API
    调用的。所以在远程调用的效率上,Dubbo 大约是 Spring Cloud 的三倍。
  • 框架:Dubbo 是一个微服务治理的框架,依赖于很多第三方插件;而 Spring Cloud 有一套成熟的解决方案。

Zookeeper 放弃了一定的可用性,在服务器挂了后,需要选举出新的 leader,会产生延迟;而 Eureka 为了保证可用性,设定每个节点都是公平的,不需要选举 leader,但也放弃了一致性。

栗子

为了测试分布式,我们先配置 host,模拟服务端和客户端。
127.0.0.1 master
127.0.0.1 slave
127.0.0.1 slave2

创建 Eureka 服务项目(eurekaserver)

  • 第一步:选择 Create New Project,创建一个 Spring Initializr 项目,选择 Web 组件和 Eureka Server 组件。
    创建项目
    起名
    Web
    Eureka Server
  • 第二步:在启动类中加入 Eureka 的服务注解 @EnableEurekaServer。
    @EnableEurekaServer
  • 第三步:配置服务属性。
    配置
  • 第四步:启动项目,访问 127.0.0.1:8761,进入管理界面。
    服务
    可以看到 EUREKASERVER 服务已经注册进去了。

创建 Eureka 服务提供项目(user)

  • 第一步:选择 Create New Project,创建一个 Spring Initializr 项目,选择 Web 组件和 Eureka Discovery 组件。
    Eureka Discovery
  • 第二步:在启动类中加入 Eureka 的客户端注解 @EnableEurekaClient。
    @EnableEurekaClient
  • 第三步:配置客户端属性。
    配置
  • 第四步:编写测试接口。
    测试接口
    第五步:启动项目,访问 127.0.0.1:8761,进入管理界面。
    服务
    可以看到 USER 服务也注册进去了。

创建 Eureka 服务调用项目(customer)

  • 第一步:选择 Create New Project,创建一个 Spring Initializr 项目,选择 Web 组件和 Eureka Discovery 组件。
  • 第二步:在启动类中加入 Eureka 的客户端注解 @EnableEurekaClient。
  • 第三步:配置客户端属性。
    配置
  • 第四步:调用服务端的接口。
    测试接口
  • 第五步:启动项目,访问 127.0.0.1:8080/test/testByEureka。
    结果
    我们可以看到 customer 成功的访问到了 user 服务。使用 HTTPclient 的方式访问接口,有点麻烦,我们可以使用 Eureka 中的 RestTemplate,不仅方便,还支持负载均衡。
    RestTemplate
    再启动一个相同的 user,把端口改为 8200,访问 127.0.0.1:8761,进入管理界面。
    服务
    可以看到现在有2个 USER 服务,端口分别为 8100 和 8200。
    访问 127.0.0.1:8080/test/testByRestTemplate。
    第一次调用了 8200 服务。
    结果
    刷新时,调用了 8100 服务。
    在这里插入图片描述
    再次刷新,又调用了 8200 服务。(默认分配算法是轮询)
    结果
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值