zookeeper
官网地址: https://zookeeper.apache.org/doc/r3.8.0/zookeeperStarted.html
中文地址: https://zookeeper.net.cn/index.html
介绍
核心概念
zookeeper是一个分布式的开源框架,它能很好的管理集群,而且提供协调分布式应用的基本服务。
它向外部应用暴露一组通用服务——分布式同步(Distributed Synchronization)、命名服务(Naming Service)、集群维护(Group Maintenance)等,简化分布式应用协调及其管理的难度,提供高性能的分布式服务。
zookeeper本身可以以standalone模式(单节点状态)安装运行,不过它的长处在于通过分布式zookeeper集群(一个leader,多个follower),基于一定的策略来保证zookeeper集群的稳定性和可用性,从而实现分布式应用的可靠性。
集群角色介绍
zookeeper集群中主要有两个角色:leader和follower。
领导者(leader),用于负责进行投票的发起和决议,更新系统状态。
学习者(learner),包括跟随者(follower)和观察者(observer)。
其中follower用于接受客户端请求并想客户端返回结果,在选主过程中参与投票。
而observer可以接受客户端连接,将写请求转发给leader,但observer不参加投票过程,只同步leader的状态,observer的目的是为了扩展系统,提高读取速度。
zookeeper节点部署的越多,服务的可靠性也就越高。当然建议最好是部署奇数个,偶数个不是不可以。但是zookeeper集群是以宕机个数过半才会让整个集群宕机的,所以奇数个集群更佳。
docker安装
安装
# 1、拉取 zookeeper 镜像
docker pull zookeeper:3.7.1-temurin
# 2、创建 zookeeper 配置文件目录 用于挂载
mkdir -p /usr/local/zookeeper/conf
echo "tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181" \
>>/usr/local/zookeeper/conf/zoo.cfg
# 3、启动 zookeeper
docker run --name zookeeper01 --restart always -d \
-p 2181:2181 \
-v /usr/local/zookeeper/conf/zoo.cfg:/conf/zoo.cfg zookeeper:3.7.1-temurin
docker run --name zookeeper01 --restart always -d \
-v /usr/local/zookeeper/conf/zoo.cfg:/conf/zoo.cfg zookeeper:3.7.1-temurin
docker run --name zookeeper01 --restart always -d zookeeper:3.7.1-temurin
操作
# 进入容器
root@8b57a494c9e5:/apache-zookeeper-3.7.1-bin# ls
# 启动 zookeeper
bin/zkServer.sh start
# 进入zookeeper
bin/zkCli.sh -server 127.0.0.1:2181
成功进入后看到如下界面
Welcome to ZooKeeper!
JLine support is enabled
... # 中间具体内容省略
[zk: localhost:2181(CONNECTED) 0]
命令
可以参考 : https://zookeeper.net.cn/zookeeperCLI.html
成功进入后使用help查勘zookeeper全部命令
addauth scheme auth ### 节点添加权限
close ### 节点添加权限
config [-c] [-w] [-s] ### 配置文件
connect host:port ### 连接
create [-s] [-e] [-c] [-t ttl] path [data] [acl] ### 添加节点
delete [-v version] path ### 根据节点版本号删除节点
deleteall path [-b batch size] ### 删除该节点以及该节点所有子节点
delquota [-n|-b|-N|-B] path
get [-s] [-w] path ### 获取节点内容
getAcl [-s] path ### 获取一条路径的ACL权限
getAllChildrenNumber path ### 获取特定路径下的所有子节点数
getEphemerals path
history ### 查看操作历史
listquota path ### 列出一个路径的配额
ls [-s] [-w] [-R] path
printwatches on|off ### 打开/关闭是否打印手表的开关。
quit ### 退出
reconfig [-s] [-v version] [[-file path] | [-members serverID=host:port1:port2;port3[,...]*]] | [-add serverId=host:port1:port2;port3[,...]]* [-remove serverId[,...]*]
redo cmdno
removewatches path [-c|-d|-a] [-l]
set [-s] [-v version] path data ### 设置节点内容
setAcl [-s] [-v version] [-R] path acl
setquota -n|-b|-N|-B val path
stat [-w] path
sync path ### 异步操作节点
version ### 查看zookeeper版本信息
whoami ### 查看用户信息
基本操作实例
添加节点
# 创建节点
create /zk_test1
# 设置节点内容
set /zk_test1 zk_test1_content
# 获取节点详细内容
get -s /zk_test1
### 测试 添加 给/zk_test1节点添加两个
zk: localhost:2181(CONNECTED) 20] create /zk_test1/zk_test1_child1
Created /zk_test1/zk_test1_child1
[zk: localhost:2181(CONNECTED) 21] create /zk_test1/zk_test1_child2
Created /zk_test1/zk_test1_child2
[zk: localhost:2181(CONNECTED) 22] set /zk_test1/zk_test1_child1 zk_test1_child1_content
[zk: localhost:2181(CONNECTED) 23] set /zk_test1/zk_test1_child2 zk_test2_child2_content
[zk: localhost:2181(CONNECTED) 24] ls -R /
/
/zk_test1
/zk_test2
/zookeeper
/zk_test1/zk_test1_child1
/zk_test1/zk_test1_child2
/zookeeper/config
/zookeeper/quota
[zk: localhost:2181(CONNECTED) 25]
删除命令
[zk: localhost:2181(CONNECTED) 25] delete /zk_test2
[zk: localhost:2181(CONNECTED) 26] delete /zk_test1
Node not empty: /zk_test1
因为节点 /zk_test1含有子节点 ,直接是删除不掉的 需要使用 deleteall
命令,这里就不测试了
版本号测试
[zk: localhost:2181(CONNECTED) 30] get -s /zk_test1/zk_test1_child1
zk_test1_child1_content
cZxid = 0xb
ctime = Thu Sep 01 19:38:41 UTC 2022
mZxid = 0xd
mtime = Thu Sep 01 19:39:12 UTC 2022
pZxid = 0xb
cversion = 0
dataVersion = 1 ### 第一次内容版本号
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 23
numChildren = 0
[zk: localhost:2181(CONNECTED) 31] set /zk_test1/zk_test1_child1 content_change_child1
[zk: localhost:2181(CONNECTED) 32] get -s /zk_test1/zk_test1_child1
content_change_child1
cZxid = 0xb
ctime = Thu Sep 01 19:38:41 UTC 2022
mZxid = 0x11
mtime = Thu Sep 01 19:47:33 UTC 2022
pZxid = 0xb
cversion = 0
dataVersion = 2 ### 内容修改之后版本号
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 21
numChildren = 0
根据版本号删除节点
[zk: localhost:2181(CONNECTED) 33] delete -v 1 /zk_test1/zk_test1_child1
version No is not valid : /zk_test1/zk_test1_child1
[zk: localhost:2181(CONNECTED) 34] delete -v 2 /zk_test1/zk_test1_child1
[zk: localhost:2181(CONNECTED) 35] get /zk_test1/zk_test1_child1
Node does not exist: /zk_test1/zk_test1_child1 ### 成功删除节点了!
设置权限
[zk: localhost:2181(CONNECTED) 44] addauth digest user1:12345
[zk: localhost:2181(CONNECTED) 46] create /acl_auth_test
Created /acl_auth_test
[zk: localhost:2181(CONNECTED) 47] setAcl /acl_auth_test auth:user1:12345:crwad
[zk: localhost:2181(CONNECTED) 48] getAcl /acl_auth_test
'digest,'user1:+owfoSBn/am19roBPzR1/MfCblE=
重新开个窗口进入容器
docker exec -it zookeeper01 /bin/bash
bin/zkCli.sh -server 127.0.0.1:2181
WatchedEvent state:SyncConnected type:None path:null
[zk: 127.0.0.1:2181(CONNECTED) 0] getAcl /acl_auth_test
Insufficient permission : /acl_auth_test
此时无权限获取节点 /acl_auth_test 内容
设置一个节点权限
setAcl -R /acl_auth_test auth:user1:12345:crwad
其他命令
[zk: localhost:2181(CONNECTED) 67] whoami
Auth scheme: User
ip: 127.0.0.1
digest: user1
[zk: localhost:2181(CONNECTED) 68] version
ZooKeeper CLI version: 3.7.1-a2fb57c55f8e59cdd76c34b357ad5181df1258d5, built on 2022-05-07 06:45 UTC
节点属性
cZxid | 创建节点时的事务ID |
---|---|
ctime | 创建节点时的时间 |
mZxid | 最后修改节点时的事务ID |
mtime | 最后修改节点时的时间 |
pZxid | 表示该节点的子节点列表最后一次修改的事务ID,添加子节点或删除子节点就会影响子节点列表,但是修改子节点的数据内容则不影响该ID(注意,只有子节点列表变更了才会变更pzxid,子节点内容变更不会影响pzxid) |
cversion | 子节点版本号,子节点每次修改版本号加1 |
dataversion | 数据版本号,数据每次修改该版本号加1 |
aclversion | 权限版本号,权限每次修改该版本号加1 |
ephemeralOwner | 创建该临时节点的会话的sessionID。 (* 如果该节点是持久节点,那么这个属性值为0)* |
dataLength | 该节点的数据长度 |
numChildren | 该节点拥有子节点的数量(只统计直接子节点的数量) |
Zookeeper的应用场景
- 数据发布/订阅
- 负载均衡
- 分布式协调/通知
- 集群管理
- 集群管理
- master 管理
- 分布式锁
- 分布式队列
代码操作
开启服务
首先开启一个docker容器
docker run -d --restart=always -p 2181:2181 --name=zookeeper02 zookeeper:3.7.1-temurin
客户端的zookeeper原生 API
测试连接 这个容器
ConnectionDemo
public static void main(String[] args) throws Exception {
try {
final CountDownLatch countDownLatch = new CountDownLatch(1);
ZooKeeper zooKeeper =
new ZooKeeper("192.168.56.40:2181",
4000, new Watcher() {
@Override
public void process(WatchedEvent event) {
if (Event.KeeperState.SyncConnected == event.getState()) {
//如果收到了服务端的响应事件,连接成功
countDownLatch.countDown();
}
}
});
countDownLatch.await();
//CONNECTED
System.out.println(zooKeeper.getState());
// 添加一个节点
createNode(zooKeeper,"/zk_testNode1","创建第一个节点");
} catch (Exception e) {
System.err.println(e.toString());
}
}
public static void createNode(ZooKeeper zooKeeper, String path, String message) {
try {
zooKeeper.create(path, message.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
}
}
控制台输出结果,出现 CONNECTED 说明连接成功
D:\environment\java\jdk\bin\java.exe -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:3677,suspend=y,server=n -javaagent:C:\Users\Administrator\AppData\Local\JetBrains\IntelliJIdea2021.2\captureAgent\debugger-agent.jar -Dfile.encoding=UTF-8 -classpath "D:\environment\java\jdk\jre\lib\charsets.jar;D:\environment\java\jdk\jre\lib\deploy.jar;D:\environment\java\jdk\jre\lib\ext\access-bridge-64.jar;D:\environment\java\jdk\jre\lib\ext\cldrdata.jar;D:\environment\java\jdk\jre\lib\ext\dnsns.jar;D:\environment\java\jdk\jre\lib\ext\jaccess.jar;D:\environment\java\jdk\jre\lib\ext\jfxrt.jar;D:\environment\java\jdk\jre\lib\ext\localedata.jar;D:\environment\java\jdk\jre\lib\ext\nashorn.jar;D:\environment\java\jdk\jre\lib\ext\sunec.jar;D:\environment\java\jdk\jre\lib\ext\sunjce_provider.jar;D:\environment\java\jdk\jre\lib\ext\sunmscapi.jar;D:\environment\java\jdk\jre\lib\ext\sunpkcs11.jar;D:\environment\java\jdk\jre\lib\ext\zipfs.jar;D:\environment\java\jdk\jre\lib\javaws.jar;D:\environment\java\jdk\jre\lib\jce.jar;D:\environment\java\jdk\jre\lib\jfr.jar;D:\environment\java\jdk\jre\lib\jfxswt.jar;D:\environment\java\jdk\jre\lib\jsse.jar;D:\environment\java\jdk\jre\lib\management-agent.jar;D:\environment\java\jdk\jre\lib\plugin.jar;D:\environment\java\jdk\jre\lib\resources.jar;D:\environment\java\jdk\jre\lib\rt.jar;D:\desktop\Learn\admin\zookeeper\target\classes;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\org\apache\zookeeper\zookeeper\3.7.1\zookeeper-3.7.1.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\org\apache\zookeeper\zookeeper-jute\3.7.1\zookeeper-jute-3.7.1.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\org\apache\yetus\audience-annotations\0.12.0\audience-annotations-0.12.0.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\io\netty\netty-handler\4.1.76.Final\netty-handler-4.1.76.Final.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\io\netty\netty-common\4.1.76.Final\netty-common-4.1.76.Final.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\io\netty\netty-resolver\4.1.76.Final\netty-resolver-4.1.76.Final.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\io\netty\netty-buffer\4.1.76.Final\netty-buffer-4.1.76.Final.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\io\netty\netty-transport\4.1.76.Final\netty-transport-4.1.76.Final.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\io\netty\netty-codec\4.1.76.Final\netty-codec-4.1.76.Final.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\io\netty\netty-transport-native-epoll\4.1.76.Final\netty-transport-native-epoll-4.1.76.Final.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\io\netty\netty-transport-native-unix-common\4.1.76.Final\netty-transport-native-unix-common-4.1.76.Final.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\io\netty\netty-transport-classes-epoll\4.1.76.Final\netty-transport-classes-epoll-4.1.76.Final.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\org\slf4j\slf4j-api\1.7.35\slf4j-api-1.7.35.jar;D:\software\idea\IntelliJ IDEA 2021.2\lib\idea_rt.jar" com.wuxin.zookeeper.ConnectionDemo
Connected to the target VM, address: '127.0.0.1:3677', transport: 'socket'
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
SLF4J: Failed to load class "org.slf4j.impl.StaticMDCBinder".
SLF4J: Defaulting to no-operation MDCAdapter implementation.
SLF4J: See http://www.slf4j.org/codes.html#no_static_mdc_binder for further details.
CONNECTED
Disconnected from the target VM, address: '127.0.0.1:3677', transport: 'socket'
进入容器查看添加节点
# 进入容器
docker exec -it zookeeper02 /bin/bash
# 连接zookeeper服务
bin/zkCli.sh -server 127.0.0.1:2181
#查看内容
[zk: 127.0.0.1:2181(CONNECTED) 0] ls /
[zk_testNode1, zookeeper]
节点添加成功!
其他操作类似
客户端的curator连接
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.data.Stat;
public class CuratorDemo {
public static void main(String[] args) throws Exception {
CuratorFramework curatorFramework =
CuratorFrameworkFactory
.builder()
.connectString("192.168.56.40:2181")
.sessionTimeoutMs(4000).retryPolicy(new ExponentialBackoffRetry(1000, 3)).
namespace("").build();
curatorFramework.start();
Stat stat = new Stat();
//查询节点数据
byte[] bytes = curatorFramework.getData().storingStatIn(stat).forPath("/zk_testNode1");
System.out.println(new String(bytes));
curatorFramework.close();
}
}
输出内容,可以看到输出内容获取到
D:\environment\java\jdk\bin\java.exe -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:3824,suspend=y,server=n -javaagent:C:\Users\Administrator\AppData\Local\JetBrains\IntelliJIdea2021.2\captureAgent\debugger-agent.jar -Dfile.encoding=UTF-8 -classpath "D:\environment\java\jdk\jre\lib\charsets.jar;D:\environment\java\jdk\jre\lib\deploy.jar;D:\environment\java\jdk\jre\lib\ext\access-bridge-64.jar;D:\environment\java\jdk\jre\lib\ext\cldrdata.jar;D:\environment\java\jdk\jre\lib\ext\dnsns.jar;D:\environment\java\jdk\jre\lib\ext\jaccess.jar;D:\environment\java\jdk\jre\lib\ext\jfxrt.jar;D:\environment\java\jdk\jre\lib\ext\localedata.jar;D:\environment\java\jdk\jre\lib\ext\nashorn.jar;D:\environment\java\jdk\jre\lib\ext\sunec.jar;D:\environment\java\jdk\jre\lib\ext\sunjce_provider.jar;D:\environment\java\jdk\jre\lib\ext\sunmscapi.jar;D:\environment\java\jdk\jre\lib\ext\sunpkcs11.jar;D:\environment\java\jdk\jre\lib\ext\zipfs.jar;D:\environment\java\jdk\jre\lib\javaws.jar;D:\environment\java\jdk\jre\lib\jce.jar;D:\environment\java\jdk\jre\lib\jfr.jar;D:\environment\java\jdk\jre\lib\jfxswt.jar;D:\environment\java\jdk\jre\lib\jsse.jar;D:\environment\java\jdk\jre\lib\management-agent.jar;D:\environment\java\jdk\jre\lib\plugin.jar;D:\environment\java\jdk\jre\lib\resources.jar;D:\environment\java\jdk\jre\lib\rt.jar;D:\desktop\Learn\admin\zookeeper\target\classes;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\org\apache\zookeeper\zookeeper\3.7.1\zookeeper-3.7.1.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\org\apache\zookeeper\zookeeper-jute\3.7.1\zookeeper-jute-3.7.1.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\org\apache\yetus\audience-annotations\0.12.0\audience-annotations-0.12.0.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\io\netty\netty-handler\4.1.76.Final\netty-handler-4.1.76.Final.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\io\netty\netty-common\4.1.76.Final\netty-common-4.1.76.Final.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\io\netty\netty-resolver\4.1.76.Final\netty-resolver-4.1.76.Final.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\io\netty\netty-buffer\4.1.76.Final\netty-buffer-4.1.76.Final.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\io\netty\netty-transport\4.1.76.Final\netty-transport-4.1.76.Final.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\io\netty\netty-codec\4.1.76.Final\netty-codec-4.1.76.Final.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\io\netty\netty-transport-native-epoll\4.1.76.Final\netty-transport-native-epoll-4.1.76.Final.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\io\netty\netty-transport-native-unix-common\4.1.76.Final\netty-transport-native-unix-common-4.1.76.Final.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\io\netty\netty-transport-classes-epoll\4.1.76.Final\netty-transport-classes-epoll-4.1.76.Final.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\org\slf4j\slf4j-api\1.7.35\slf4j-api-1.7.35.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\org\apache\curator\curator-framework\4.0.0\curator-framework-4.0.0.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\org\apache\curator\curator-client\4.0.0\curator-client-4.0.0.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\com\google\guava\guava\20.0\guava-20.0.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\org\apache\curator\curator-recipes\4.0.0\curator-recipes-4.0.0.jar;D:\software\idea\IntelliJ IDEA 2021.2\lib\idea_rt.jar" com.wuxin.zookeeper.CuratorDemo
Connected to the target VM, address: '127.0.0.1:3824', transport: 'socket'
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
SLF4J: Failed to load class "org.slf4j.impl.StaticMDCBinder".
SLF4J: Defaulting to no-operation MDCAdapter implementation.
SLF4J: See http://www.slf4j.org/codes.html#no_static_mdc_binder for further details.
创建第一个节点
监听
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import java.io.IOException;
public class WatcherDemo implements Watcher {
static ZooKeeper zooKeeper;
static {
try {
// 连接客户端
zooKeeper = new ZooKeeper("192.168.56.40:2181", 4000, new WatcherDemo());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void process(WatchedEvent event) {
System.out.println("eventType:" + event.getType());
if (event.getType() == Event.EventType.NodeDataChanged) {
try {
zooKeeper.exists(event.getPath(), true);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
String path = "/watcher";
if (zooKeeper.exists(path, false) == null) {
zooKeeper.create("/watcher", "0".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
Thread.sleep(1000);
System.out.println("-----------");
//true表示使用zookeeper实例中配置的watcher
Stat stat = zooKeeper.exists(path, true);
System.in.read();
}
}
控制台内容
D:\environment\java\jdk\bin\java.exe -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:14799,suspend=y,server=n -javaagent:C:\Users\Administrator\AppData\Local\JetBrains\IntelliJIdea2021.2\captureAgent\debugger-agent.jar -Dfile.encoding=UTF-8 -classpath "D:\environment\java\jdk\jre\lib\charsets.jar;D:\environment\java\jdk\jre\lib\deploy.jar;D:\environment\java\jdk\jre\lib\ext\access-bridge-64.jar;D:\environment\java\jdk\jre\lib\ext\cldrdata.jar;D:\environment\java\jdk\jre\lib\ext\dnsns.jar;D:\environment\java\jdk\jre\lib\ext\jaccess.jar;D:\environment\java\jdk\jre\lib\ext\jfxrt.jar;D:\environment\java\jdk\jre\lib\ext\localedata.jar;D:\environment\java\jdk\jre\lib\ext\nashorn.jar;D:\environment\java\jdk\jre\lib\ext\sunec.jar;D:\environment\java\jdk\jre\lib\ext\sunjce_provider.jar;D:\environment\java\jdk\jre\lib\ext\sunmscapi.jar;D:\environment\java\jdk\jre\lib\ext\sunpkcs11.jar;D:\environment\java\jdk\jre\lib\ext\zipfs.jar;D:\environment\java\jdk\jre\lib\javaws.jar;D:\environment\java\jdk\jre\lib\jce.jar;D:\environment\java\jdk\jre\lib\jfr.jar;D:\environment\java\jdk\jre\lib\jfxswt.jar;D:\environment\java\jdk\jre\lib\jsse.jar;D:\environment\java\jdk\jre\lib\management-agent.jar;D:\environment\java\jdk\jre\lib\plugin.jar;D:\environment\java\jdk\jre\lib\resources.jar;D:\environment\java\jdk\jre\lib\rt.jar;D:\desktop\Learn\admin\zookeeper\target\classes;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\org\apache\zookeeper\zookeeper\3.7.1\zookeeper-3.7.1.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\org\apache\zookeeper\zookeeper-jute\3.7.1\zookeeper-jute-3.7.1.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\org\apache\yetus\audience-annotations\0.12.0\audience-annotations-0.12.0.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\io\netty\netty-handler\4.1.76.Final\netty-handler-4.1.76.Final.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\io\netty\netty-common\4.1.76.Final\netty-common-4.1.76.Final.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\io\netty\netty-resolver\4.1.76.Final\netty-resolver-4.1.76.Final.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\io\netty\netty-buffer\4.1.76.Final\netty-buffer-4.1.76.Final.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\io\netty\netty-transport\4.1.76.Final\netty-transport-4.1.76.Final.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\io\netty\netty-codec\4.1.76.Final\netty-codec-4.1.76.Final.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\io\netty\netty-transport-native-epoll\4.1.76.Final\netty-transport-native-epoll-4.1.76.Final.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\io\netty\netty-transport-native-unix-common\4.1.76.Final\netty-transport-native-unix-common-4.1.76.Final.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\io\netty\netty-transport-classes-epoll\4.1.76.Final\netty-transport-classes-epoll-4.1.76.Final.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\org\slf4j\slf4j-api\1.7.35\slf4j-api-1.7.35.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\org\apache\curator\curator-framework\4.0.0\curator-framework-4.0.0.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\org\apache\curator\curator-client\4.0.0\curator-client-4.0.0.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\com\google\guava\guava\20.0\guava-20.0.jar;D:\environment\java\maven\apache-maven-3.8.3\maven-repo\org\apache\curator\curator-recipes\4.0.0\curator-recipes-4.0.0.jar;D:\software\idea\IntelliJ IDEA 2021.2\lib\idea_rt.jar" com.wuxin.zookeeper.WatcherDemo
Connected to the target VM, address: '127.0.0.1:14799', transport: 'socket'
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
SLF4J: Failed to load class "org.slf4j.impl.StaticMDCBinder".
SLF4J: Defaulting to no-operation MDCAdapter implementation.
SLF4J: See http://www.slf4j.org/codes.html#no_static_mdc_binder for further details.
eventType:None
监听之后在 docker 容器中操作节点 /watcher 操作,
set /watcher watcher_content
控制台新增内容,监听到了节点发生了变化。
-----------
eventType:NodeDataChanged
部分源代码
# 设置监控
request.setWatch(watcher != null);
zookeeper集群搭建
docker 容器下 zookeeper 目录如下
root@8b57a494c9e5:/# ls
apache-zookeeper-3.7.1-bin data etc lib64 mnt run tmp
bin datalog home libx32 opt sbin usr
boot dev lib logs proc srv var
conf docker-entrypoint.sh lib32 media root sys
root@8b57a494c9e5:/#
配置文件和 id文件分别在 conf 和 data 配置文件中
修改配置文件 /conf/zoo.cfg
dataDir=/data
dataLogDir=/datalog
tickTime=2000
initLimit=5
syncLimit=2
autopurge.snapRetainCount=3
autopurge.purgeInterval=0
maxClientCnxns=60
standaloneEnabled=true
admin.enableServer=true
server.1=localhost:2888:3888;2181
主要添加以下内容
server.1=192.168.56.10:2888:3888;2181
server.2=192.168.56.20:2888:3888;2181
server.3=192.168.56.30:2888:3888;2181
其他三个类似,然后就是修改 /data/myid 内容依次为 1 、2 、3
修改完毕之后需要重新启,这三台就可以默认为是一个zookeeper小集群了
ZAB协议
zookeeper 原子广播协议 https://zookeeper.net.cn/zookeeperInternals.html#sc_consistency
ZooKeeper 的核心是一个原子消息系统,它使所有服务器保持同步。