用于微服务注册和发现的 ZooKeeper

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战(已更新的所有项目都能学习) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新开坑项目:《Spring AI 项目实战》 正在持续爆肝中,基于 Spring AI + Spring Boot 3.x + JDK 21..., 点击查看 ;
  • 《从零手撸:仿小红书(微服务架构)》 已完结,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观

在微服务世界中,多个服务通常分布在 PaaS 环境中。不可变的基础设施由容器或不可变的 VM 映像提供。服务可以根据某些预定义的指标扩大和缩小。在部署服务并准备好使用之前,可能不知道服务的确切地址。

服务端点地址的动态特性由服务注册和发现处理。在此,每个服务都向代理注册并提供有关自身的更多详细信息,例如端点地址。然后其他消费者服务查询代理以找出服务的位置并调用它。注册和查询服务有多种方式,例如 ZooKeeper、etcd、consul、Kubernetes、Netflix Eureka 等。

从单体到微服务重构 展示了如何将现有单体重构为基于微服务的应用程序。用户、目录和订单服务 URI 是静态定义的。此博客将展示如何使用 ZooKeeper 注册和发现微服务。

非常感谢 Ioannis Canellos ( @iocanel ) 对 ZooKeeper 的所有破解!

什么是动物园管理员?

ZooKeeper 是一个 Apache 项目,提供分布式、最终一致的分层配置存储。

ZooKeeper 是一种集中式服务,用于维护配置信息、命名、提供分布式同步和提供组服务。所有这些类型的服务都以某种形式被分布式应用程序使用。

因此服务可以使用逻辑名称向 ZooKeeper 注册,配置信息可以包含 URI 端点。它也可以包含其他细节,例如 QoS。

ZooKeeper 有一个陡峭的学习曲线,如 Apache ZooKeeper Made Simpler with Curator 中所述。因此,本博客将不直接使用 ZooKeeper,而是使用 Apache Curator

Curator n ˈkyoor͝ˌātər:博物馆或其他藏品的饲养员或保管人 – 动物园管理员。

Apache Curator 有几个组件,本博客将使用 框架

Curator Framework 是一个高级 API,它大大简化了 ZooKeeper 的使用。它添加了许多基于 ZooKeeper 构建的功能,并处理管理与 ZooKeeper 集群的连接和重试操作的复杂性。

ZooKeeper 概念

ZooKeeper 概述 提供了对主要概念的很好的概述。以下是一些相关的:

  • Znodes :ZooKeeper 将数据存储在一个共享的分层命名空间中,该命名空间的组织方式类似于标准文件系统。名称空间由数据寄存器组成——用 ZooKeeper 的说法称为 znodes—— 它们类似于文件和目录。
  • 节点名称 :ZooKeeper 名称空间中的每个节点都由路径标识。节点的确切名称是由斜杠 (/) 分隔的一系列路径元素。
  • 客户端/服务器 :客户端连接到单个 ZooKeeper 服务器。客户端维护一个 TCP 连接,通过它发送请求、获取响应、获取监视事件和发送心跳。如果与服务器的 TCP 连接中断,客户端将连接到另一台服务器。
  • 配置数据 :ZooKeeper 命名空间中的每个节点都可以有与其关联的数据以及子节点。 ZooKeeper 最初设计用于存储协调数据,因此每个节点存储的数据通常很小,在 KB 范围内)。
  • 集成 :ZooKeeper 本身旨在通过一组称为集成的主机进行复制。构成 ZooKeeper 服务的服务器必须相互了解。
  • 手表 :ZooKeeper 支持 手表 的概念。客户端可以在 znode 上设置监视。当 znode 更改时,将触发并删除 watch。

ZooKeeper 是一个关于 CAP 定理的 CP 系统。这意味着如果出现分区故障,它将保持一致但不可用。这可能会导致 Eureka! 中解释的问题。 为什么不应该使用 ZooKeeper 进行服务发现

