zookeeper学习记录

news2024/11/24 19:15:06

本文Java代码地址: https://gitee.com/blackjie_1/ljUp/tree/master/zookeeperDemo

个人博客网站:什么是快乐

基于docker 安装

拉取zookeeper 3.4.10

docker pull zookeeper:3.4.10

启动服务端

docker run -d -p 2181:2181 -v /root/docker/zookeeper:/home/zookeeper --name zookeeper_1 --restart always zookeeper:3.4.10

启动客户端

docker run -it --``rm` `--link zookeeper_one:zookeeper zookeeper zkCli.sh -server zookeeper

或者

docker exec -it zookeeper_1 zkCli.sh

数据模型

其数据结构类似一个树形结构,每个节点可以拥有子节点并能存储1M的数据

1、持久化

2、临时节点 -e

3、持久化顺序节点 -s

4、临时顺序节点 -es

客户端命令

连接本地zookeeper
docker exec -it zookeeper_1 zkCli.sh

或者

docker run -it --rm --link zookeeper_1:zookeeper_1 zookeeper:3.4.10  zkCli.sh -server zookeeper_1
退出
quit
查看节点
ls  /节点名称
创建节点
create /节点名称 [数据] 

create -e /节点名称 [数据]    临时节点,当前会话断开时,临时节点会删除

create -s /节点名称 [数据]    顺序节点,节点名称后会有编号
  
create -s /节点名称 [数据]    临时的顺序节点
获取数据
get /节点名称
设置数据
set /节点名称 [数据]
删除
delete  /节点名称

delete all /节点名称  删除节点及节点下所有节点

Java代码操作

maven依赖

<!-- 本次学习zookeeper版本是3.4.10-->

        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-client</artifactId>
            <version>2.12.0</version>

        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>2.12.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>2.12.0</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>

增删改查

连接
public void curatorFramework() {
        //重试策略
        ExponentialBackoffRetry exponentialBackoffRetry = new ExponentialBackoffRetry(3000, 10);

        //第一种方式
//        CuratorFramework client = CuratorFrameworkFactory
//                .newClient(zookeeperUrl, 60000, 15000, exponentialBackoffRetry);

        //第二种方法
        client = CuratorFrameworkFactory.builder()
                .connectString("192.168.106.128:2181")
                .connectionTimeoutMs(15000)
                .sessionTimeoutMs(60000)
                .retryPolicy(exponentialBackoffRetry)
                .namespace("lj")
                .build();

        client.start();
    }
新增
    /**
     * zookeeper 创建节点 持久、临时、顺序  带有数据
     * create
     * 1、创建节点并带有数据
     * 2、设置节点类型
     * 3、创建多级节点
     */
    @Test
    public void curatorCreate() throws Exception {
        //基本创建
        String app1 = client.create().forPath("/app1");
        //创建带有数据的节点
        String s1 = client.create().forPath("/app2", "李杰_app2".getBytes(StandardCharsets.UTF_8));
        //创建节点默认类型:持久化。可通过withMode方法设置类型
        String s2 = client.create().withMode(CreateMode.EPHEMERAL).forPath("/app3", "李杰_临时".getBytes(StandardCharsets.UTF_8));
        //创建多级节点
        //creatingParentsIfNeeded  :创建多级节点,如果父节点不存在则创建父节点
        String s3 = client.create().creatingParentsIfNeeded().forPath("/app4/app5", "李杰_多级节点".getBytes(StandardCharsets.UTF_8));

        System.out.println(s3);
    }
查询
 /**
     * zookeeper 查询节点
     * 1、查询字节点 ls /
     * 2、获取数据  get /
     * 3、查询节点状态 ls -s
     */
    @Test
    public void curatorQuery() throws Exception {
        //获取数据  getData
        byte[] bytes = client.getData().forPath("/app1");
        //查询子节点  getChildren
        List<String> strings = client.getChildren().forPath("/");

        //查询子节点信息+数据信息
        //stat 用于获取节点信息,结果会放在stat对象中
        Stat stat = new Stat();
        byte[] bytes1 = client.getData().storingStatIn(stat).forPath("/app2");

        System.out.println(new String(bytes1));

    }
