基本操作函数
连接服务器
Zookeeper的所有操作都基于会话,因为我们也从连接服务器开始。
1 | 4j |
三个必要参数:
- connectString:连接串,也就是host:port 列表,表示服务器地址,连接成功后悔返回一个sessionId
- sessionTimeout:超时时间(至少是tickTime的两倍,至多是20倍),服务器会返回一个它的
- watcher:默认监听器,有两个作用,一个是作为会话的监听对象(之前在介绍api的时候我们连接到服务器显示的watch字段),另一个是作为后面其他操作的默认监听器。
如上的代码,是一个简单的示例,连接到server端,并继承Watche,将自己作为watche注册。运行代码:
1 | 11:43:06.451|INFO |onConnected|org.apache.zookeeper.ClientCnxn - Session establishment complete on server localhost/0:0:0:0:0:0:0:1:2181, session id = 0x100052db5000015, negotiated timeout = 15000 |
上面的输出可以看出,连接成功,并触发了监听
创建节点
一般Zookeeper方法中有同步和异步两种方式,下面我们用示例来演示,不过通常我们使用异步的方式来处理。
我们接着上面的代码继续往下,新增一个Node类,这个是为我们主从模式作铺垫。
1 | /** |
参数:
- path:节点路径
- data:节点绑定的数据
- acl: 权限列表,可以参考[ZooKeeper ACL权限控制]https://blog.csdn.net/liuxiao723846/article/details/79391650)
- createMode: 节点的类型,比如持久节点还是临时节点
- cb: 回调,这个是一个创建的模式,创建完成后会触发回调函数
- ctx: 环境变量,也就是回调函数中所需要的。
由上可以看出,同步和异步没有太大的不同,主要是一些参数的不同,异步有点麻烦的是要实现回调,但它的性能和可操作性远胜同步的。
在main函数中分别加入这两个方法启动:
1 | ## 同步方法 |
我们发现/master节点可以创建两次,也就是说明确实是临时节点,不过如果两次启动够快的话,会出现nodeExists的状态。
监听器watches
所有读操作都能增加一个监听器,getData()、getChildre()、exists(). 使用方法如:
1 | public Stat exists(final String path, Watcher watcher) ; // 使用心得监听器 |
监听器是在服务端维护的,所以就算客户端失去连接了,也可以选择在重新连接上后再次注册。
在定义监听器时,需要考虑三个关键点:
- 只触发一次:默认watch,数据更改后,一个监视事件将发送给客户端,但在此修改后,不会发送,除非你重新再设置。
- 异步发送:客户端可能因为网络原因导致不会理解获得监听器返回的数据,不过Zookeeper保证在收到监听数据之前,看不到任何改节点的变换,也就是胡搜Zookeeper保证了顺序一致性。
- 不同的watch返回的数据不一样: getData()和exists()返回节点的信息,但getChildren()返回的是子节点列表。
触发情况
事件 | exists | getData | getChildren |
---|---|---|---|
创建create | ture | true | false |
删除delete | true | true | true |
修改set | true | true | flase |
子节点事件 | false | false | true |
示例一:我们接着使用上面的代码来演示,在我们创建/master 之前,我们使用CommonClient来监听/master节点,我们在创建完成后,再进行删除。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22public class TestWatch implements Watcher {
public void process(WatchedEvent event) {
log.info("监听结果:{}",event);
}
}
// CommonClient 类中添加
void masterExist() throws KeeperException, InterruptedException {
zk.exists("/master",new TestWatch());
}
// main 函数中添加
CommonClient commonClient = new CommonClient();
commonClient.startZK();
Node node=new Node();
commonClient.masterExist();
node.runForMaster();
Thread.sleep(1000);
log.info("--------------------------------");
node.stopZK();
while (true){
Thread.sleep(1000);
}
测试结果:
1 | 11:47:44.014|INFO |process|com.huawei.cq.CommonClient - com.huawei.cq.Node@1f1c7bf6 状态 WatchedEvent state:SyncConnected type:None path:null |
由上可以看出,在创建的时候触发了一次监听,但在删除的时候不会再触发。
哪有没有永久触发呢,肯定是有的,3.6.0版本之后增加了永久监听器,后面会讲。