我使用的zookeeper-3.4.11,所以添加dependency的版本号是2.x.x。
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.12.0</version>
</dependency>
基本用法,创建CuratorFramework。start方法会尝试连接zookeeper。其他的新建,读,更新,删除操作一看就能明白。
public static void main(String[] args) throws Exception {
RetryPolicy retryPolicy = new RetryOneTime(1000);
CuratorFramework framework = CuratorFrameworkFactory.newClient("127.0.0.1:2181", retryPolicy) ;
framework.start();
framework.create().forPath("/p", "hello".getBytes());
System.out.println(new String(framework.getData().forPath("/p")));
framework.setData().forPath("/p", "hello2".getBytes());
System.out.println(new String(framework.getData().forPath("/p")));
System.out.println(framework.checkExists().forPath("/p").getDataLength());
framework.delete().forPath("/p");
}
来一个复杂点的watch,运行下面代码后,重新打开客户端 zkCli.cmd, 添加节点 /p, 更新,删除等操作,均会收到通知。
public static void main(String[] args) throws Exception {
RetryPolicy retryPolicy = new RetryOneTime(1000);
CuratorFramework framework = CuratorFrameworkFactory.newClient("127.0.0.1:2181", retryPolicy);
framework.start();
framework.getCuratorListenable().addListener(new CuratorListener() {
public void eventReceived(CuratorFramework client, CuratorEvent event) throws Exception {
System.out.println(event.getWatchedEvent());
if (event.getType() == CuratorEventType.WATCHED) {
client.checkExists().watched().forPath("/p");
}
}
});
framework.checkExists().watched().forPath("/p");
System.in.read();
}
实现分布式锁:
public static void main(String[] args) throws Exception {
RetryPolicy retryPolicy = new RetryOneTime(1000);
CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", retryPolicy);
client.start();
InterProcessMutex lock = new InterProcessMutex(client, "/lock");
if (lock.acquire(10, TimeUnit.SECONDS)) {
System.out.println("Got lock!");
Thread.sleep(10000);
}
lock.release();
}
上面代码会在/lock 下面添加临时序列节点,最小的节点会成功的获取锁。在锁释放之前通过zkCli查看会看到有下面的节点:
[zk: localhost:2181(CONNECTED) 32] ls /lock
[_c_8eeaf9ce-8ce2-425b-abfe-0481c3788486-lock-0000000002]
领导选举,在方法 takeLeadership回调时,当前结点会被选中作为leader,处理一些事情后,方法结束时退出leader。接下来会重新选举leader。
private static void leader() throws Exception {
RetryPolicy retryPolicy = new RetryOneTime(1000);
CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", retryPolicy);
client.start();
LeaderSelector selector = new LeaderSelector(client, "/leader", new LeaderSelectorListener() {
public void stateChanged(CuratorFramework client, ConnectionState newState) {
}
public void takeLeadership(CuratorFramework client) throws Exception {
System.out.println("I got the leadship!");
// do something
System.out.println("I leave the leadship!");
}
});
selector.autoRequeue();
selector.start();
Thread.sleep(1000);
selector.close();
}