修改
/**
     * zookeeper 修改节点数据
     * 1、修改数据
     * 2、根据版本修改数据
     */
    @Test
    public void curatorUpdate() throws Exception {
        //1、修改数据
//        client.setData().forPath("/app2","app2_修改".getBytes(StandardCharsets.UTF_8));

        //2、根据版本修改数据  withVersion
        //获取版本号
        Stat stat = new Stat();
        client.getData().storingStatIn(stat).forPath("/app2");
        //根据版本号修改数据
        client.setData()
                .withVersion(stat.getVersion())
                .forPath("/app2","app2_version_update".getBytes(StandardCharsets.UTF_8));

    }
删除
/**
     * zookeeper 删除节点
     * 1、删除单个节点
     * 2、删除带有子节点的节点
     * 3、必须成功的删除
     * 4、回调函数
     */
    @Test
    public void curatorDelete() throws Exception {
        //1、删除数据
        client.delete().forPath("/app1");

        //2、删除带有子节点的节点   deletingChildrenIfNeeded
        client.delete().deletingChildrenIfNeeded().forPath("/app4");

        //3、删除子节点 (必须删除成功,本质是重试策略) guaranteed
        client.delete().guaranteed().forPath("/app4");

        //4、回调函数 inBackground 。在删除后执行的方法
        client.delete().guaranteed().inBackground(new BackgroundCallback(){
            @Override
            public void processResult(CuratorFramework curatorFramework, CuratorEvent curatorEvent) throws Exception {
                System.out.println("我被删除了");
                System.out.println(curatorEvent);
            }
        }).forPath("/app4");

    }

监听器

* 监听节点
* 1、监听单个节点   nodeCache
* 2、监听节点下所有子节点  PathChildrenCache
* 3、监听单个节点和节点下的所有子节点  TreeCache
监听单个节点
@Test
    public void curatorFrameworkWatch() throws Exception {
        //监听单个节点
        //1、创建监听对象
        NodeCache nodeCache = new NodeCache(client,"/app2",false);

        //2、注册监听
        nodeCache.getListenable().addListener(new NodeCacheListener() {
            @Override
            public void nodeChanged() throws Exception {
                byte[] data = nodeCache.getCurrentData().getData();
                System.out.println("节点发生改变,当前值:"+new String(data));
            }
        });
        //3、开启监听
        nodeCache.start();
        while (true){

        }
    }
监听某节点下的所有子节点
/**
     * 监听某节点的所有子节点
     * @throws Exception
     */
    @Test
    public void curatorFrameworkWatchChildren() throws Exception {

        //监听某节点的所有子节点
        //1、创建监听对象PathChildrenCache
        PathChildrenCache pathChildrenCache = new PathChildrenCache(client, "/app2", true);

        //2、注册监听
        pathChildrenCache.getListenable().addListener(new PathChildrenCacheListener() {
            @Override
            public void childEvent(CuratorFramework curatorFramework, PathChildrenCacheEvent event) throws Exception {
                //会监听很多数据,包括节点新增,删除,修改连接等
                System.out.println("节点发生改变");
                System.out.println(event);

                //监听子节点数据发生变化
                if(PathChildrenCacheEvent.Type.CHILD_UPDATED.equals(event.getType())){
                    // 确实是子节点数据发生变化,获取变化后的值
                    byte[] data = event.getData().getData();
                    String s = new String(data);
                    System.out.println(s);
                }
            }
        });
        //3、开启监听
        pathChildrenCache.start();
        while (true){

        }
    }
