zookeeper的安装目录:/usr/local/zookeeper-3.4.6/bin/zkServer.sh;

配置文件路径:../conf/zoo.cfg


端口 :2181;


ZooKeeper服务命令:

     在准备好相应的配置之后,可以直接通过zkServer.sh 这个脚本进行服务的相关操作

  • 1. 启动ZK服务:       sh bin/zkServer.sh start
  • 2. 查看ZK服务状态: sh bin/zkServer.sh status
  • 3. 停止ZK服务:       sh bin/zkServer.sh stop
  • 4. 重启ZK服务:       sh bin/zkServer.sh restart

zk客户端命令

ZooKeeper命令行工具类似于Linux的shell环境,不过功能肯定不及shell啦,但是使用它我们可以简单的对ZooKeeper进行访问,数据创建,数据修改等操作.  使用 ./zkCli.sh -server 127.0.0.1:2181 连接到 ZooKeeper 服务,连接成功后,系统会输出 ZooKeeper 的相关环境以及配置信息。

命令行工具的一些简单操作如下:

  • 1. 显示根目录下、文件: ls / 使用 ls 命令来查看当前 ZooKeeper 中所包含的内容
  • 2. 显示根目录下、文件: ls2 / 查看当前节点数据并能看到更新次数等数据
  • 3. 创建文件,并设置初始内容: create /zk "test" 创建一个新的 znode节点“ zk ”以及与它关联的字符串
  • 4. 获取文件内容: get /zk 确认 znode 是否包含我们所创建的字符串
  • 5. 修改文件内容: set /zk "zkbak" 对 zk 所关联的字符串进行设置
  • 6. 删除文件: delete /zk 将刚才创建的 znode 删除
  • 7. 退出客户端: quit
  • 8. 帮助命令: help

 


ZooKeeper 常用四字命令:

      ZooKeeper 支持某些特定的四字命令字母与其的交互。它们大多是查询命令,用来获取 ZooKeeper 服务的当前状态及相关信息。用户在客户端可以通过 telnet 或 nc 向 ZooKeeper 提交相应的命令

  • 1. 可以通过命令:echo stat|nc 127.0.0.1 2181 来查看哪个节点被选择作为follower或者leader
  • 2. 使用echo ruok|nc 127.0.0.1 2181 测试是否启动了该Server,若回复imok表示已经启动。
  • 3. echo dump| nc 127.0.0.1 2181 ,列出未经处理的会话和临时节点。
  • 4. echo kill | nc 127.0.0.1 2181 ,关掉server
  • 5. echo conf | nc 127.0.0.1 2181 ,输出相关服务配置的详细信息。
  • 6. echo cons | nc 127.0.0.1 2181 ,列出所有连接到服务器的客户端的完全的连接 / 会话的详细信息。
  • 7. echo envi |nc 127.0.0.1 2181 ,输出关于服务环境的详细信息(区别于 conf 命令)。
  • 8. echo reqs | nc 127.0.0.1 2181 ,列出未经处理的请求。
  • 9. echo wchs | nc 127.0.0.1 2181 ,列出服务器 watch 的详细信息。
  • 10. echo wchc | nc 127.0.0.1 2181 ,通过 session 列出服务器 watch 的详细信息,它的输出是一个与 watch 相关的会话的列表。
  • 11. echo wchp | nc 127.0.0.1 2181 ,通过路径列出服务器 watch 的详细信息。它输出一个与 session 相关的路径。

一、Zookeeper单击模式安装及使用

1、系统环境

liunx 查看zookeeper版本 linux查看zookeeper是否启动_客户端

2、导入JDK和Zookeeper包

1)、使用SecureCRT工具打开SFTP连接,直接拖拽,到当前用户文件夹下,然后使用mv命令(mv 文件 目标文件夹)移动到自定义路径下

liunx 查看zookeeper版本 linux查看zookeeper是否启动_服务器_02

2)、使用tar -zxvf 包名,解压JDK和Zookeeper

liunx 查看zookeeper版本 linux查看zookeeper是否启动_客户端_03

 3、配置java环境变量,vi /etc/profile,编辑完成保存后,使用source /etc/profile使环境变量生效,java -version命令验证

liunx 查看zookeeper版本 linux查看zookeeper是否启动_liunx 查看zookeeper版本_04

liunx 查看zookeeper版本 linux查看zookeeper是否启动_liunx 查看zookeeper版本_05

4、在zookeeper目录下的conf目录下,新建zoo.cfg文件并配置如下(zoo.cfg文件是Zookeeper默认配置文件,其配置案例在zoo_samples.cfg中)

 

liunx 查看zookeeper版本 linux查看zookeeper是否启动_客户端_06

tickTime:服务器与服务器之间或服务器与客户端之间心跳间隔

dataDir:Zookeeper保存数据的目录,默认情况下,Zookeeper将写数据的日志文件也保存在这;如果目录不存在启动时候会自动创建

clientPort:客户端连接Zookeeper服务器的端口,Zookeeper会监听这个端口,接收客户端的访问请求

5、启动Zookeeper,在bin文件夹下调用zkServer.sh start命令,start后面如果不指定配置文件路径,默认使用con/zoo.cfg

