掘金 后端 ( ) • 2024-05-01 10:21
  1. 首先安装Docker Desktop

官网:Docker Desktop: The #1 Containerization Tool for Developers | Docker

  1. 安装ubuntu镜像
docker pull ubuntu
  1. zookeeper的运行需要java的支持,因此需要先在环境中安装jdk
apt-get update
apt-get install -y openjdk-8-jdk
  1. 作为集群,那么网络是需要互通的,而Docker容器默认并不具有一个可在宿主机网络上直接访问的IP地址。因此Dokcer可以使用一个自己的网络来让容器之间能够互相通信。
docker network create mynetwork    #mynetwork换成自定义名称
  1. 运行容器,三台服务器的端口需要绑定不同。因为这是在一台服务器上进行三台 集群部署:
docker run -it --network=mynetwork -p 2181:2181 -p 2888:2888 -p 3888:3888 --name ubuntu1 ubuntu
docker run -it --network=mynetwork -p 2182:2181 -p 2889:2888 -p 3889:3888 --name ubuntu2 ubuntu
docker run -it --network=mynetwork -p 2183:2181 -p 2890:2888 -p 3890:3888 --name ubuntu3 ubuntu
  1. 在bin和conf的同级目录下创建一个数据文件夹,并在数据文件夹中创建一个名为myid的文件。填入全局唯一的序号:

在每一台服务器中这个id都要不一样

  1. 修改每一台zookeeper服务器的配置文件,文件在解压后的conf中的zoo.cfg文件中。修改配置如下:
tickTime=2000
dataDir=/var/zookeeper/  #修改为自己的数据文件夹,可以在conf同级目录创建一个data文件夹,填入地址
clientPort=2181
initLimit=5
syncLimit=2
server.1=localhost:2888:3888 #这里填三台集群的映射端口。如果有多台就写多台。
server.2=localhost:2889:3889 # localhost要替换成网络中具体的地址
server.3=localhost:2890:3890

这个配置告诉ZooKeeper去寻找运行在‘localhost:2888:3888’,‘localhost:2889:3889’和‘localhost:2890:3890’的其他ZooKeeper实例。

注意

  • 在ZooKeeper集群配置中,server.X然后是它们的主机名字(server.X=hostname:port:port)。X是服务器的标识符,这个标识符在每个ZooKeeper实例中myid文件中设置的那个序号。
  • 创建的网络中具体的地址查询如下:
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' ubuntu1
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' ubuntu2
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' ubuntu3

因此修改过的配置文件应该为(如果你重新启动容器,这个地址可能是会变化的!!!! ):

tickTime=2000
dataDir=/opt/module/zookeeper-3.5.7/zkData
clientPort=2181
initLimit=10
syncLimit=5
server.1=172.18.0.4:2888:3888
server.2=172.18.0.3:2889:3889
server.3=172.18.0.2:2890:3890
  1. zookeeper要超过半数的服务器启动才会启动,因此对于三台服务器,需要在其中两台中在bin目录下运行:
./zkServer.sh start  # 启动命令

即可选举出Leader和Follower。

./zkServer.sh stop  #停止命令
./zkServer.sh status # 查看状态
  1. 通过java访问:
  • maven的配置:
<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.5.7</version>
</dependency>
  • 创建连接:
ZooKeeper zk =  new ZooKeeper(connectString, sessionTime, new Watcher() {
        public void process(WatchedEvent watchedEvent) {
            try {
                getServerList();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } catch (KeeperException e) {
                throw new RuntimeException(e);
            }
        }
    });
}

其中connectString就是三台服务器的连接地址、sessionTime是超时时间,配置如下:

private String connectString="localhost:2181,localhost:2182,localhost:2183";
private int sessionTime=2000;

其中的Watcher是监听的机制,需要重写process方法。因为每次监听都是一次性的,通过重写Watcher中的process方法能够实现实时监听,下面的例子就是不断监听servers下的节点变化:

private void getServerList() throws InterruptedException, KeeperException {
  List<String> children = zooKeeper.getChildren("/servers", true);
  ArrayList<String> servers = new ArrayList<String>();
  for (String child : children) {
      byte[] data = zooKeeper.getData("/servers/" + child, false, null);
      servers.add(new String(data));
  }
  //打印
  System.out.println(servers);
}