监听某节点和其所有的子节点
 /**
     * 监听某节点和其所有子节点
     * @throws Exception
     */
    @Test
    public void curatorFrameworkWatchAll() throws Exception {

        //1、创建监听对象PathChildrenCache
        TreeCache pathChildrenCache = new TreeCache(client, "/app2");

        //2、注册监听
        pathChildrenCache.getListenable().addListener(new TreeCacheListener() {
            @Override
            public void childEvent(CuratorFramework curatorFramework, TreeCacheEvent event) throws Exception {
                //会监听很多数据,包括节点新增,删除,修改连接等
                System.out.println("节点发生改变");
                System.out.println(event);

                //监听子节点数据发生变化
                if(TreeCacheEvent.Type.NODE_UPDATED.equals(event.getType())){
                    // 确实是节点数据发生变化,获取变化后的值
                    byte[] data = event.getData().getData();
                    String s = new String(data);
                    System.out.println(s);
                }
            }
        });
        //3、开启监听
        pathChildrenCache.start();
        while (true){

        }
    }

分布式锁

简略概念:多机器下的对于锁的处理。实现方式:

1、redis (性能高,但是不是很可靠)

2、数据库实现(获得锁:数据库新增一条唯一数据。释放锁:删除新增的数据。锁等待:等新增成功。此思想同样可以用redis实现。)

3、zookeeper

在这里插入图片描述

Java代码实现

本次使用的锁是InterProcessMutex

主要步骤:

1、构建CuratorFramework client 对象

2、通过client 构建InterProcessMutex 对象:lock= new InterProcessMutex(client, “/lock”);

3、执行业务前获取锁:boolean acquire = lock.acquire(5, TimeUnit.SECONDS);

4、业务结束后释放锁:lock.release();

模拟售票

public class ZookeeperLockTests {

   private static class Tick12306{
        private int tick=100;

        public int buyTick(){
            int result=0;
            if(tick>0){
                result=tick;
                tick--;
            }else{
                System.out.println("无票了");
                return -1000;
            }
            return result;
        }
   }
   private static class OtherTick implements Runnable{
       //抢票机构名称
       private String name;

       //12306票池
       private Tick12306 tick12306;

       //分布式锁
       private InterProcessMutex lock;

       public OtherTick(String name,Tick12306 tick12306){
           this.name=name;
           this.tick12306=tick12306;
           //重试策略
           ExponentialBackoffRetry exponentialBackoffRetry = new ExponentialBackoffRetry(3000, 10);

           CuratorFramework client = CuratorFrameworkFactory.builder()
                   .connectString("192.168.106.128:2181")
                   .connectionTimeoutMs(15000)
                   .sessionTimeoutMs(60000)
                   .retryPolicy(exponentialBackoffRetry)
                   .namespace("lj")
                   .build();

           client.start();

           lock = new InterProcessMutex(client, "/lock");
       }

       //抢票
       @Override
       public void run() {

           while (tick12306.tick>0){
               try {
                   //获取锁
                   boolean acquire = lock.acquire(5, TimeUnit.SECONDS);
                   if(acquire){
                       System.out.println(this.name+"抢票:"+tick12306.buyTick());
                   }
               }catch (Exception e){
                   e.printStackTrace();
               }finally {
                   try {
                       //锁释放
                       lock.release();
                   } catch (Exception e) {
                       e.printStackTrace();
                   }
               }

           }
       }
   }