liunx 查看zookeeper版本 linux查看zookeeper是否启动_liunx 查看zookeeper版本_07

查看服务状态,./zkServer.sh status

liunx 查看zookeeper版本 linux查看zookeeper是否启动_zookeeper_08

6、客户端连接服务端,bin/zkCli.sh -server 127.0.0.1:2181

liunx 查看zookeeper版本 linux查看zookeeper是否启动_liunx 查看zookeeper版本_09

7、增删改查命令使用,进入客户端后通过help可查看所有命令使用方法

liunx 查看zookeeper版本 linux查看zookeeper是否启动_liunx 查看zookeeper版本_10

1)、ls 查看znode节点

liunx 查看zookeeper版本 linux查看zookeeper是否启动_liunx 查看zookeeper版本_11

2)、create 创建znode节点,节点后面必须赋值,否则不会创建成功

liunx 查看zookeeper版本 linux查看zookeeper是否启动_客户端_12

3)、get 获取节点值

liunx 查看zookeeper版本 linux查看zookeeper是否启动_liunx 查看zookeeper版本_13

4)、set 修改节点值

liunx 查看zookeeper版本 linux查看zookeeper是否启动_客户端_14

5)、创建/test子节点,注意获取/test值时,cversion由0变为1

liunx 查看zookeeper版本 linux查看zookeeper是否启动_客户端_15

6)、delete 删除节点

如果有子节点,父节点不能删除,需要先删除子节点再删除父节点

liunx 查看zookeeper版本 linux查看zookeeper是否启动_liunx 查看zookeeper版本_16

7)、quit 退出客户端操作界面

liunx 查看zookeeper版本 linux查看zookeeper是否启动_zookeeper_17

8、停掉Zookeeper服务

liunx 查看zookeeper版本 linux查看zookeeper是否启动_zookeeper_18

二、Zookeeper集群模式搭建(3台,最好奇数台,根据Leader选举算法Paxos协议,半数原则)

zk1对应IP:192.168.7.128

zk2对应IP:192.168.7.216

zk3对应IP:192.168.7.217

1、每台服务器上搭建基础环境,参照单击模式搭建

2、在Zookeeper保存数据的文件路径下创建myid文件,并写入server对应值(如果保存数据文件路径不存在自己创建),各台机器执行如下命令

zk1中命令:echo "1">myid;zk2中命令:echo "2">myid;zk3中命令:echo "3">myid

最终如下

liunx 查看zookeeper版本 linux查看zookeeper是否启动_liunx 查看zookeeper版本_19

3、配置各台及其conf/zoo.cfg文件如下

liunx 查看zookeeper版本 linux查看zookeeper是否启动_客户端_20

initLimit:Zookeeper集群中,连接到Leader的Follower服务初始化连接时最长限制时间多少个心跳间隔,如上配置5,表示5*2000=10秒,10秒内没有连接上表示Follower连接失败

syncLimit:Leader和Follower之间发送消息,请求和应答最长心跳间隔数,如上2*2000=4秒

 server.x(x表示上面配置的1,2,3),x就是各台服务器中写入myid文件的数

IP:2888:3888      IP就是各服务器IP,2888是这个服务器与集群中的Leader进行信息交换的端口,3888是表示万一集群中的Leader服务器挂掉,需要一个端口来重新进行选举,选出一个新Leader,也就是这个3888端口是用来执行选举Leader时候用

4、启动各台Zookeeper服务 bin/zkServer.sh start ,都启动成功后,bin/zkServer.sh status查看服务器状态

起初查看状态报错如下,后来想到是防火墙的问题,就执行 systemctl stop firewalld 关闭即可

liunx 查看zookeeper版本 linux查看zookeeper是否启动_zookeeper_21

查看防火墙并关闭

liunx 查看zookeeper版本 linux查看zookeeper是否启动_客户端_22

各台服务器 bin/zkServer.sh restart 命令重启Zookeeper服务,查看状态

zk1服务器如下,注意Mode:leader,即此服务器为集群Leader(Leader选举有算法,并非第一个就是Leader)

liunx 查看zookeeper版本 linux查看zookeeper是否启动_liunx 查看zookeeper版本_23

zk2服务器如下,注意Mode:

 

liunx 查看zookeeper版本 linux查看zookeeper是否启动_客户端_24

zk3服务器和zk2服务器一样,Mode都是follower

5、测试集群,随便一个服务器上增删改节点,另一个服务器上也会一致性变化(可自行验证)

6、如果Leader服务器挂掉,会选出另一台Leader服务器,3台服务器最多可挂掉一台,超过一台挂掉Zookeeper就不可用了

 三、ZooKeeper JavaAPI使用,直接上代码,看注释



package com.hjp.zookeeper;

import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;

import java.io.IOException;
import java.util.concurrent.CountDownLatch;

public class ConnectionWatcher implements Watcher {

    private static final int SESSION_TIMEOUT = 5000;

    protected ZooKeeper zk;
    private CountDownLatch connectedSignal = new CountDownLatch(1);

