Apachecurator-framework是一个高层API,对curator-client组件进行了二次封装,开发者可以更少的关注zookeeper底层,进行快捷的开发.
特性一览:
- 链接管理: 框架已经兼容了zookeeper网络链接异常问题,并提供了自动重连机制.
- 简洁的API设计: fluent风格API(最大亮点),大部分API中已经兼容了zookeeper操作异常问题.
- 事件通知: 对于wather的注册/管理,以及事件处理,一致都比较繁琐,在framework中,这个工作将变得简单.
- 提供了基于异步操作,和zk异常控制.
CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder(); // fluent style String namespace = "cluster-worker";//命名空间,会被作为所有path的前缀自动补全. // FixedEnsembleProvider CuratorFramework client = builder.connectString("127.0.0.1:2181") .sessionTimeoutMs(30000) .connectionTimeoutMs(30000) .canBeReadOnly(false) .retryPolicy(new ExponentialBackoffRetry(1000, Integer.MAX_VALUE)) .namespace(namespace) .aclProvider(new MappedACLProvider()) .defaultData(null) .build(); // client中无法直接指定watcher(即defaultWatcher),因为框架需要使用这个watcher来处理与链接有关的异常 // 开发者可以通过如下方式指定 CuratorListener listener = new CuratorListener() { @Override public void eventReceived(CuratorFramework client, CuratorEvent event) throws Exception { if(event == null){ return; } if(CuratorEventType.CLOSING == event.getType()){ System.out.println("Client will be closed!"); }else{ System.out.println("CuratorEvent type:" + event.getType().toString()); System.out.println("CuratorEvent path:" + event.getPath()); } } }; client.getCuratorListenable().addListener(listener); client.start(); //.... //client.close()在client中注册的listener或者backgroundCallback将会在两个单独的线程中运行.当zookeeper操作有任何事件触发时,都会执行listener.eventReceived()方法. 2. 创建节点("异步"方式)
EnsurePath ensure = client.newNamespaceAwareEnsurePath(namespace); ensure.ensure(client.getZookeeperClient()); // -----------create a node------------ // use async style // for time trace BackgroundCallback callback = new BackgroundCallback() { @Override public void processResult(CuratorFramework client, CuratorEvent event) throws Exception { Long begin = (Long) event.getContext(); Long end = System.currentTimeMillis(); System.out.println("<Time>:" + (end - begin) + "ms"); //check result Code rc = Code.get(event.getResultCode()); if(rc != Code.OK){ System.out.println("Background operation fail,path:" + event.getPath() + ";Message:" + KeeperException.create(rc).getMessage()); } } }; long current = System.currentTimeMillis(); String value = "test-" + current; client.create() .creatingParentsIfNeeded() .withMode(CreateMode.PERSISTENT) .inBackground(callback, current) .forPath("/test/0", value.getBytes("utf-8"));
create操作以异步的方式执行,此时"create操作"将会被封装成一个Operation而提交到线程池中,无论操作执行是否成功或者抛出异常,都执行BackgroundCallback;对于开发者而言,需要在callback中处理"失败"情况.
3. getData和注册watcher
// ----------getData--------------- // register a watcher // only print something CuratorWatcher dataWatcher = new CuratorWatcher() { @Override public void process(WatchedEvent event) throws Exception { System.out.println("path:" + event.getPath()); EventType eventType = event.getType(); if (eventType == EventType.None) { KeeperState state = event.getState(); System.out.println(state.toString()); } else { System.out.println(eventType.toString()); } } }; Stat stat = new Stat(); byte[] data = client.getData().storingStatIn(stat).usingWatcher(dataWatcher).forPath("/test/0"); System.out.println("version:" + stat.getVersion()); System.out.println("data:" + new String(data));
4. 事务
// trasaction CuratorTransaction tx = client.inTransaction(); tx.delete().forPath("/test/0") .and() .create().forPath("/test/01") .and() .commit();
使用frameworker开发zookeeper程序,已经相当简单了,开发者无需过度关注"链接异常"等问题.