Apache Curator Framework

Curator framework提供了高级API, 极大的简化了ZooKeeper的使用。 它在ZooKeeper基础上增加了很多特性,可以管理与ZOoKeeper的连接和重试机制。这些特性包括:

  • 自动连接管理
    ** 有些潜在的错误情况需要让ZooKeeper client重建连接和重试。Curator可以自动地和透明地处理这些情况
  • Cleaner API
    简化原始的ZooKeeper方法,事件等 提供现代的流式接口
  • 技巧(Recipe)实现
    Leader选举 共享锁
    Path缓存和监控 分布式队列
    分布式优先级队列 ...

    产生Curator framework 实例

    使用CuratorFrameworkFactory产生framework实例。 CuratorFrameworkFactory 既提供了factory方法也提供了builder来创建实例。 CuratorFrameworkFactory是线程安全的。你应该在应用中为单一的ZooKeeper集群共享唯一的CuratorFramework实例。

工厂方法(newClient())提供了一个简单的方式创建实例。Builder可以使用更多的参数控制生成的实例。一旦生成framework实例, 必须调用start方法启动它。应用结束时应该调用close方法关闭它。

CuratorFramework API

CuratorFramework 使用流程风格的接口。 代码胜于说教:

1
2
3
4
client.create().forPath("/head", new byte[0]);
client.delete().inBackground().forPath("/head");
client.create().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath("/head/child", new byte[0]);
client.getData().watched().inBackground().forPath("/test");

方法

方法名描述
create()开始一create操作. 可以调用额外的方法(mode or background),最后调用forPath()
delete()开始一个delete操作. 调用额外的方法(version or background) , 最好调用forPath()
checkExists()开始一个检查ZNode是否存在的操作. 调用额外的方法 (watch or background), 最后调用forPath()
getData()开始一个获取ZNode节点数据的操作. 调用额外的方法(watch, background or get stat), 最后调用forPath()
setData()开始一个设置ZNode节点数据的操作. 调用额外的方法(version or background), 最后调用forPath()
getChildren()开始一个获取ZNode的子节点列表的操作.调用额外的方法(watch, background or get stat), 最后调用forPath()
inTransaction()开始一个原子的ZooKeeper事务. 可以包含 create, setData, check, and/or delete 操作的组合, 然后commit() 作为一个原子操作.

通知 Notifications

服务于后台操作和监控(watch)的通知通过ClientListener接口发布。你通过CuratorFramework实例的addListener方法可以注册监听器。
Interface CuratorListener

1
eventReceived() A background operation has completed or a watch has triggered. Examine the given event for details

Interface ConnectionStateListener:

1
2
stateChanged(CuratorFramework client, ConnectionState newState)
Called when there is a state change in the connection

Interface UnhandledErrorListener:

1
2
unhandledError(String message, Throwable e)
Called when an exception is caught in a background thread, handler, etc.

ClientEvent

ClientEvent是事件父类, 代表后台通知和监控的类型。 ClientEvent有用的字段根据事件的类型(getType()方法获取)不同而不同。

Event TypeEvent Methods
CREATEgetResultCode() and getPath()
DELETEgetResultCode() and getPath()
EXISTSgetResultCode(), getPath() and getStat()
GETDATAgetResultCode(), getPath(), getStat() and getData()
SETDATAgetResultCode(), getPath() and getStat()
CHILDRENgetResultCode(), getPath(), getStat(), getChildren()
WATCHEDgetWatchedEvent()

命名空间 namespace

因为ZOoKeeper是一个共享的集群。所以命名空间约定极为重要,各个应用在使用同一集群时不会有冲突的ZK path。
CuratorFramework 提供了命名空间的概念。当生成CuratorFramework 可以设置命名空间。CuratorFramework在调用API会在所有的path前面加上命名空间。

1
2
3
4
CuratorFramework client = CuratorFrameworkFactory.builder().namespace("MyApp") ... build();
...
client.create().forPath("/test", data);
// node was actually written to: "/MyApp/test"

临时连接

Temporary CuratorFramework instances are meant for single requests to ZooKeeper ensembles over a failure prone network such as a WAN.
临时的CuratorFramework用来发送单独请求通过一个易出错的网络如WAN。CuratorTempFramework 的API是有限制的,而且,连接在不用一段时间后会被关闭。
这个想法基于Camille Fournier的文章: http://whilefalse.blogspot.com/2012/12/building-global-highly-available.html

创建CuratorTempFramework

就像正常的CuratorFramework 实例一样,CuratorTempFramework依然通过CuratorFrameworkFactory 创建。但是最后不是调用build()方法, 而是buildTemp()。buildTemp()创建创建CuratorTempFramework然后在它不用三分钟后就关闭它。有个buildTemp()重载版本可以设定不活跃(不用)的时间。

Limited API

CuratorTempFramework提供了下列方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* Stop the client
*/
public void close();
/**
* Start a transaction builder
*
* @return builder object
* @throws Exception errors
*/
public CuratorTransaction inTransaction() throws Exception;
/**
* Start a get data builder
*
* @return builder object
* @throws Exception errors
*/
public TempGetDataBuilder getData() throws Exception;

原文