Zookeeper

Zookeeper

学习目标

  • 定义:是一个分布式的、开源的协调服务(中间件)

  • 作用:

    • 配置管理
      • 用来管理服务的信息(ip、端口、服务提供功能接口),例如连接数据库的配置信息。
    • 分布式锁
      • 用户控制服务的资源,锁住之后,只能有一个服务科操作,其它服务等待
    • 集群管理
      • 用于管理服务的节点(每个节点提供的服务相同,则组成一个集群),组成(高可用)
  • 场景:

  • 原理/架构:

    • 架构

在这里插入图片描述

  • Znode是根节点衍生出的

    • 持久化
  • 临时节点 客户断开之后,则节点自动删除

    • 持久化顺序节点,子节点会按照数字自增的方式创建
    • 临时顺序节点
  • 使用:

    • 命令行(liunx)

      • 登录 zhCli.-service ip:端口(2181)
      • 查看节点有哪些子节点: ls /节点名
      • 查看节点详细信息:ls -s /节点
      • 创建节点 :create /目录 节点名 数据 (create /app1 itheima)
      • 获取数据 : get /节点名
      • 设置数据: set /节点名数据
      • 删除节点: delete /节点名
      • 删除节点包含子节点: deleteall /节点名
    • 临时节点

      • create -e ,临时节点
    • 顺序节点

      • create -s /顺序节点
    • 临时顺序节点

      • create -es /临时顺序节点
    • API方式

连接客户端

  • 连接客户端

    • 方式1

    步骤1.导入坐标

    <!--curator-->
            <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>
    

    步骤2.获得链接对象

    // 1.使用CuratorFrameworkFactory对象获取链接对象
    //重试策略 3000 代表3秒尝试重试一次,一共重试10次
            RetryPolicy rp = new ExponentialBackoffRetry(3000,10);
    //2.获取链接 
    	CuratorFramework client = CuratorFrameworkFactory.newClient("1270.0.1:2181", 3000, 3000, rp);
    	
    
  1. 开启链接

     client.start();
    
    • 方式2 参数同上
    //client.start();
            build = CuratorFrameworkFactory.builder().connectString("127.0.0.1:2181").connectionTimeoutMs(15 * 1000).sessionTimeoutMs(60 * 1000).retryPolicy(rp).namespace("WSL").build();
    //开启链接
          build.start();
    

API创建节点

  • 创建持久化节点 语法:连接对象.create().forPath("/节点名");
build.create().forPath("/test");
  • 创建临时节点: 连接对象.create().withMode(“创建类型”).forPath("/节点名")
build.create().withMode(CreateMode.EPHEMERAL).forPath("/节点名字")
  • 创建持久化顺序节点: 连接对象.create().withMode(“创建类型”).forPath("/节点名")
build.create().withMode(CreateMode.PERSISTENT_SEQUENTIAL).forPath("/节点名")
  • 创建临时节点:连接对象.create().withMode(“创建类型”).forPath("/节点名")
build.create().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath("/节点名")

查询节点信息

  1. 查询数据 get : 连接对象.getData().forPath()
//先创建一个持久性节点,并设置值
        build.create().forPath("/test","hhh".getBytes());
        //从节点中获取值的格式是:连接对象.getData().forPath("/节点路径")
        byte[] bytes = build.getData().forPath("/test");
        String s = new String(bytes);
        System.out.println(s);
  1. 查询某个节点下所有的子节点:ls :getChildren().forPath("/路径")
 List<String> strings = build.getChildren().forPath("/");
        System.out.println(strings);//执行结果[test2, test]
  1. 查询节点的完整状态信息:getData.storingStatIn(Stat对象).forPath("/查询节点路径")
 //保存查询节点状态信息
        Stat stat = new Stat();
        byte[] bytes = build.getData().storingStatIn(stat).forPath("/test2");
        System.out.println(stat);//查询的结果内容110,110,1595861595448,1595861595448,0,0,0,0,0,0,10

修改节点

  1. 普通修改 连接对象.setData().forPath("/节点路径",“修改的内容”.getBytes());
//修改节点信息
        build.setData().forPath("/test","itheima".getBytes());
        //从新查询修改的信息
        byte[] bytes = build.getData().forPath("/test");
        System.out.println(new String(bytes));
2. 执行版本进行修改
 Stat stat = new Stat();
        build.getData().storingStatIn(stat).forPath("/test");
        //修改只想版本对应的内容
        build.setData().withVersion(stat.getVersion()).forPath("/test","修改数据".getBytes());
        //取出修改后的内容
        byte[] bytes = build.getData().forPath("/test");
        System.out.println(new String(bytes));//输出结果:修改数据

删除节点

  1. 删除单个节点

    build.delete().forPath("/test2");
    
    //先查询有WSL节点下有哪些子节点
            List<String> strings = build.getChildren().forPath("/");
            System.out.println("删除前子节点"+strings);
            //删除test2的节点
            build.delete().forPath("/test2");
            //再次查询
            List<String> strings1 = build.getChildren().forPath("/");
            System.out.println("删除后的子节点"+strings1);
            /*
            删除前子节点[test2, test]
            删除后的子节点[test]
             */
    
  2. 删除带有子节点的节点

    //删除这个test和app1
            build.delete().deletingChildrenIfNeeded().forPath("/test");
    
  3. 必须成功的删除(在网络有波动的情况下,一次删除可以能不成功,需要尝试几次)

    //使用必须删除成功的方法,在网络有波动的情况下, 可以会删除失败,使用这个方法的本质就是重试几次
            build.delete().guaranteed().forPath("/test");
    
   