然而,ZooKeeper 是微服务世界中使用的最流行的服务发现机制之一。

让我们开始吧!

启动动物园管理员

在 Docker 容器中启动 ZooKeeper 实例:


 docker run -d -p 2181:2181 fabric8/zookeeper

使用 telnet 验证 ZooKeeper 实例:


 docker run -d -p 2181:2181 fabric8/zookeeper

键入命令“ruok”以验证服务器是否在非错误状态下运行。如果服务器正在运行,它将以“imok”响应:


 docker run -d -p 2181:2181 fabric8/zookeeper

否则它根本不会响应。 ZooKeeper 还有其他类似的 四字母命令。

服务注册和发现

在我们的例子中,每个服务、用户、目录和订单都有一个预先初始化的 bean,它注册和注销服务作为生命周期初始化方法的一部分。这是来自 CatalogService 的代码:


 docker run -d -p 2181:2181 fabric8/zookeeper

代码非常简单,它注入 ServiceRegistry 类,带有 @ZooKeeperRegistry 限定符。然后用于注册和注销服务。可以在相同的逻辑名称下注册多个 URI,每个 URI 对应一个无状态服务。

这个时候限定符来自另一个maven模块。一种更简洁的 Java EE 方法是将 @ZooKeeperRegistry 限定符移动到 CDI 扩展( #20 )。当在任何 REST 端点上指定此限定符时,将向 ZooKeeper 注册服务( #22 )。目前,服务端点 URI 也是硬编码的 ( #24 )。

ZooKeeper 类是什么样的?

  1. ZooKeeper 类使用构造函数注入和硬编码 IP 地址和端口( #23 ):
  2. 
     docker run -d -p 2181:2181 fabric8/zookeeper
    

    它执行以下任务:

    1. 从属性文件加载 ZooKeeper 的主机/端口
    2. 初始化 Curator 框架并启动它
    3. 初始化一个 hashmap 来存储 URI 名称到 zNode 的映射。稍后删除此节点以注销服务。
  3. 服务注册是使用 registerService 方法完成的:
  4. 
     docker run -d -p 2181:2181 fabric8/zookeeper
    

    代码非常简单:

    1. 如果需要,创建父 zNode
    2. 创建一个临时的和顺序的节点
    3. 向该节点添加元数据,包括 URI
  5. 服务发现是使用 discover 方法完成的:

 docker run -d -p 2181:2181 fabric8/zookeeper

再次,简单的代码:

  1. 查找为服务注册的路径的所有孩子
  2. 获取与此节点关联的元数据,在我们的例子中为 URI,然后返回。在本例中返回第一个这样的节点。可以将不同的 QoS 参数附加到配置数据。这将允许返回适当的服务端点。

阅读 ZooKeeper Javadocs 的 API。

ZooKeeper watches 可以设置为通知客户端服务的生命周期( #27 )。 ZooKeeper 路径缓存可以提供子节点的优化实现( #28 )。

多个服务发现实现

我们的购物车应用程序有两个 服务发现实现 ServiceDisccoveryStatic ServiceDiscoveryZooKeeper 。第一个具有静态定义的所有服务 URI,另一个从 ZooKeeper 检索它们。

通过在 services 模块中创建新包并实现 ServiceRegistry 接口,可以轻松添加其他注册和发现方式。例如, Snoop etcd Consul Kubernetes 。随时为其中任何一个发送 PR。

运行应用程序

  1. 确保 ZooKeeper 映像正在如前所述运行。
  2. 下载 并运行 WildFly:
  3. 
     docker run -d -p 2181:2181 fabric8/zookeeper
    
  4. 部署应用程序:
  5. 
     docker run -d -p 2181:2181 fabric8/zookeeper
    
  6. localhost:8080/everest-web/ 访问应用程序。在 Java EE 应用程序的单体到微服务重构 博客中了解有关应用程序和不同组件的更多信息。

最新发布