Featured image of post Java工程师 ZooKeeper 1 入门

Java工程师 ZooKeeper 1 入门

🌏Java工程师 ZooKeeper 🎯 这篇文章用于记录 Java工程师 ZooKeeper 1 入门

🎄ZooKeeper 主要应用功能

🎯分布式配置管理:ZooKeeper可以用来进行分布式系统的配置管理,例如可以将一些全局参数存储在ZooKeeper中,并且可以动态地更新这些配置。**【举例说明】**一个分布式系统需要连接到数据库,在连接信息发生变化时,可以将新的数据库连接信息存储在ZooKeeper中,并通知所有相关的节点更新配置

🎯服务注册和发现:ZooKeeper可以作为命名服务来提供统一的命名空间,并帮助分布式系统实现服务注册发现的功能。**【举例说明】**在一个集群环境中,各个节点可以通过ZooKeeper来注册自己提供的服务,并获取其他节点提供的服务地址,从而实现服务发现。

🎯分布式锁:ZooKeeper提供了分布式锁的实现,可以帮助分布式系统协调各个节点的并发访问控制。**【举例说明】**在分布式环境中,多个节点可能需要同时访问共享资源,利用ZooKeeper的分布式锁可以确保只有一个节点能够访问共享资源,从而避免竞争条件。

🎯集群管理:ZooKeeper自身就是一个集群系统,可以用来管理整个集群的状态信息。他是一个分布式的、开源的分布式应用程序的协调服务 -> 实际上干活的还是各个结点 ZooKeeper只进行协调管理

🎄ZooKeeper的安装和配置

可见 :ZooKeeper的安装和配置

🎄ZooKeeper的命令

🍭ZooKeeper数据模型

(1)ZooKeeper是一个树形目录服务,其数据模型和UNIX的文件系统目录很相似,拥有一个层次化的结构

(2)这里面的每一个节点都被称为ZNode,每一个节点上都会保存自己的数据和结点信息

(3)结点可以拥有子节点,同时也允许存储少量的(1MB)数据存储在该节点下

(4)结点可以分为四大类:

  • PERSTSTENT 持久化结点
  • EPHEMERAL 临时结点 -e
  • PERSTSTENT_SEQUENTIAL 持久化顺序结点 -s
  • EPHEMERAL_SEQUENTIAL 临时顺序结点 -es

🍭ZooKeeper的命令操作

ZooKeeper的命令操作包括服务端、客户端方面

🌴服务端的操作

服务端的操作非常简单

(1)启动ZooKeeper服务./bin/zkServer.sh start
(2)查看ZooKeeper服务./bin/zkServer.sh status
(3)停止ZooKeeper服务./bin/zkServer.sh stop
(4)重启ZooKeeper服务./bin/zkServer.sh restart

🌴客户端的操作

1ZooKeeper客户端连接服务端(指定IP + 端口)  `./zkCli.sh -server localhost:2181`
2查看根目录下的列表:`ls /`
3创建节点:`create /目录结构 指定要存的数据`
4获取节点下存储的数据:`get /目录结构`
5为节点设置存储的数据:`set /目录结构 指定要存的数据`
6删除结点:`delete /指定目录结构`
7联级删除:`deleteall` 
8临时结点`只在当前的会话有效 ` `create -e /目录结构`
9顺序结点的创建  `create -s /目录结构`
10临时顺序结点的创建  `create -es /目录结构`

🔮持久化结点的相关操作

(1)ZooKeeper客户端连接服务端(指定IP + 端口) ./zkCli.sh -server localhost:2181

(2)查看根目录下的列表:ls /

(3)创建节点:create /目录结构 指定要存的数据

(4)获取节点下存储的数据:get /目录结构

(5)为节点设置存储的数据:set /目录结构 指定要存的数据

(6)删除结点:delete /指定目录结构

(7)联级删除:deleteall

(8)注意:不可级联创建结点

🔮临时结点的创建

临时结点只在当前的会话有效 create -e /目录结构

🔮顺序结点的创建

命名默认是顺序的 create -s /目录结构

**🔮临时顺序结点的创建 ** create -es /目录结构

🎄ZooKeeper的JavaAPI操作

对应下图的ZooKeeper Java API

🍭Curator介绍

Curator是Apache ZooKeeper的Java客户端库 演变过程:原生JavaAPI -> ZkClient -> Curator

🍭Curator API常用操作

🌱前置Maven配置

<!-- 使用Curator操作ZooKeeper -->
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-framework</artifactId>
    <version>4.0.0</version> <!--当前最新版本-->
</dependency>
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>4.0.0</version>
</dependency>
<!--junit4-->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>

⚡创建zkApiTest类进行测试

连接客户端 -> client变量接收客户端连接对象

注意:代码中的🎯.namespace("bbm") 绑定名称空间 可以简化操作,也就是说 之后的所有操作都是在远程ZooKeeper的/bbm目录下操作

public class zkApiTest {

    RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 10);
    private static final String connectString = "node1:2181";
    // 定义客户端连接
    private static CuratorFramework client = null;
    
    @Before
    public void init() throws IOException {
        // 创建一个客户端的连接
        client = CuratorFrameworkFactory.builder().connectString(connectString)
            .sessionTimeoutMs(60 * 1000)
            .connectionTimeoutMs(15 * 1000)
            .retryPolicy(retryPolicy)
            🎯.namespace("bbm") // 绑定名称空间 简化操作
            .build();
        client.start(); // 创建之后进行start之后才能操作远程的ZooKeeper
    }
    
    @After
    public void close() {
        // 释放资源
        if(client != null) client.close();
    }
}

⚡连接客户端的两种方式

/**
 * Curator建立连接 第一种方式 CuratorFrameworkFactory.newClient(..)
 */
@Test
public void setUpConnection() {
    /**
     * @Param connectString – list of servers to connect to 连接字符串 地址和端口("192.168.12.3:2181, 192.168.12.4"2181")
     * @Param sessionTimeoutMs – session timeout 会话超时时间
     * @Param connectionTimeoutMs – connection timeout 连接超时时间
     * @Param retryPolicy – retry policy to use 重试策略
     */
    RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 10);
    CuratorFramework client = CuratorFrameworkFactory.newClient("node1:2181", 60 * 1000, 15 * 1000, retryPolicy);
    client.start(); // 测试客户端是否能正常连接和运行
}

/**
 * Curator建立连接 第2种方式 使用建造者模式进行创建
 */
@Test
public void setUpConnection2() {
    RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 10);
    CuratorFramework client = CuratorFrameworkFactory.builder().connectString("node1:2181")
        .sessionTimeoutMs(60 * 1000)
        .connectionTimeoutMs(15 * 1000)
        .retryPolicy(retryPolicy)
        .namespace("bbm") // 绑定名称空间 简化操作
        .build();
    client.start();
}

创建节点(创建多种节点)

创建节点 -> 持久、临时、顺序、数据(和shell操作是对应的)

1)基本创建 (2)创建带有数据的结点 (3)设置结点的类型 (4)创建多级结点/app1/p1

(1)基本创建 -> 默认创建的是持久化的结点

@Test
public void createNode() throws Exception {
    // (1) 基本创建
    String str = client.create().forPath("/app1_202311301614");
    System.out.println("str = " + str);
}

查看创建后的结果:

如果创建节点的时候没有指定存储的数据 则默认存储客户端的IP地址:

🍭分布式锁

🍭模拟12306售票案例