    public void connect(String hosts) throws IOException, InterruptedException {
        //第一个参数是Zookeeper服务主机地址,可指定端口号,默认为2181;第二个参数以毫秒为单位的会话超时参数;
        // 第三个参数是一个Watcher对象的实例。Watcher对象接收来自于Zookeeper的回调,以获得各种事件通知,
        // 本例中CreateGroup是一个Watcher对象,因此参数为this
        zk = new ZooKeeper(hosts, SESSION_TIMEOUT, this);
        //当一个ZooKeeper的实例被创建时,会启动一个线程连接到Zookeeper服务。
        // 由于对构造函数的调用是立即返回的,因此在使用新建的Zookeeper对象之前一定要等待其与Zookeeper服务之间的连接建立成功。
        // 使用CountDownLatch使当前线程等待,直到Zookeeper对象准备就绪
        connectedSignal.await();
    }

    public void process(WatchedEvent watchedEvent) {
        //客户端与ZK建立连接后,Watcher的process方法会被调用,参数是表示该连接的事件,
        // 连接成功后调用CountDownLatch的countDown方法,计数器减为0,释放线程锁,zk对象可用
        if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {
            connectedSignal.countDown();
        }
    }

    public void close() throws InterruptedException {
        zk.close();
    }
}

连接ZK



package com.hjp.zookeeper;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooDefs.Ids;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.CountDownLatch;

public class ZKOperateAPI extends ConnectionWatcher {

    //创建组
    public void create(String groupName, String data) throws KeeperException, InterruptedException {
        String path = "/" + groupName;
        //创建znode节点,第一个参数为路径;第二个参数为znode内容,字节数组;
        // 第三个参数访问控制列表(简称ACL,此处使用完全开放的ACL,允许任何客户端对znode进行读写);
        // 第四个为创建znode类型,此处是持久的(两种类型,短暂的和持久的,短暂类型会在客户端与zk服务断开连接后,被zk服务删掉,而持久的不会)
        String createPath = zk.create(path, data.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        System.out.println("Created " + createPath);
    }

    //加入组
    public void join(String groupName, String memberName, String data) throws KeeperException, InterruptedException {
        String path = "/" + groupName + "/" + memberName;
        //创建短暂znode,会在客户端断开连接后删掉
        String createPath = zk.create(path, data.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
        System.out.println("Create " + createPath);
    }

    //列出组成员
    public void list(String groupName) {
        String path = "/" + groupName;
        try {
            //第一个参数为组名,即znode路径;第二个参数是否设置观察标识,如果为true,那么一旦znode状态改变,当前对象的Watcher会被触发
            List<String> children = zk.getChildren(path, false);
            if (children.isEmpty()) {
                System.out.printf("No members in group %s\n", groupName);
                System.exit(1);
            }
            for (String child : children) {
                System.out.println(child);
            }
        } catch (KeeperException.NoNodeException ex) {
            System.out.printf("Group %s does not exist\n", groupName);
            System.exit(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (KeeperException e) {
            e.printStackTrace();
        }
    }

    //删除组
    public void delete(String groupName) throws KeeperException, InterruptedException {
        String path = "/" + groupName;
        try {
            List<String> children = zk.getChildren(path, false);
            for (String child : children) {
                //删除方法第一个参数指定路径,第二个参数是版本号;这是一种乐观锁机制,如果指定的版本号和对应znode版本号一致才可删除;
                // 如果设置为-1,不校验可直接删除
                zk.delete(path + "/" + child, -1);
            }
            zk.delete(path, -1);
        } catch (KeeperException.NoNodeException ex) {
            System.out.printf("Group %s does not exist\n", groupName);
            System.exit(1);
        }
    }

}

增删改查操作,继承连接类




import com.hjp.zookeeper.ZKOperateAPI;
import org.junit.Test;

public class TestZK {

    @Test
    public void create() throws Exception {
        ZKOperateAPI operateAPI = new ZKOperateAPI();
        //端口号不写,默认是2181
//        operateAPI.connect("192.168.7.128:2181");
        operateAPI.connect("192.168.7.128");
        operateAPI.create("testAPI", "aaa");
        operateAPI.close();
    }

    @Test
    public void join() throws Exception {
        ZKOperateAPI operateAPI = new ZKOperateAPI();
        operateAPI.connect("192.168.7.128");
        ;
        operateAPI.join("testAPI", "testAPIChild", "aaaChild");
        //模拟正在某种操作,休眠20秒后,断开zk服务连接,可查看zk服务中短暂znode被删除
        Thread.sleep(20000);
        operateAPI.close();
    }

    @Test
    public void list() throws Exception {
        ZKOperateAPI operateAPI = new ZKOperateAPI();
        operateAPI.connect("192.168.7.216");
        operateAPI.list("testAPI");
        operateAPI.close();
    }

    @Test
    public void delete() throws Exception{
        ZKOperateAPI operateAPI = new ZKOperateAPI();
        operateAPI.connect("192.168.7.217");
        operateAPI.delete("testAPI");
        operateAPI.close();
    }

}

测试执行代码

如果在java 连接的过程中报 Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory     异常

那么需要将zookeeper 安装目录下的 lib文件夹下的相关jar包导入到工程中