java面试题网站:www.javaoffers.com
package com.mh.others.zk.curator;
import com.mh.others.log.LOGUtils;
import org.apache.curator.*;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.api.transaction.CuratorOp;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.x.discovery.ServiceDiscovery;
import org.apache.curator.x.discovery.ServiceDiscoveryBuilder;
import org.apache.curator.x.discovery.ServiceInstance;
import org.apache.curator.x.discovery.ServiceProviderBuilder;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.junit.Test;
/**
* @Description:
* @Auther: create by cmj on 2020/10/10 10:44
*/
public class CuratorStu {
/**
* 主要测试-创建,获取
* @throws Exception
*/
@Test
public void test() throws Exception {
//创建客户端
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
CuratorFramework client = CuratorFrameworkFactory.newClient("localhost:2181", retryPolicy);
client.start(); //开始链接
//链接状态改变时,在连接zk成功时/丢掉zk连接时(在使用client时zk突然宕机时) 都会触发改监听器
client.getConnectionStateListenable().addListener((a,b)->{
try {
if(b.isConnected()){
LOGUtils.printLog("zk连接已经建立完成");
}else{
LOGUtils.printLog("zk连接已经断开");
}
} catch (Exception e) {
e.printStackTrace();
}
});
client.delete().forPath("/curator-stu-persistent");//先删除
//创建 默认永久的
client.create().forPath("/curator-stu-persistent","cmj-curator-stu".getBytes());
//获取
byte[] bytes = client.getData().forPath("/curator-stu-persistent");
String s = new String(bytes);
LOGUtils.printLog(s);
//如果存在
if(client.checkExists().creatingParentContainersIfNeeded().forPath("/curator-stu-ephemeral")!=null){
client.delete().forPath("/curator-stu-ephemeral");//先删除
}
//创建临时的,动态的,CreateMode中包含永久的,永久有序的,临时的,临时有序的
String s1 = client.create().creatingParentContainersIfNeeded().withMode(CreateMode.EPHEMERAL).forPath("/curator-stu-ephemeral", bytes);
//查看
bytes = client.getData().forPath("/curator-stu-ephemeral");
s = new String(bytes);
LOGUtils.printLog(s);
//开启后台线程进行处理forPath,如果后台线程出错了则回调用该监听器, 该案例不好进行测试. 可以忽略此api, 尽量不要用inBackground (类似异步处理)
client.create().inBackground().withUnhandledErrorListener((a,b)->{
LOGUtils.printLog("withUnhandledErrorListener 绑定错误!!!");
}).forPath("/curator-UnhandledErrorListener","UnhandledErrorListener".getBytes());
byte[] unhandledErrorListener = client.getData().forPath("/curator-UnhandledErrorListener");
LOGUtils.printLog(new String(unhandledErrorListener));
client.delete().forPath("/curator-UnhandledErrorListener");
//创建或更新,如果存在则更新
client.create().orSetData().withMode(CreateMode.EPHEMERAL).forPath("/curator-watches");
//开始watcher监听,一次watcher一次触发,即: /curator-watches 被更改时会触发该watcher,如果不进行二次watcher监听, 则再次更新/curator-watches时则不会触发watcher,
client.checkExists().creatingParentContainersIfNeeded().usingWatcher(new Watcher() {
@Override
public void process(WatchedEvent event) {
LOGUtils.printLog(" triger watcher : "+event.getPath());
}
}).forPath("/curator-watches");
//更新,如果不存在 /curator-update 则会报错.
client.setData().forPath("/curator-update","curator-update".getBytes());
//事务
CuratorOp curatorOp = client.transactionOp().create().forPath("/curator-t1", "curator-t1".getBytes());
CuratorOp curatorOp1 = client.transactionOp().create().forPath("/curator-t2", "curator-t2".getBytes());
CuratorOp curatorOp2 = client.transactionOp().create().forPath("/curator-t3", "curator-t3".getBytes());
//执行事务
client.transaction().forOperations(curatorOp,curatorOp1,curatorOp2);
Thread.sleep(1000*500);
/**
* curator常用API:
* getConnectionStateListenable: zk连接状态监听
* create: 创建
* delete: 删除
* setData: 修改
* getData: 查询
* checkExists: watcher监听,是否存在
* transactionOp,transaction : 支持事务
*
*/
}
/**
* 删除,为了测试 watcher
* @throws Exception
*/
@Test
public void testDelete() throws Exception {
//创建客户端具有尝试链接功能
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
CuratorFramework client = CuratorFrameworkFactory.newClient("localhost:2181", retryPolicy);
client.start(); //开始链接
client.delete().forPath("/curator-watches"); //会触发watcher, 如果watcher 存在.
client.setData().forPath("/curator-watches","update-curator-watche1r".getBytes());//修改会触发watcher,如果watcher 存在.
}
/**
* serviceDiscovery 服务发现
* @throws Exception
*/
@Test
public void test2() throws Exception {
//创建客户端
ExponentialBackoffRetry retry = new ExponentialBackoffRetry(1000, 3);
CuratorFramework client = CuratorFrameworkFactory.newClient("localhost:2181", retry);
client.start();// 否者会报错 java.lang.IllegalStateException: Expected state [STARTED] was [LATENT]
ServiceDiscoveryBuilder<Object> builder = ServiceDiscoveryBuilder.builder(Object.class);
ServiceDiscovery<Object> sd = builder.client(client)
.basePath("curator-discovery-stu") //基础路径
.build();
ServiceInstance<Object> serviceInstance = ServiceInstance.builder()
.address("http://localhost/curator-discovery-stu")
.id("1")//当前服务的路径
.name("curator-service")
.enabled(true)
.build();
//serviceInstance 会转换为json格式的数据存在zk中.路径为: basePath/id,
/**
* 可以通过zk命令Get查看:
* [zk: localhost:2181(CONNECTED) 13] get /curator-discovery-stu/curator-service/1
* {"name":"curator-service","id":"1","address":"http://localhost/curator-discovery-stu","port":null,"sslPort":null,"payload":null,"registrationTimeUTC":1602646585722,"serviceType":"DYNAMIC","uriSpec":null}
* cZxid = 0x3f3
* ctime = Wed Oct 14 11:36:25 CST 2020
* mZxid = 0x3f3
* mtime = Wed Oct 14 11:36:25 CST 2020
* pZxid = 0x3f3
* cversion = 0
* dataVersion = 0
* aclVersion = 0
* ephemeralOwner = 0x175251a74250001
* dataLength = 203
* numChildren = 0
*/
sd.registerService(serviceInstance); //注册服务, 默认是 EPHEMERAL 动态的,非永久的,如果掉线会自动删除
}
}