2

引言

行内在构建微服务平台时,选用了 Zookeeper 作为服务注册中心。

就分布式 CAP 定理而言,ZookeeperCPEurekaAP,但其实是 AP 场景更适合服务注册中心的高可用,可用性要比一致性更重要。

目前国内的 Zookeeper 普及受影响于 Dubbo 的开源,阿里巴巴有一套自己的服务注册中心配合 Dubbo,但该服务注册中心却并未随 Dubbo 一起开源,客观环境限制下,Dubbo 官方推荐使用 Zookeeper 作为服务注册中心,这影响了一大批企业,虽然在后来阿里巴巴官方相关团队已经发布文章不推荐使用 Zookeeper,但这就像谣言和辟谣一样,谣言传播的范围远远高于辟谣信息的传播范围。

阿里巴巴为什么不用 ZooKeeper 做服务发现? - 阿里中间件团队博客

所以,如果不是非要用 Zookeeper 搭建服务注册中心的话,本文请选择性观看,就当做是一个对 Zookeeper 的了解学习就好。Zookeeper 仍然是一款伟大的框架,当之无愧的分布式顶级项目,在数据一致性方面无可匹敌。

再次打开 Spring 官网,不由得感叹开源社区的伟大,在去年学习微服务时,仅有 EurekaZuulFeignRibbonHystrix 等几个组件,如今已经发展至 30 多个开源组件;如今的 Spring Cloud,已经支持 Zookeeper,成为业界最流行的微服务解决方案。

image.png

Zookeeper

官方定义:

ZooKeeper: A Distributed Coordination Service for Distributed Applications.

Zookeeper:面向分布式应用的分布式协调服务。

安装

Zookeeper下载地址:Releases - Apache Zookeeper

选择一个稳定的 Release 版本下载:

image.png

Zookeeper 采用 Java 编写,运行 Zookeeper 之前需要配置 Java 环境。

默认 conf 目录下没有配置文件,此处只做学习使用,创建文件 zoo.cfg,内容与 zoo_sample.cfg 一致,使用默认配置即可。

image.png

在命令行中运行 bin 目录下的 zkServer.cmd 启动 Zookeeper 服务器(若在 Unix 环境下请运行 .sh 脚本,下同)。

image.png

启动客户端连接。

运行 zkCli.cmd 启动 Zookeeper 客户端,是一个可对服务器数据进行操作的命令行界面,与 Redis 类似。

image.png

数据结构

引用 Zookeeper 官网的一张图,Zookeeper 的内部数据结构采用树状结构,以 / 为根节点,类似于 Unix 文件系统,每个节点中可以存储信息。

image

Zookeeper 节点分为永久节点、顺序节点、临时节点,如下图所示。

image.png

永久节点:节点始终存在,除非显式执行删除命令,永久节点下可以创建子节点。

顺序节点:节点创建之后,Zookeeper 为节点添加一个序列号,如图中的 zk-sequence-node0000000008,其中 0000000008Zookeeper 追加的序列号。该序列号在同一父节点下是唯一的,格式为 10 位数字,不足 10 位用 0 补齐。

临时节点:该节点的生命周期依赖于创建它的会话,当客户端断开连接后,该节点会被自动删除,临时节点不允许有子节点。

image.png

这里的临时节点就非常适合做微服务注册中心。

微服务启动时作为客户端向 Zookeeper 注册,创建包含当前微服务信息的临时节点,当微服务下线时,该临时节点自动被 Zookeeper 删除,保障了微服务的高可用。

并且客户端可以添加对节点的监听 watch,也就是观察者,当节点更新时,会通知客户端,这样能保证微服务获取到的服务列表一直是最新的。

可视化工具

Zookeeper 的基础命令就不做讲解了,Zookeeper 的命令无非是对节点的增加、删除、更新、查询,没有必要深入学习,作为非专业应用支持人员,简单做了解即可。

这里推荐使用可视化工具对 Zookeeper 进行学习,可以可视化对节点进行操作,不需要打命令那么麻烦了。

zkui - Github

image.png

实战

新建 maven 项目,添加依赖:

<dependencies>
    <!-- Zookeeper 服务发现组件 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
    </dependency>
</dependencies>

添加配置:

spring:
  application:
    # 应用名
    name: sample-application
  cloud:
    zookeeper:
      # Zookeeper 地址,此处演示只使用单 Zookeeper 节点,未部署集群
      connect-string: localhost:2181
      # 服务发现
      discovery:
        # 注册自身
        register: true
        # 优先注册 IP
        prefer-ip-address: true
server:
  port: 9000

启动应用,会打印出很多 Zookeeper 连接相关的日志:

image.png

查看 Zookeeper 服务器的节点信息,在 services/sample-application 节点下挂载了一个 nameUUID 格式的临时节点,节点内存储了该微服务的相关信息。

image.png

总结

以后有时间一起学习 Zookeeper 集群及其他主流分布式解决方案。

本文作者:河北工业大学梦云智开发团队 张喜硕


张喜硕
2.1k 声望423 粉丝

浅梦辄止,书墨未浓。