4. 回调 (不仅仅只有删除才有,增、改、查,都有)

   ```java
    //先创建一个持久性的节点
           build.create().inBackground(new BackgroundCallback() {
               /**
                *
                * @param curatorFramework 这是链接对象
                * @param curatorEvent 封装了节点的状态详细信息
                * @throws Exception
                */
               @Override
               public void processResult(CuratorFramework curatorFramework, CuratorEvent curatorEvent) throws Exception {
                   System.out.println("创建了");
                   System.out.println(curatorEvent);
               }
           }).forPath("/test");

执行后的结果

在这里插入图片描述

ZK监听机制

  • ​ 统一步骤

    • 创建监听对象

      NodeCache node=new NodeCache(连接对象,"/被监听的节点路径")
    • 注册监听

      node.getListenable.addListener(new NodeCacheListener(){
          @Override
          public void nodeChanged() throws Exception {
              //这就是监听后需要处理的流程
          }
      })
      
    • 开启监听

      node.start();
      
  • NodeCache:只监听特定子节点的删、该、创建事件

     //1.创建监听
            NodeCache nodeCache = new NodeCache(build, "/test");
            //2.注册监听器 getListenable->获取监听器,addListener添加监听,添加监听对象,用于监听
            nodeCache.getListenable().addListener(new NodeCacheListener() {
                @Override
                public void nodeChanged() throws Exception {
                    System.out.println("test节点发生了改变");
                }
            });
            //3.开启监听
            nodeCache.start();
    
  • PathChildrenCache:监听一个节点的子节点

    //创建PathChildrenCache对象 构造方法中的true表示的是开启子节点的缓存数据,可以拿到子节点内容
            PathChildrenCache pathChildrenCache = new PathChildrenCache(build, "/",true);
            //注册监听
            pathChildrenCache.getListenable().addListener(new PathChildrenCacheListener() {
                /**
                 *
                 * @param curatorFramework 这是连接对象
                 * @param pathChildrenCacheEvent 缓冲区里面的内容
                 * @throws Exception
                 */
                @Override
                public void childEvent(CuratorFramework curatorFramework, PathChildrenCacheEvent pathChildrenCacheEvent) throws Exception {
                    System.out.println("子节点发生了变化");
                    System.out.println(pathChildrenCacheEvent);
                    //可以判断是增删改的那种事件
                    PathChildrenCacheEvent.Type type = pathChildrenCacheEvent.getType();
                    //如果是更改操作就提示更新
                    if(type.equals(PathChildrenCacheEvent.Type.CHILD_UPDATED)){
                        System.out.println("内容被更新了");
                        byte[] data = pathChildrenCacheEvent.getData().getData();
                        System.out.println("更新后的内容:"+new String(data));
                    }
                    //监听了添加事件
                    else if(type.equals(PathChildrenCacheEvent.Type.CHILD_ADDED)){
                        System.out.println("添加了节点");
                        ChildData data = pathChildrenCacheEvent.getData();
                        System.out.println("节点路径:"+data.getPath());
                    }
                    //监听删除事件
                    else if(type.equals(PathChildrenCacheEvent.Type.CHILD_REMOVED)){
                        System.out.println("子节点删除");
                        ChildData data = pathChildrenCacheEvent.getData();
                        System.out.println("被删除的节点路径:"+data.getPath());
                    }
    
                }
            });
            //开启监听
            pathChildrenCache.start();
    
  • ThreeCache:监听一个节点并包含所有的子节点和

     //创建监听对象
            TreeCache treeCache = new TreeCache(build, "/");
            //注册监听对象
            treeCache.getListenable().addListener(new TreeCacheListener() {
                @Override
                public void childEvent(CuratorFramework curatorFramework, TreeCacheEvent treeCacheEvent) throws Exception {
                    System.out.println("节点变化了");
                    System.out.println(treeCacheEvent);
                }
            });
            //3.开启节点监听
            treeCache.start();
    

分布式锁[了解]

  • 定义:协调跨机器的进程之间的数据同步问题

    原理

在这里插入图片描述

集群角色和职责

k, TreeCacheEvent treeCacheEvent) throws Exception {
System.out.println(“节点变化了”);
System.out.println(treeCacheEvent);
}
});
//3.开启节点监听
treeCache.start();


![在这里插入图片描述](https://img-blog.csdnimg.cn/20200810182620413.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1dzbF9Dbg==,size_16,color_FFFFFF,t_70)


​	

## 分布式锁[了解]

- 定义:协调跨机器的进程之间的数据同步问题

原理



![在这里插入图片描述](https://img-blog.csdnimg.cn/20200810182437873.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1dzbF9Dbg==,size_16,color_FFFFFF,t_70)




### 集群角色和职责

![在这里插入图片描述](https://img-blog.csdnimg.cn/20200810182604180.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1dzbF9Dbg==,size_16,color_FFFFFF,t_70)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值