- 首先安装Docker Desktop
官网:Docker Desktop: The #1 Containerization Tool for Developers | Docker
-
安装ubuntu镜像
docker pull ubuntu
-
zookeeper的运行需要java的支持,因此需要先在环境中安装jdk
sql
apt-get update
apt-get install -y openjdk-8-jdk
- 作为集群,那么网络是需要互通的,而Docker容器默认并不具有一个可在宿主机网络上直接访问的IP地址。因此Dokcer可以使用一个自己的网络来让容器之间能够互相通信。
arduino
docker network create mynetwork #mynetwork换成自定义名称
- 运行容器,三台服务器的端口需要绑定不同。因为这是在一台服务器上进行三台 集群部署:
yaml
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
- 在bin和conf的同级目录下创建一个数据文件夹,并在数据文件夹中创建一个名为myid的文件。填入全局唯一的序号:
在每一台服务器中这个id都要不一样
- 修改每一台zookeeper服务器的配置文件,文件在解压后的conf中的zoo.cfg文件中。修改配置如下:
ini
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文件中设置的那个序号。
- 创建的网络中具体的地址查询如下:
yaml
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
因此修改过的配置文件应该为(如果你重新启动容器,这个地址可能是会变化的!!!! ):
ini
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
- zookeeper要超过半数的服务器启动才会启动,因此对于三台服务器,需要在其中两台中在bin目录下运行:
bash
./zkServer.sh start # 启动命令
即可选举出Leader和Follower。
bash
./zkServer.sh stop #停止命令
./zkServer.sh status # 查看状态
- 通过java访问:
- maven的配置:
xml
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.5.7</version>
</dependency>
- 创建连接:
java
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是超时时间,配置如下:
ini
private String connectString="localhost:2181,localhost:2182,localhost:2183";
private int sessionTime=2000;
其中的Watcher是监听的机制,需要重写process方法。因为每次监听都是一次性的,通过重写Watcher中的process方法能够实现实时监听,下面的例子就是不断监听servers
下的节点变化:
ini
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);
}