docker配置zookeeper集群:
我们需要的 docker-compose.yml 文件 ,这个需要我们自己先安装好,docker以及docker-compose,这个我在之前的教程中写到了,可以看这里:docker-compose以及docker的安装
接下来,是我们需要的的docker-compose.yml
文件:
version: '3'
services:
zoo1:
image: wurstmeister/zookeeper
restart: always
hostname: zoo1
container_name: zoo1
ports:
- 2181:2181
environment:
ZOO_MY_ID: 1
ZOO_SERVERS: server.1=0.0.0.0:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
zoo2:
image: wurstmeister/zookeeper
restart: always
hostname: zoo2
container_name: zoo2
ports:
- 2182:2181
environment:
ZOO_MY_ID: 2
ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=0.0.0.0:2888:3888;2181 server.3=zoo3:2888:3888;2181
zoo3:
image: wurstmeister/zookeeper
restart: always
hostname: zoo3
container_name: zoo3
ports:
- 2183:2181
environment:
ZOO_MY_ID: 3
ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=0.0.0.0:2888:3888;2181
这里坑点挺多的,就按照我的这个文件来。然后 docker-compose up
命令启动zookeeper集群(这里我用的是之前下载的 wurstmeister/zookeeper
image,因为懒得再下载, 如果你们想用最新版的,可以直接在上面改成 image: zookeeper
),我的zookeeper是在一台虚拟机上部署的,如果想用多台虚拟机,每台部署一个zookeeper server,可以改成这样子:
version: '3'
services:
zoo1:
image: wurstmeister/zookeeper
restart: always
hostname: zoo1
container_name: zoo1
ports:
- 2181:2181
environment:
ZOO_MY_ID: 1
ZOO_SERVERS: server.1=0.0.0.0:2888:3888;2181 server.2=第二台虚拟机IP:2888:3888;2181 server.3=第三台虚拟机IP:2888:3888;2181
version: '3'
services:
zoo2:
image: wurstmeister/zookeeper
restart: always
hostname: zoo2
container_name: zoo2
ports:
- 2182:2181
environment:
ZOO_MY_ID: 2
ZOO_SERVERS: server.1=第一台虚拟机IP:2888:3888;2181 server.2=0.0.0.0:2888:3888;2181 server.3=第三台虚拟机IP:2888:3888;2181
version: '3'
services:
zoo3:
image: wurstmeister/zookeeper
restart: always
hostname: zoo3
container_name: zoo3
ports:
- 2183:2181
environment:
ZOO_MY_ID: 3
ZOO_SERVERS: server.1=第一台虚拟机IP:2888:3888;2181 server.2=第二台虚拟机IP:2888:3888;2181 server.3=0.0.0.0:2888:3888;2181
上面是每台虚拟机zookeeper 对应的docker-compose.yml文件。总之,本身的那台虚拟机,地址设置成 0.0.0.0。
成功部署~
下面我们用java尝试连接一下,用zookeeper自带的客户端工具:
写一个测试类(仅仅用来连接):
public class TestZooKeeper {
private String connectString = "192.168.119.131:2181,192.168.119.131:2182,192.168.119.131:2183";
private int sessionTimeout = 2000;
private ZooKeeper zooKeeper;
@Test
public void init() throws IOException {
zooKeeper = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
public void process(WatchedEvent watchedEvent) {
}
});
}
}
这里我们要注意的是,需要关掉zookeeper所在虚拟机的防火墙,不然可能会发生不可预知的错误。
点击测试,如果测试用例通过,表示顺利连接上了集群。(上面的三个地址对应的是你的zookeeper server的地址,端口号是暴露到本地的端口号,这个我们在docker-compose.yml中提到了)
上面的测试类中使用的是zookeeper原生的客户端,但是不推荐大家使用,这里我建议使用 Curator ,所以,对于上面的例子,我不再扩展,下面我将重新使用Curator来实现节点的CRUD。
在此之前加入相关的依赖:
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.12.0</version>
</dependency>
代码如下(参考了 https://www.jianshu.com/p/ccd31ddcd2d6 )
public class CuratorConTest {
private static String connectString = "192.168.119.131:2181,192.168.119.131:2182,192.168.119.131:2183";
static RetryPolicy policy = new ExponentialBackoffRetry(1000, 3); // 重试3次
static CuratorFramework zkFluentClient = CuratorFrameworkFactory.builder()
.connectString(connectString)
.sessionTimeoutMs(5000)
.connectionTimeoutMs(3000)
.retryPolicy(policy)
.build();
public static void main(String[] args) throws Exception {
zkFluentClient.start();
CuratorConTest curatorConTest = new CuratorConTest();
curatorConTest.testCreate();
curatorConTest.testGet();
}
private void testCreate() throws Exception {
// 2、创建有默认值的节点
zkFluentClient.create().forPath("/book","Love story".getBytes());
// 3、创建临时节点,断开后会自动清除
zkFluentClient.create().withMode(CreateMode.EPHEMERAL).
forPath("/template","template Node".getBytes());
// 4、创建临时节点,同时如果父节点不存在,也把父节点创建了。但是父节点会是持久节点
zkFluentClient.create().creatingParentsIfNeeded()
.withMode(CreateMode.EPHEMERAL).
forPath("/parentnode/childnode","parentnodeorchildnode".getBytes());
}
private void testGet() throws Exception {
// 1、获取,注意返回的是bytes
String value = new String(zkFluentClient.getData().forPath("/book"));
System.out.println(value);
}
}