zoukankan      html  css  js  c++  java
  • Zookeeper简介及使用

    一、Zookeeper简介

    1、zookeeper简介
        动物管理员
        Apache ZooKeeper致力于开发和维护开源服务器,实现高度可靠的分布式协调。
    2、什么是ZooKeeper?
        ZooKeeper是一种集中式服务,用于维护配置信息,命名,提供分布式同步和提供组服务。所有这
        些类型的服务都以分布式应用程序的某种形式使用。每次实施它们都需要做很多工作来修复不可避
        免的错误和竞争条件。由于难以实现这些类型的服务,应用程序最初通常会吝啬它们,这使得它们
        在变化的情况下变得脆弱并且难以管理。即使正确完成,这些服务的不同实现也会在部署应用程序
        时导致管理复杂性。
    3、zookeeper功能
        (1)存储数据
        (2)监听
    4、zookeeper工作机制
        基于观察者模式设计的分布式服务管理框架
    5、zookeeper的存储结构
        目录树结构
    6、zookeeper应用场景
        (1)集群统一配置管理
        (2)集群统一命名服务
        (3)集群统一管理
        (4)服务器的动态上下线感知
        (5)负载均衡
    7、安装zookeeper单机版
        (1)下载安装包 zookeeper-3.4.10.tar.gz
        (2)上传安装包到Linux
        alt+p(SecureCRT中)
        (3)解压
        tar -zxvf zookeeper-3.4.10.tar.gz
        (4)修改配置文件
        进入zookeeper安装目录下的conf文件夹下
        mv zoo_sample.cfg zoo.cfg
        vi zoo.cfg
        dataDir=/root/hd/zookeeper-3.4.10/zkData
        (5)启动zk
        bin/zkServer.sh start
        (6)查看状态
        bin/zkServer.sh status
        (7)启动客户端
        bin/zkCli.sh
    8、完全分布式安装
        (1)下载安装包 zookeeper-3.4.10.tar.gz
        (2)上传安装包到Linux
        alt+p(SecureCRT中)
        (3)解压
        tar -zxvf zookeeper-3.4.10.tar.gz
        (4)修改配置文件
        进入zookeeper安装目录下的conf文件夹下
        mv zoo_sample.cfg zoo.cfg
        vi zoo.cfg
        dataDir=/root/hd/zookeeper-3.4.10/zkData
        ###############cluster###############
        server.1=hd09-1:2888:3888
        server.2=hd09-2:2888:3888
        server.3=hd09-3:2888:3888
        其中server.后面的数字1、2、3分别是机器hd09-1、hd09-2、hd09-3中zookeeper-3.4.10/zkData/myid文件中的值
        (5)添加文件myid
        $cd zookeeper-3.4.10/zkData
        $touch myid
        (6)添加内容在myid为1
        $ vi myid
        1
        (7)发送zookeeper文件到其它机器
        $ scp -r zookeeper-3.4.10 hd09-2:$PWD
        $ scp -r zookeeper-3.4.10 hd09-3:$PWD
        (8)修改myid依次为2 3
        (9)修改环境变量
        vi /etc/profile
        export ZOOKEEPER_HOME=/root/hd/zookeeper3.4.10
        export PATH=$PATH:$ZOOKEEPER_HOME/bin
        (10)生效环境变量
        source /etc/profile
        (11)启动zookeeper
        zkServer.sh start
        (12)查看状态
        zkServer.sh status
        (13)关闭zookeeper
        zkServer.sh stop
    
    9、客户端的命令行操作
    (1)启动客户端
        zkCli.sh
    (2)查看帮助
        help
    (3)查看当前znode所包含的内容
        ls /
    (4)创建节点
        create /hello 18
    (5)创建短暂znode
        create -e /haha tom
    (6)创建带序号znode
        create -s /bigdata tom
    (7)创建短暂带序号
        create -e -s /bigdata tom
    (8)查看此节点的详细信息
        ls2 /
    (9)获得节点值监听
        get /hello watch
    (10)监听路径
        ls / watch
    (11)修改znode数据
        set /hello iiiii
    (12)删除节点
        delete /hello
    (13)递归删除
        rmr /delireba
    (14)查看节点状态信息
        stat /

    二、Zookeeper工作机制

    1、Zookeeper工作机制

    2、Zookeeper目录结构

    3、Zookeeper选举机制

     

    三、Zookeeper简单客户端API

    package com.css.zk;
    
    import java.io.IOException;
    import java.util.List;
    
    import org.apache.zookeeper.CreateMode;
    import org.apache.zookeeper.KeeperException;
    import org.apache.zookeeper.WatchedEvent;
    import org.apache.zookeeper.Watcher;
    import org.apache.zookeeper.ZooDefs.Ids;
    import org.apache.zookeeper.ZooKeeper;
    import org.apache.zookeeper.data.Stat;
    import org.junit.Before;
    import org.junit.Test;
    
    public class ZkClient {
    
        private String connectString = "192.168.146.132:2181,192.168.146.133:2181,192.168.146.134:2181";
        private int sessionTimeout = 3000;
        ZooKeeper zkCli = null;
    
        // 初始化客户端
        @Before
        public void init() throws IOException {
            zkCli = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
                // 回调监听
                @Override
                public void process(WatchedEvent event) {
                    // System.out.println(event.getPath() + "	" + event.getState() + "	" + event.getType());
                    try {
                        List<String> children = zkCli.getChildren("/", true);
                        for (String c : children) {
                            // System.out.println(c);
                        }
                    } catch (KeeperException e) {
                        e.printStackTrace();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    
        // 创建子节点
        @Test
        public void createZnode() throws KeeperException, InterruptedException {
            String path = zkCli.create("/hello", "world".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            System.out.println(path);
        }
    
        // 获取子节点
        @Test
        public void getChild() throws KeeperException, InterruptedException {
            List<String> children = zkCli.getChildren("/", true);
            for (String c : children) {
                System.out.println(c);
            }
            Thread.sleep(Long.MAX_VALUE);
        }
    
        // 删除节点
        @Test
        public void rmChildData() throws KeeperException, InterruptedException {
            // byte[] data = zkCli.getData("/bbq", true, null);
            // System.out.println(new String(data));
            zkCli.delete("/hello", -1);
        }
    
        // 修改数据
        @Test
        public void setData() throws KeeperException, InterruptedException {
            zkCli.setData("/hello", "17".getBytes(), -1);
        }
    
        // 判断节点是否存在
        @Test
        public void testExist() throws KeeperException, InterruptedException {
            Stat exists = zkCli.exists("/hello", false);
            System.out.println(exists == null ? "not exists" : "exists");
        }
    }

    四、Zoopeeper监听API

    1、监听单节点内容

    package com.css.zk;
    
    import java.io.IOException;
    
    import org.apache.zookeeper.KeeperException;
    import org.apache.zookeeper.WatchedEvent;
    import org.apache.zookeeper.Watcher;
    import org.apache.zookeeper.ZooKeeper;
    
    // 监听单节点内容
    public class WatchDemo {
        public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
            ZooKeeper zkCli = new ZooKeeper("192.168.146.132:2181,192.168.146.133:2181,192.168.146.134:2181", 3000,
                    new Watcher() {
                        // 监听回调
                        @Override
                        public void process(WatchedEvent event) {
    
                        }
                    });
    
            byte[] data = zkCli.getData("/hello", new Watcher() {
                // 监听的具体内容
                @Override
                public void process(WatchedEvent event) {
                    System.out.println("监听路径为:" + event.getPath());
                    System.out.println("监听的类型为:" + event.getType());
                    System.out.println("监听被修改了!!!");
                }
            }, null);
    
            System.out.println(new String(data));
            Thread.sleep(Long.MAX_VALUE);
        }
    }

    2、监听目录

    package com.css.zk;
    
    import java.io.IOException;
    import java.util.List;
    
    import org.apache.zookeeper.KeeperException;
    import org.apache.zookeeper.WatchedEvent;
    import org.apache.zookeeper.Watcher;
    import org.apache.zookeeper.ZooKeeper;
    
    // 监听目录
    public class WatchDemo1 {
    
        static List<String> children = null;
    
        public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
            ZooKeeper zkCli = new ZooKeeper("192.168.146.132:2181,192.168.146.133:2181,192.168.146.134:2181", 3000,
                    new Watcher() {
                        // 监听回调
                        @Override
                        public void process(WatchedEvent event) {
                            System.out.println("正在监听中......");
                        }
                    });
    
            // 监听目录
            children = zkCli.getChildren("/", new Watcher() {
                @Override
                public void process(WatchedEvent event) {
                    System.out.println("监听路径为:" + event.getPath());
                    System.out.println("监听的类型为:" + event.getType());
                    System.out.println("监听被修改了!!!");
                    for (String c : children) {
                        System.out.println(c);
                    }
                }
            });
            Thread.sleep(Long.MAX_VALUE);
        }
    }

    五、Zookeeper动态上下线感知系统

    需求

    某分布式系统当中,主节点有多台,可以进行动态上下线,当有任何一台机器发生了动态的上下线 任何一台客户端都能感知到。

    思路

    (1)创建客户端与服务端
    (2)启动client端 监听
    (3)启动server端 注册
    (4)当server端 发生上下线
    (5)client端都能感知到

    1、服务端

    package com.css.serverclient;
    
    import java.io.IOException;
    
    import org.apache.zookeeper.CreateMode;
    import org.apache.zookeeper.KeeperException;
    import org.apache.zookeeper.WatchedEvent;
    import org.apache.zookeeper.Watcher;
    import org.apache.zookeeper.ZooDefs.Ids;
    import org.apache.zookeeper.ZooKeeper;
    
    public class ZkServer {
        public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
            // 1.连接zkServer
            ZkServer zkServer = new ZkServer();
            zkServer.getConnect();
    
            // 2.注册节点信息 服务器ip添加到zk中
            zkServer.regist(args[0]);
    
            // 3.业务逻辑处理
            zkServer.build(args[0]);
        }
    
        private String connectString = "192.168.146.132:2181,192.168.146.133:2181,192.168.146.134:2181";
        private int sessionTimeout = 3000;
        ZooKeeper zkCli = null;
        // 定义父节点
        private String parentNode = "/servers";
    
        // 1.连接zkServer
        public void getConnect() throws IOException {
            zkCli = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
    
                @Override
                public void process(WatchedEvent event) {
    
                }
            });
        }
    
        // 2.注册信息
        public void regist(String hostname) throws KeeperException, InterruptedException {
            String node = zkCli.create(parentNode + "/server", hostname.getBytes(), Ids.OPEN_ACL_UNSAFE,
                    CreateMode.EPHEMERAL_SEQUENTIAL);
            System.out.println(node);
        }
    
        // 3.构造服务器
        public void build(String hostname) throws InterruptedException {
            System.out.println(hostname + ":服务器上线了!");
            Thread.sleep(Long.MAX_VALUE);
        }
    }

    2、客户端

    package com.css.serverclient;
    
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    import org.apache.zookeeper.KeeperException;
    import org.apache.zookeeper.WatchedEvent;
    import org.apache.zookeeper.Watcher;
    import org.apache.zookeeper.ZooKeeper;
    
    // 客户端
    public class ZkClient {
        public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
            // 1.获取连接
            ZkClient zkClient = new ZkClient();
            zkClient.getConnect();
    
            // 2.监听服务的节点信息
            zkClient.getServers();
    
            // 3.业务逻辑(一直监听)
            zkClient.getWatch();
        }
    
        // 3.业务逻辑
        public void getWatch() throws InterruptedException {
            Thread.sleep(Long.MAX_VALUE);
        }
    
        // 2.监听服务的节点信息
        public void getServers() throws KeeperException, InterruptedException {
            List<String> children = zkCli.getChildren("/servers", true);
            ArrayList<String> serverList = new ArrayList<String>();
    
            // 获取每个节点的数据
            for (String c : children) {
                byte[] data = zkCli.getData("/servers/" + c, true, null);
                serverList.add(new String(data));
            }
    
            // 打印服务器列表
            System.out.println(serverList);
        }
    
        private String connectString = "192.168.146.132:2181,192.168.146.133:2181,192.168.146.134:2181";
        private int sessionTimeout = 3000;
        ZooKeeper zkCli = null;
    
        // 1.连接集群
        public void getConnect() throws IOException {
            zkCli = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
    
                @Override
                public void process(WatchedEvent event) {
                    List<String> children = null;
                    try {
                        // 监听父节点
                        children = zkCli.getChildren("/servers", true);
    
                        // 创建集合存储服务器列表
                        ArrayList<String> serverList = new ArrayList<String>();
    
                        // 获取每个节点的数据
                        for (String c : children) {
                            byte[] data = zkCli.getData("/servers/" + c, true, null);
                            serverList.add(new String(data));
                        }
    
                        // 打印服务器列表
                        System.out.println(serverList);
                    } catch (KeeperException e) {
                        e.printStackTrace();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }

    3、只启动客户端时,控制台输出为:

    此时在集群的某一台机器执行以下命令:

    此时客户端控制台输出:

    4、同时启动客户端和服务端

     服务端执行

    此时服务端输出:

    客户端输出:

    这样就实现了简单的动态上下线感知。

     

  • 相关阅读:
    Entity Framework
    SQLiteHelp
    NLog日志记录
    C# 特性(Attribute)
    C# 正则表达式
    C#中显现串口通信SerialPort类
    C#.NET编码规范
    AspNetCore 限流中间件IpRateLimitMiddleware 介绍
    .Net Core中的Api版本控制
    C# Task的使用
  • 原文地址:https://www.cnblogs.com/areyouready/p/10014947.html
Copyright © 2011-2022 走看看