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