zoukankan      html  css  js  c++  java
  • zookeeper03

    1 zookeeper开源客户端curator介绍

    1.1 curator简介

    • curator是Netflix公司开源的一个zookeeper客户端,后来捐赠给Apache。curator框架在zookeeper原生API接口上进行了包装,解决了很多zookeeper客户端非常底层的细节开发。提供zookeeper各种应用场景(比如:分布式锁服务、集群领导选举、共享计数器、缓存机制、分布式队列等)的抽象封装,实现了Fluent风格的API接口,是最好用,最流行的zookeeper的客户端。

    • 原生zookeeperAPI的不足:

      • 1️⃣连接对象异步创建,需要开发人员自行编码等待。
      • 2️⃣连接没有自动重连超时机制。
      • 3️⃣watcher一次注册生效一次。
      • 4️⃣不支持递归创建树形节点。
    • curator的特点:

      • 1️⃣解决了session会话超时重连。
      • 2️⃣watcher反复注册。
      • 3️⃣简化开发API。
      • 4️⃣遵循Fluent风格的API。
      • 5️⃣提供了分布式锁服务,共享计数器、缓存机制等解决方案。
    • maven依赖:

    <!-- 需要和zookeeper的安装版本保持一致 -->
    <!-- 对zookeeper的底层api的一些封装 -->
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-framework</artifactId>
        <version>2.12.0</version>
    </dependency>
    <!-- 封装了一些高级特性,如:Cache事件监听、选举、分布式锁、分布式计数器、分布式Barrier等 -->
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-recipes</artifactId>
        <version>2.12.0</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13</version>
    </dependency>
    

    1.2 连接到zookeeper

    • 示例:
    package com.sunxiaping.curator;
    
    import org.apache.curator.framework.CuratorFramework;
    import org.apache.curator.framework.CuratorFrameworkFactory;
    import org.apache.curator.retry.RetryOneTime;
    
    public class ZookeeperConnection {
        public static void main(String[] args) {
            CuratorFramework client = CuratorFrameworkFactory.builder()
                    //连接参数
                    .connectString("192.168.40.101:2181")
                    //会话超时时间
                    .sessionTimeoutMs(5000)
    //                .namespace("hadoop")
                    //重试机制
                    .retryPolicy(new RetryOneTime(3000))
                    .build();
            //开始连接
            client.start();
            System.out.println("client.isStarted() = " + client.isStarted());
            //关闭连接
            client.close();
            System.out.println("client.isStarted() = " + client.isStarted());
    
        }
    }
    

    1.3 curator连接对象的重连策略

    • 示例:
    package com.sunxiaping.curator;
    
    import org.apache.curator.RetryPolicy;
    import org.apache.curator.framework.CuratorFramework;
    import org.apache.curator.framework.CuratorFrameworkFactory;
    import org.apache.curator.retry.ExponentialBackoffRetry;
    import org.apache.curator.retry.RetryNTimes;
    import org.apache.curator.retry.RetryOneTime;
    import org.apache.curator.retry.RetryUntilElapsed;
    
    /**
     * 连接到zookeeper
     */
    public class CuratorConnection {
        public static void main(String[] args) {
            //IP地址端口号
            String connectString = "192.168.179.101:2181,192.168.179.102:2181,192.168.179.103:2181";
            //会话超时时间
            int sessionTimeoutMs = 5000;
            //重试策略
            //① 3秒后重连,只重连一次
            RetryPolicy retryPolicy = new RetryOneTime(3000);
            //② 每3秒重连一次,重连3次
            retryPolicy = new RetryNTimes(3, 3000);
            //③ 每3秒重连一次,总等待时间超过10秒后停止重连
            retryPolicy = new RetryUntilElapsed(10000, 3000);
            //④ baseSleepTimeMs* Math.max(1,random.nextInt(1 << (retryCount +1)))
            retryPolicy = new ExponentialBackoffRetry(1000, 3);
    
            CuratorFramework client = CuratorFrameworkFactory.builder()
                    .connectString(connectString)
                    .sessionTimeoutMs(sessionTimeoutMs)
                    .retryPolicy(retryPolicy)
                    //命名空间 以命名空间指定的字符串作为“/命名空间”节点查询
    //                .namespace("create")
                    .build();
            //打开连接
            client.start();
            System.out.println("连接是否打开 = " + client.isStarted());
            //关闭连接
            client.close();
        }
    }
    

    1.4 新增节点

    • 示例:
    package com.sunxiaping.curator;
    
    import org.apache.curator.framework.CuratorFramework;
    import org.apache.curator.framework.CuratorFrameworkFactory;
    import org.apache.curator.framework.api.BackgroundCallback;
    import org.apache.curator.framework.api.CuratorEvent;
    import org.apache.curator.retry.ExponentialBackoffRetry;
    import org.apache.zookeeper.CreateMode;
    import org.apache.zookeeper.ZooDefs;
    import org.junit.Before;
    import org.junit.Test;
    
    /**
     * curator创建节点
     */
    public class CreateNode {
    
        private CuratorFramework client;
    
        @Before
        public void before() {
            client = CuratorFrameworkFactory.builder()
                    .connectString("192.168.40.101:2181")
                    .sessionTimeoutMs(5000)
                    .retryPolicy(new ExponentialBackoffRetry(1000, 3))
                    //命名空间
                    .namespace("hadoop")
                    .build();
            client.start();
        }
    
        @Test
        public void after() {
            if (client != null) {
                client.close();
            }
        }
    
        @Test
        public void testCreateNode1() throws Exception {
            String path = client.create()
                    //持久节点
                    .withMode(CreateMode.PERSISTENT)
                    //ACL
                    .withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE)
                    //节点路径和节点数据
                    .forPath("/node1", "node1".getBytes());
            System.out.println("path = " + path);
        }
    
        /**
         * 递归创建节点
         *
         * @throws Exception
         */
        @Test
        public void testCreateNode2() throws Exception {
            String path = client.create()
                    //递归创建
                    .creatingParentContainersIfNeeded()
                    //持久节点
                    .withMode(CreateMode.PERSISTENT)
                    //ACL
                    .withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE)
                    //节点路径和节点数据
                    .forPath("/node2/node21", "node21".getBytes());
            System.out.println("path = " + path);
        }
    
        /**
         * 异步方式创建节点
         *
         * @throws Exception
         */
        @Test
        public void testCreateNode3() throws Exception {
            client.create()
                    //递归创建
                    .creatingParentContainersIfNeeded()
                    //持久节点
                    .withMode(CreateMode.PERSISTENT)
                    //ACL
                    .withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE)
                    //异步回调接口
                    .inBackground(new BackgroundCallback() {
                        @Override
                        public void processResult(CuratorFramework curatorFramework, CuratorEvent event) throws Exception {
                            System.out.println("节点路径 = " + event.getPath());
                            System.out.println("事件类型 = " + event.getType());
                        }
                    })
                    //节点路径和节点数据
                    .forPath("/node3/node31", "node31".getBytes());
    
            Thread.sleep(5000);
            System.out.println("结束");
        }
    
    }
    

    1.5 更新节点

    • 示例:
    package com.sunxiaping.curator;
    
    import org.apache.curator.framework.CuratorFramework;
    import org.apache.curator.framework.CuratorFrameworkFactory;
    import org.apache.curator.framework.api.BackgroundCallback;
    import org.apache.curator.framework.api.CuratorEvent;
    import org.apache.curator.retry.ExponentialBackoffRetry;
    import org.apache.zookeeper.data.Stat;
    import org.junit.Before;
    import org.junit.Test;
    
    /**
     * 更新节点
     */
    public class UpdateNode {
        private CuratorFramework client;
    
        @Before
        public void before() {
            client = CuratorFrameworkFactory.builder()
                    .connectString("192.168.40.101:2181")
                    .sessionTimeoutMs(5000)
                    .retryPolicy(new ExponentialBackoffRetry(1000, 3))
                    //命名空间
                    .namespace("hadoop")
                    .build();
            client.start();
        }
    
        @Test
        public void after() {
            if (client != null) {
                client.close();
            }
        }
    
        @Test
        public void testUpdateNode() throws Exception {
            Stat stat = client.setData().withVersion(-1).forPath("/node1", "node1 update".getBytes());
            System.out.println("stat = " + stat);
        }
    
        @Test
        public void testUpdateNode2() throws Exception {
            client.setData().withVersion(-1)
                     .inBackground(new BackgroundCallback() {
                         @Override
                         public void processResult(CuratorFramework client, CuratorEvent event) throws Exception {
                             System.out.println("节点路径 = " + event.getPath());
                             System.out.println("事件类型 = " + event.getType());
                         }
                     })
                    .forPath("/node1", "node11 update".getBytes());
    
            Thread.sleep(5000);
            System.out.println("结束");
        }
    }
    

    1.6 删除节点

    • 示例:
    package com.sunxiaping.curator;
    
    import org.apache.curator.framework.CuratorFramework;
    import org.apache.curator.framework.CuratorFrameworkFactory;
    import org.apache.curator.framework.api.BackgroundCallback;
    import org.apache.curator.framework.api.CuratorEvent;
    import org.apache.curator.retry.ExponentialBackoffRetry;
    import org.junit.Before;
    import org.junit.Test;
    
    /**
     * 删除节点
     */
    public class DeleteNode {
        private CuratorFramework client;
    
        @Before
        public void before() {
            client = CuratorFrameworkFactory.builder()
                    .connectString("192.168.40.101:2181")
                    .sessionTimeoutMs(5000)
                    .retryPolicy(new ExponentialBackoffRetry(1000, 3))
                    //命名空间
                    .namespace("hadoop")
                    .build();
            client.start();
        }
    
        @Test
        public void after() {
            if (client != null) {
                client.close();
            }
        }
    
        /**
         * 删除节点
         *
         * @throws Exception
         */
        @Test
        public void testDeleteNode() throws Exception {
            client.delete().withVersion(-1).forPath("/node1");
        }
    
        /**
         * 递归删除
         *
         * @throws Exception
         */
        @Test
        public void testDeleteNode2() throws Exception {
            client.delete()
                    //递归删除
                    .deletingChildrenIfNeeded()
                    .withVersion(-1)
                    .forPath("/node2");
        }
    
    
        /**
         * 异步删除
         *
         * @throws Exception
         */
        @Test
        public void testDeleteNode3() throws Exception {
            client.delete()
                    //递归删除
                    .deletingChildrenIfNeeded()
                    .withVersion(-1)
                    .inBackground(new BackgroundCallback() {
                        @Override
                        public void processResult(CuratorFramework client, CuratorEvent event) throws Exception {
                            System.out.println("节点路径 = " + event.getPath());
                            System.out.println("事件类型 = " + event.getType());
                        }
                    })
                    .forPath("/node3");
            Thread.sleep(5000);
            System.out.println("结束");
        }
    
    }
    

    1.7 查看节点数据

    • 示例:
    package com.sunxiaping.curator;
    
    import org.apache.curator.framework.CuratorFramework;
    import org.apache.curator.framework.CuratorFrameworkFactory;
    import org.apache.curator.framework.api.BackgroundCallback;
    import org.apache.curator.framework.api.CuratorEvent;
    import org.apache.curator.retry.ExponentialBackoffRetry;
    import org.apache.zookeeper.data.Stat;
    import org.junit.Before;
    import org.junit.Test;
    
    /**
     * 查看节点数据
     */
    public class GetNodeData {
        private CuratorFramework client;
    
        @Before
        public void before() {
            client = CuratorFrameworkFactory.builder()
                    .connectString("192.168.40.101:2181")
                    .sessionTimeoutMs(5000)
                    .retryPolicy(new ExponentialBackoffRetry(1000, 3))
                    //命名空间
                    .namespace("hadoop")
                    .build();
            client.start();
        }
    
        @Test
        public void after() {
            if (client != null) {
                client.close();
            }
        }
    
        /**
         * 读取节点数据
         *
         * @throws Exception
         */
        @Test
        public void testGetNodeData1() throws Exception {
            byte[] bytes = client.getData().forPath("/node1");
            System.out.println("data = " + new String(bytes));
        }
    
    
        /**
         * 读取节点数据时获取节点的属性
         *
         * @throws Exception
         */
        @Test
        public void testGetNodeData2() throws Exception {
            Stat stat = new Stat();
            byte[] bytes = client.getData().storingStatIn(stat).forPath("/node1");
            System.out.println("data = " + new String(bytes));
            System.out.println("stat = " + stat);
        }
    
        /**
         * 异步方式读取节点数据
         *
         * @throws Exception
         */
        @Test
        public void testGetNodeData3() throws Exception {
            client.getData().inBackground(new BackgroundCallback() {
                @Override
                public void processResult(CuratorFramework client, CuratorEvent event) throws Exception {
                    System.out.println("节点路径 = " + event.getPath());
                    System.out.println("事件类型 = " + event.getType());
    
                    System.out.println("结果 = " + new String(event.getData()));
                }
            }).forPath("/node1");
    
            Thread.sleep(5000);
            System.out.println("结束");
        }
    
    
    }
    

    1.8 查看子节点数据

    • 示例:
    package com.sunxiaping.curator;
    
    import org.apache.curator.framework.CuratorFramework;
    import org.apache.curator.framework.CuratorFrameworkFactory;
    import org.apache.curator.framework.api.BackgroundCallback;
    import org.apache.curator.framework.api.CuratorEvent;
    import org.apache.curator.retry.ExponentialBackoffRetry;
    import org.apache.zookeeper.data.Stat;
    import org.junit.Before;
    import org.junit.Test;
    
    import java.util.List;
    
    /**
     * 查看节点数据
     */
    public class GetChildrenNodeData {
        private CuratorFramework client;
    
        @Before
        public void before() {
            client = CuratorFrameworkFactory.builder()
                    .connectString("192.168.40.101:2181")
                    .sessionTimeoutMs(5000)
                    .retryPolicy(new ExponentialBackoffRetry(1000, 3))
                    //命名空间
                    .namespace("hadoop")
                    .build();
            client.start();
        }
    
        @Test
        public void after() {
            if (client != null) {
                client.close();
            }
        }
    
        /**
         * 读取子节点数据
         *
         * @throws Exception
         */
        @Test
        public void GetChildrenNodeData1() throws Exception {
            List<String> list = client.getChildren().forPath("/node1");
            System.out.println("list = " + list);
        }
    
    
        /**
         * 读取子节点数据时获取节点的属性
         *
         * @throws Exception
         */
        @Test
        public void testGetNodeData2() throws Exception {
            Stat stat = new Stat();
            List<String> list = client.getChildren().storingStatIn(stat).forPath("/node1");
            System.out.println("list = " + list);
            System.out.println("stat = " + stat);
        }
    
        /**
         * 异步方式读取子节点数据
         *
         * @throws Exception
         */
        @Test
        public void testGetNodeData3() throws Exception {
            client.getChildren().inBackground(new BackgroundCallback() {
                @Override
                public void processResult(CuratorFramework client, CuratorEvent event) throws Exception {
                    System.out.println("节点路径 = " + event.getPath());
                    System.out.println("事件类型 = " + event.getType());
                    List<String> list = event.getChildren();
                    System.out.println("list = " + list);
                    Stat stat = event.getStat();
                    System.out.println("stat = " + stat);
                }
            }).forPath("/node1");
    
            Thread.sleep(5000);
            System.out.println("结束");
        }
    
    }
    

    1.9 查看节点是否存在

    • 示例:
    package com.sunxiaping.curator;
    
    import org.apache.curator.framework.CuratorFramework;
    import org.apache.curator.framework.CuratorFrameworkFactory;
    import org.apache.curator.framework.api.BackgroundCallback;
    import org.apache.curator.framework.api.CuratorEvent;
    import org.apache.curator.retry.ExponentialBackoffRetry;
    import org.apache.zookeeper.data.Stat;
    import org.junit.Before;
    import org.junit.Test;
    
    public class ExistsNode {
        private CuratorFramework client;
    
        @Before
        public void before() {
            client = CuratorFrameworkFactory.builder()
                    .connectString("192.168.40.101:2181")
                    .sessionTimeoutMs(5000)
                    .retryPolicy(new ExponentialBackoffRetry(1000, 3))
                    //命名空间
                    .namespace("hadoop")
                    .build();
            client.start();
        }
    
        @Test
        public void after() {
            if (client != null) {
                client.close();
            }
        }
    
        @Test
        public void testExistsNode1() throws Exception {
            Stat stat = client.checkExists().forPath("/node1");
            System.out.println("stat = " + stat);
        }
    
        @Test
        public void testExistsNode2() throws Exception {
            client.checkExists()
                    .inBackground(new BackgroundCallback() {
                        @Override
                        public void processResult(CuratorFramework client, CuratorEvent event) throws Exception {
                            System.out.println("节点路径 = " + event.getPath());
                            System.out.println("事件类型 = " + event.getType());
    
                            Stat stat = event.getStat();
                            System.out.println("stat = " + stat);
                        }
                    }).forPath("/node1");
            Thread.sleep(5000);
            System.out.println("结束");
        }
    
    }
    

    1.10 事件监听机制

    • curator提供了两种Watcher(Cache)来监听节点的变化。

    • Node Cache:只是监听某一个特定的节点,监听节点的新增和修改。

    • PathChildren Cache:监控一个znode节点,当一个子节点增加、删除时,PathChildren Cache会改变它的状态,会包含最新的子节点,子节点数据和状态。

    • 示例:

    package com.sunxiaping.curator;
    
    import org.apache.curator.framework.CuratorFramework;
    import org.apache.curator.framework.CuratorFrameworkFactory;
    import org.apache.curator.framework.recipes.cache.*;
    import org.apache.curator.retry.ExponentialBackoffRetry;
    import org.junit.Before;
    import org.junit.Test;
    
    public class CuratorWatcher {
        private CuratorFramework client;
    
        @Before
        public void before() {
            client = CuratorFrameworkFactory.builder()
                    .connectString("192.168.40.101:2181")
                    .sessionTimeoutMs(5000)
                    .retryPolicy(new ExponentialBackoffRetry(1000, 3))
                    //命名空间
                    .namespace("hadoop")
                    .build();
            client.start();
        }
    
        @Test
        public void after() {
            if (client != null) {
                client.close();
            }
        }
    
        @Test
        public void testWatcher1() throws Exception {
            //监视某个节点数据的变化
            NodeCache nodeCache = new NodeCache(client, "/watcher1");
            //增加监听器
            nodeCache.getListenable().addListener(new NodeCacheListener() {
                //当节点变化时
                @Override
                public void nodeChanged() throws Exception {
                    String path = nodeCache.getCurrentData().getPath();
                    System.out.println("path = " + path);
                    System.out.println("数据 = " + new String(nodeCache.getCurrentData().getData()));
                }
            });
    
            //启动监视器
            nodeCache.start();
    
            Thread.sleep(50000);
            System.out.println("结束");
            //关闭监视器
            nodeCache.close();
        }
    
        @Test
        public void testWatcher2() throws Exception {
            //监视子节点
            PathChildrenCache pathChildrenCache = new PathChildrenCache(client, "/watcher1", true);
            //增加监听器
            pathChildrenCache.getListenable().addListener(new PathChildrenCacheListener() {
                @Override
                public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
                    System.out.println("节点的事件类型 = " + event.getType());
                    System.out.println("节点的路径 = " + event.getData().getPath());
                    System.out.println("数据 = " + new String(event.getData().getData()));
                }
            });
    
            //启动监视器
            pathChildrenCache.start();
    
            Thread.sleep(50000);
            System.out.println("结束");
            //关闭监视器
            pathChildrenCache.close();
        }
    }
    

    1.11 事务

    • 示例:
    package com.sunxiaping.curator;
    
    import org.apache.curator.framework.CuratorFramework;
    import org.apache.curator.framework.CuratorFrameworkFactory;
    import org.apache.curator.retry.ExponentialBackoffRetry;
    import org.junit.Before;
    import org.junit.Test;
    
    public class CuratorTx {
        private CuratorFramework client;
    
        @Before
        public void before() {
            client = CuratorFrameworkFactory.builder()
                    .connectString("192.168.40.101:2181")
                    .sessionTimeoutMs(5000)
                    .retryPolicy(new ExponentialBackoffRetry(1000, 3))
                    //命名空间
                    .namespace("hadoop")
                    .build();
            client.start();
        }
    
        @Test
        public void after() {
            if (client != null) {
                client.close();
            }
        }
    
        @Test
        public void test() throws Exception {
            //开启事务
            client.inTransaction()
                    .create()
                    .forPath("/node1", "node1".getBytes())
                    .and()
                    .setData()
                    .forPath("/node2", "node2".getBytes())
                    .and()
                    //事务提交
                    .commit();
        }
    }
    

    1.12 分布式锁

    • InterProcessMutex:分布式可重入排它锁。

    • InterProcessReadWriteLock:分布式读写锁。

    • 示例:

    package com.sunxiaping.curator;
    
    import org.apache.curator.framework.CuratorFramework;
    import org.apache.curator.framework.CuratorFrameworkFactory;
    import org.apache.curator.framework.recipes.locks.InterProcessLock;
    import org.apache.curator.framework.recipes.locks.InterProcessMutex;
    import org.apache.curator.framework.recipes.locks.InterProcessReadWriteLock;
    import org.apache.curator.retry.ExponentialBackoffRetry;
    import org.junit.Before;
    import org.junit.Test;
    
    public class CuratorLock {
        private CuratorFramework client;
    
        @Before
        public void before() {
            client = CuratorFrameworkFactory.builder()
                    .connectString("192.168.40.101:2181")
                    .sessionTimeoutMs(5000)
                    .retryPolicy(new ExponentialBackoffRetry(1000, 3))
                    //命名空间
                    .namespace("hadoop")
                    .build();
            client.start();
        }
    
        @Test
        public void after() {
            if (client != null) {
                client.close();
            }
        }
    
        /**
         * 排它锁
         */
        @Test
        public void test1() throws Exception {
            //arg1:连接对象
            //arg2:节点路径
            InterProcessLock interProcessLock = new InterProcessMutex(client, "/lock1");
            System.out.println("等待获取锁对象");
            //获取锁
            interProcessLock.acquire();
            for (int i = 0; i < 10; i++) {
                Thread.sleep(3000);
                System.out.println("i = " + i);
            }
    
            //释放锁
            interProcessLock.release();
            System.out.println("等待释放锁");
    
        }
    
        /**
         * 读写锁
         */
        @Test
        public void test2() throws Exception {
            //arg1:连接对象
            //arg2:节点路径
            InterProcessReadWriteLock interProcessReadWriteLock = new InterProcessReadWriteLock(client, "/lock1");
            //读锁
            InterProcessLock readLock = interProcessReadWriteLock.readLock();
            System.out.println("等待获取锁对象");
            //获取锁
            readLock.acquire();
            for (int i = 0; i < 10; i++) {
                Thread.sleep(3000);
                System.out.println("i = " + i);
            }
    
            //释放锁
            readLock.release();
            System.out.println("等待释放锁");
        }
    
    
        /**
         * 读写锁
         */
        @Test
        public void test3() throws Exception {
            //arg1:连接对象
            //arg2:节点路径
            InterProcessReadWriteLock interProcessReadWriteLock = new InterProcessReadWriteLock(client, "/lock1");
            //写锁
            InterProcessLock writeLock = interProcessReadWriteLock.writeLock();
            System.out.println("等待获取锁对象");
            //获取锁
            writeLock.acquire();
            for (int i = 0; i < 10; i++) {
                Thread.sleep(3000);
                System.out.println("i = " + i);
            }
    
            //释放锁
            writeLock.release();
            System.out.println("等待释放锁");
        }
    }
    

    2 zookeeper四字监控命令

    • zookeeper支持某些特定的四字命令和其交互,它们大多数查询命令,用来获取zookeeper服务的当前状态及其相关信息。用户在客户端可以通过telnet或nc向zookeeper提交相应的命令。zookeeper常用的四字命令如下表所示:
    命令 描述
    conf 输出相关服务配置的详细信息。比如端口、zk数据、最大连接数、session超时时间、serverId等。
    cons 列出所有连接到这台服务器的客户端连接/会话的详细信息。包括"接受/发送"的包数量、sessionId、操作延迟、最后的操作执行等信息
    crst 重置当前这台服务器所有连接/会话统计信息
    dump 列出未经处理的会话和临时节点
    envi 输出关于服务器的环境详细信息
    ruok 测试服务是否处于正确运行状态。如果正常返回"imok",否则返回空。
    stat 输出服务器的详细新:接受/发送包数量、连接数、模式(Leader/follower)、节点总数、延迟。所有客户端的列表。
    wchs 列出服务器watches的简洁信息:连接总数、watching节点总数和watches总数。
    wchc 通过session分组,列出watch的所有节点,它的输出是一个和watch相关的会话的节点列表
    mntr 列出集群的健康状态。包括“接受/发送”的包数量、操作延迟、当前服务模式(Leader、follower)、节点总数、watch总数、临时节点总数。
    srst 重置server状态
    • telnet命令的安装:
    • 1️⃣查看是否安装telnet和依赖的xinetd:
    rpm -qa | grep telnet
    
    • 2️⃣没有则安装:
    yum -y install  xinetd
    yum -y install telnet
    yum -y install telnet-server
    
    • 3️⃣telnet默认不开启,修改文件/etc/xinetd.d/telnet来开启服务,修改disable=yes为disable=no。如果telnet文件不存在,则手动新建telnet文件,并添加如下内容:
    service telnet         
    {  
      flags = REUSE  
      socket_type = stream  
      wait = no  
      user = root  
      server =/usr/sbin/in.telnetd  
      log_on_failure += USERID  
      disable = no   
    }
    
    • 4️⃣启动telnet和xinetd。
    systemctl start xinetd
    
    • 5️⃣加入开机自启动:
    systemctl enable xinetd.service
    
    • 6️⃣telnet的使用:
    telnet 192.168.40.101 2181
    
    mntr
    

    • nc命令的安装:
    • 1️⃣安装命令如下:
    yum -y install nmap-ncat.x86_64
    
    • 2️⃣nc的使用:
    echo mntr | nc 192.168.40.101 2181
    

    nc的使用

    3 zookeeper图形化的客户端工具(ZooInspector)

    • 下载地址
    • 解压:进入目录的build,使用java -jar zookeeper-dev-ZooInspector.jar运行zookeeper-dev-ZooInspector.jar。

    ZooInspector启动界面

  • 相关阅读:
    redis集群部署之codis 维护脚本
    redis 数据库维护之 key 大小获取
    用HAProxy和KeepAlived构建高可用的反向代理
    blender 2.8 [学习笔记-028] 编辑模式- 所有面整体切分
    blender 2.8 [学习笔记-027] 编辑模式- 切分
    blender 2.8 [学习笔记-026] 编辑模式- 切割
    blender 2.8 [学习笔记-025] 编辑模式- 偏移环切边
    blender 2.8 [学习笔记-024] 编辑模式- 环切
    blender 2.8 [学习笔记-023] 编辑模式-倒角
    blender 2.8 [学习笔记-023] 编辑模式-内插面
  • 原文地址:https://www.cnblogs.com/xuweiweiwoaini/p/13814425.html
Copyright © 2011-2022 走看看