Zookeeper(二)实战-客户端使用


前言

本文主要讲解Zookeeper经典使用场景以及Zookeeper原生的客户端和Apache Curator开源客户端使用,以及Zookeeper集群的配置。
Zookeeper的使用主要包括:

  1. 分布式配置中心
  2. 分布式注册中心
  3. 分布式锁
  4. 分布式队列
  5. 集群选举
  6. 分布式屏障
  7. 发布/订阅

一、Zookeeper的Java客户端

1.Zookeeper分布式配置中心使用

配置中心原理就是对某个节点监听,只要节点有变化就会通知客户端,获取变化的数据。
效果:
在这里插入图片描述
在这里插入图片描述

我直接把我的pom文件贴出来了,其实只需要一个zookeeper即可。其余是属于项目补充。

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.5</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--引入zookeeper-->
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.6.3</version>
        </dependency>
        <!--引入lombok 方便处理类-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--引入Junit测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
        <!--引入Jackson用于序列化类-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
        <!--springboot-test的包-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>

    </dependencies>

创建一个配置类:

@Data //注在类上,提供类的get、set、equals、hashCode、canEqual、toString方法
@NoArgsConstructor //注在类上,提供类的无参构造
public class MyConfig {
    private String key;
    private String name;
}

创建Zookeeper客户端(感觉不好理解的代码都加了注释)

@Slf4j
public class ZookeeperClient {

    @Test
    public void test01() throws IOException, InterruptedException, KeeperException {
        final String CONNECT_STRING = "10.10.2.21:2181";
        final int SESSION_TIME_OUT = 30*1000;
        /*
        倒计数器:多个线程之间的同步工具类。
        主要是用来控制线程等待,可以让某一个线程等待直到倒计数				结束,再开始执行。
       下面主线程就是用countDownLatch.await();
       来阻塞主线程的执行,直到Zookeeper线程创建完毕才会继续执行主线程之后的代码
        */
        final CountDownLatch countDownLatch = new CountDownLatch(1);
        final ZooKeeper zooKeeper = new ZooKeeper(CONNECT_STRING, SESSION_TIME_OUT, new Watcher() {
             @Override
             public void process(WatchedEvent watchedEvent) {
                 if(watchedEvent.getType() == (Event.EventType.None) && watchedEvent.getState() == Event.KeeperState.SyncConnected){
                    log.info("连接已建立");
                    countDownLatch.countDown();//递减锁的个数,当计数达到零时释放所有等待的线程
                 }
             }
         });
        /**
         * 为什么要用CountDownLatch?因为创建Zookeeper客户端是异步线程并且是守护线程
         * (this.createConnection()方法中new了两个线程new ClientCnxn.SendThread()和 new ClientCnxn.EventThread()
         * 点进去会发现都是守护线程 this.setDaemon(true);)
         * 也就意味着当主线程结束的时候,zookeeper的线程也会随之结束,这个时候zookeeper可能还没链接成功那
         */
        countDownLatch.await();//阻塞当前线程,直到计数器值为零。

        final MyConfig myConfig = new MyConfig();
        myConfig.setKey("anyKey");
        myConfig.setName("anyName");
        //使用的是jackson序列化工具类
        final ObjectMapper objectMapper = new ObjectMapper();
        final byte[] bytes = objectMapper.writeValueAsBytes(myConfig);
        //创建节点
        final String s = zooKeeper.create("/myconfig", bytes, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        //这个watcher提出来写是因为,zookeeper对节点的监听是一次性的,如果想要实现循环监听的话,需要循环调用。即在watcher中zooKeeper.getData()
        final Watcher watcher = new Watcher() {
            @SneakyThrows
            @Override
            public void process(WatchedEvent event) {
                log.info(".......");
                if(event.getType() == Event.EventType.NodeDataChanged && event.getPath() != null && event.getPath().equals("/myconfig")){
                    log.info("path:{}发生了变化",event.getPath());
                    final byte[] data = zooKeeper.getData("/myconfig", this, null);
                    final MyConfig newConfig = objectMapper.readValue(new String(data), MyConfig.class);
                    log.info("数据发生变化:{}",newConfig);
                }
            }
        };
        //获取数据并创建监听
        byte[] data = zooKeeper.getData("/myconfig", watcher, null);//如果不需要监听节点变化,watcher直接复制为null就好了
        final MyConfig originalMyConfig = objectMapper.readValue(new String(data), MyConfig.class);
        log.info("原始数据:{}",originalMyConfig);
        //之所以要一直睡眠是因为zookeeper客户端的线程是守护线程,所以主线程结束,zookeeper客户端就会结束,所以为了达到客户端一直能够连接上服务端所以主线程必须一直睡眠
        TimeUnit.SECONDS.sleep(Integer.MAX_VALUE);
    }
}

Zookeeper这么多实例化方法中主要参数详解:
在这里插入图片描述
对于每个参数的含义对应的构造方法上面都有备注
比如:connectString
在这里插入图片描述

2.Zookeeper的JavaAPI使用

使用一个抽象类用来创建Zookeeper连接
在这里插入图片描述
这是getData的方法用来获取指定节点的数据。
在这里插入图片描述
setData方法用来设置节点数据
在这里插入图片描述

二、使用Curator客户端

pom文件添curator-recipes对应的maven即可。
然后连接zookeeper的主要代码是
在这里插入图片描述

1.创建节点

<<1:>> 递归创建节点
在这里插入图片描述
在这里插入图片描述
<<2:>> protection模式创建节点
在这里插入图片描述

三、Zookeeper集群模式

概念

Zookeeper集群模式有三种不同类型的角色;
Leader: 处理所有的事务请求(写请求),可以处理读请求,集群中只能有一个Leader
Follower: 只能处理读请求,同时作为Leader的候选节点,即如果Leader宕机,Follower节点要参与薪的Leader选举中,有可能称为薪的Leader节点。
Observer: 只能处理读请求。不能参与选举。
在这里插入图片描述

集群搭建

目前先搭建一个伪集群:
第一步:先配置事务数据存储路径,每个myid里面的数字都代表着它的服务对应的ID
在这里插入图片描述
第二步:
配置对应的配置文件
第一个端口2001是Leader和Follower节点之间通信的端口
第二个端口3001是进行集群选举的时候需要的端口
总共配置四个服务,第四个配置成Observer节点
在这里插入图片描述

在这里插入图片描述
第三步启动服务:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值