    public static void main(String[] args) {
        Tick12306 tick12306 = new Tick12306();
        OtherTick t1 = new OtherTick("携程", tick12306);
        OtherTick t2 = new OtherTick("飞猪", tick12306);
        Thread thread1 = new Thread(t1);
        Thread thread2 = new Thread(t2);
        thread1.start();
        thread2.start();
    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1220033.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电源地虚接,导致信号线发烫

音频板的信号是经过隔直电容接到音频板的。

【Linux】C文件系统详解(一)——C文件操作

文章目录 文件操作总结预备知识结论: C文件操作回顾语言方案w写入方式a写入方式r只读方式 系统方案但是这个**没有设置权限**,需要这样改: 文件操作总结 1.文件描述符,重定向,缓冲区,语言和系统关于文件的不同的视角的理解 – 都是要让我们深刻理解文件 2.文件系统 3.动静态库 …

实时音视频方案汇总

若有好的方案欢迎留言讨论&#xff0c;非常感谢&#xff0c;汇总了一些&#xff0c;从市面上了解的一些低时延的端到端的方案&#xff0c;仅供参照&#xff0c;若有问题&#xff0c;也欢迎留言更正&#xff01; 方案 方案描述 时延 备注 1大华同轴高清电缆200米电缆&#xf…

Python 使用difflib库 快速实现批量对比文件差异

关注我们 本文内容仅供学习参考,不足错误之处,还请多多指正,如果喜欢我们,请关注我们,你的支持就是我们最大的动力。 需求来源 霍克是一名软件实施工程师,每次版本升级时,虽然会提供升级相关的清单,但不会详细说明具体的改动点。为了能够更有针对性地验证和测试系统,…

通过 Canal 将 MySQL 数据实时同步到 Easysearch

Canal 是阿里巴巴集团提供的一个开源产品&#xff0c;能够通过解析数据库的增量日志&#xff0c;提供增量数据的订阅和消费功能。使用 Canal 模拟成 MySQL 的 Slave&#xff0c;实时接收 MySQL 的增量数据 binlog&#xff0c;然后通过 RESTful API 将数据写入到 Easysearch 中。…

Spring Boot Actuator:自定义端点

要在Spring Boot Actuator中实现自定义端点&#xff0c;可以按照以下步骤进行操作&#xff1a; 1.创建一个自定义端点类 该类需要使用Endpoint注解进行标记&#xff0c;并使用Component注解将其作为Spring Bean进行管理。 package com.example.highactuator.point;import lo…

Linux项目自动化构建工具:make与Makefile的基本用法

目录 1.什么是makefile 2.快速简单了解make/Makefile的使用 3.背后的知识&#xff1a; 4.依赖关系 5.其他写法 1.什么是makefile 会不会写makefile&#xff0c;从一个侧面说明了一个人是否具备完成大型工程的能力一个工程中的源文件不计数&#xff0c;其按类型、功能、模块…

phpStorm Xdebug调试 加FireFox浏览器

步骤1&#xff1a; [Xdebug] zend_extension“D:\phpstudy_pro\Extensions\php\php5.4.45nts\ext\php_xdebug.dll” xdebug.collect_params1 xdebug.collect_return1 xdebug.remote_enableOn xdebug.remote_hostlocalhost xdebug.remote_port9001 xdebug.remote_handlerdbgp ;…

超融合还是虚拟化?一文了解二者的区别、优缺点与传统虚拟化转型方案

超融合作为一种创新的 IT 基础架构&#xff0c;从最初进入市场&#xff0c;到当下成为主流方案&#xff0c;发展速度十分迅猛&#xff0c;且未来趋势依然向好。但对于国内不少用户而言&#xff0c;“超融合”仍是一个新概念&#xff0c;很容易与“虚拟化”相混淆&#xff1a;“…

如何为初创企业选择合适的 ERP 系统?

**ERP系统**是制造、分销、供应链、金融、会计、风险管理等多个行业必不可少的企业技术解决方案。不论垂直行业、企业规模或目标受众如何&#xff0c;将ERP作为企业管理战略的核心部分都非常重要。 对于渴望发展的小型企业和初创企业来说&#xff0c;更是如此。大型企业需要对…

quickapp_快应用_tabBar

tabBar 配置项中配置tabBar(版本兼容)使用tabs组件配置tabBar语法示例问题-切换tab没有反应问题-数据渲染问题解决优化 问题-tab的动态配置 第三方组件tabbar 一般首页都会显示几个tab用于进行页面切换&#xff0c;以下是几种tab配置方式。 配置项中配置tabBar(版本兼容) 在m…

三种快速创建SpringBoot项目的方式

文章目录 在线创建IntelliJ IDEA 创建Maven 创建基本项目结构 SpringBoot 是一个快速开发框架&#xff0c;通过maven依赖的继承方式&#xff0c;帮助我们快速整合第三方常用框架。现在是 Java 领域的绝对霸主。 今天介绍三种快速创建 SpringBoot 项目的方式。 在线创建 1、打…

Uniapp-安装HBuilder调试基座失败解决方案

无法安装原因 有时候我们测试的时候&#xff0c;在手机上插上了线可能因为各种原因没有点击安装或者安装后删除就无法再次安装了&#xff0c;会提示同步资源失败,未得到同步资源的授权,请停止运行后重新运行&#xff0c;而且无论怎么操作都解决不聊这个问题&#xff0c;这是由…

搭建自己的JRebel服务

引入 JRebel插件热部署快速入门教程 上一篇文章有提到如何使用JRebel&#xff0c;其中在激活JRebel那一步骤时咱们使用的激活地址实际就是放在我的个人服务器上&#xff0c;本篇文章咱们手把手的搭建一个个人的JRebel服务。 下载激活工具 下载地址 如下图所示&#xff0c;…

专注于绘画,不受限制!尝试Growly Draw for Mac的快速绘画应用

Growly Draw Mac版是Mac平台上的一款绘画应用&#xff0c;它提供了简单易用的画板页面和多种色彩、画笔工具&#xff0c;让你可以轻松地完成作画。无论你是初学者还是专业人士&#xff0c;都可以在这款应用中找到适合自己的绘画方式。通过使用Growly Draw Mac版&#xff0c;你可…

echarts 实现双y轴折线图示例

该示例有如下几个特点&#xff1a; ①实现tooltip自定义样式&#xff08;echarts 实现tooltip提示框样式自定义-CSDN博客&#xff09; ②legend左右区分展示 ③双y轴折线展示 代码如下&#xff1a; this.options {grid: {left: "3%",right: "3%",top: &…

3GPP TS38.201 NR; Physical layer; General description (Release 18)

TS38.201是介绍性的标准&#xff0c;简单介绍了RAN的信道组成和PHY层承担的功能&#xff0c;下图是PHY层相关标准的关系。 文章目录 结构信道类型调制方式PHY层支持的过程物理层测量其他标准TS 38.202: Physical layer services provided by the physical layerTS 38.211: Ph…

docker笔记14--docker-nerdctl-crictl-ctr使用对比

docker笔记14--docker-nerdctl-crictl-ctr使用对比 介绍工具对比dockernerdctlcrictlctr 注意事项说明 介绍 随着容器云技术的成熟&#xff0c;越来越多的从业者开始接触、熟悉 docker和containerd 了&#xff0c;很多时候需要同时在 docker 和 containerd之间切换&#xff0c…

L1 频段卫星导航射频前端低噪声放大器芯片MS2659

产品简述 MS2659 是一款具有高增益、低噪声系数的低噪声放大器 (LNA) &#xff0c;支持 L1 频段多模式全球卫星定位&#xff0c;可以应用于 GPS 、 北斗二代、伽利略、 GLONASS 等 GNSS 导航接收机中。芯片采 用 SOT23-6 的封装形式。 主要特点 ◼ 支持北斗、 …

java调用c函数

一、关于JNI JNI是Java Native Interface的缩写&#xff0c;JNI是JAVA平台专门用于和本地C代码进行相互操作的API&#xff0c;称为JAVA本地接口。 二、JNI开发流程 1.在JAVA中先声明一个native方法。2.通过javac -h或javah -jni命令导出JNI使用的C头头文件。3.使用C实现本地方…