Curator和zookeeper

    Curator是Netflix开源的一套ZooKeeper客户端框架,用它来操作zookeeper更加简单方便。

    zookeeper的原生api相对来说比较繁琐,比如:对节点添加监听事件,当监听触发后,我们需要再次手动添加监听,否则监听只生效一次;再比如,断线重连也需要我们手动代码来判断处理等。

    Curator框架提供了一套高级的API, 简化了ZooKeeper的操作。它增加了很多使用ZooKeeper开发的特性,可以处理ZooKeeper集群复杂的连接管理和重试机制。


组成部分

Curator包含了几个包:

Framework:对zookeeper的底层api的一些封装,用来简化ZooKeeper高级功能的使用, 并增加了一些新的功能,比如管理到ZooKeeper集群的连接, 重试处理

Client:是ZooKeeper客户端的一个替代品, 提供了一些底层处理和相关的工具方法

Recipes:封装了一些高级特性,如:Cache事件监听、选举、分布式锁、分布式计数器、分布式Barrier等,该组件建立在Framework的基础之上

Utilities:各种ZooKeeper的工具类

Errors: 异常处理, 连接, 恢复等

Extensions: recipe扩展


从Framework入手

Framework 是ZooKeeperClient更高的抽象API。

自动连接管理:当ZooKeeper客户端内部出现异常,将自动进行重连或重试,该过程对外几乎完全透明,

更清晰的API:简化了ZooKeeper原生的方法,事件等, 提供流程的接口 。

CuratorFrameworkFactory类提供了两个方法,一个工厂方法newClient,一个构建方法build。 使用工厂方法newClient可以创建一个默认的实例, 而build构建方法可以对实例进行定制。当CuratorFramework实例构建完成,紧接着调用start()方法, 在应用结束的时候, 需要调用close()方法。 CuratorFramework是线程安全的。 在一个应用中可以共享同一个zk集群的CuratorFramework。


实例

Maven依赖

<dependency>
	<groupId>org.apache.curator</groupId>
	<artifactId>curator-framework</artifactId>
	<version>2.8.0</version>
</dependency>

<dependency>
	<groupId>org.apache.curator</groupId>
	<artifactId>curator-recipes</artifactId>
	<version>2.8.0</version>
</dependency>

<dependency>
       <groupId>org.apache.curator</groupId>
       <artifactId>curator-test</artifactId>
       <version>2.7.1</version>
</dependency>



两种创建方式

1使用静态工程方法newClient创建


2 构建方法 build


public static void main(String[] args) throws Exception {
        TestingServer server = new TestingServer();
        CuratorFramework client = null;
        try {
        	//使用静态方法newClient创建
            client = createSimple(server.getConnectString());
            client.start();
            client.create().creatingParentsIfNeeded().forPath(PATH, "test".getBytes());
            CloseableUtils.closeQuietly(client);

            //使用构建方法build创建
            client = createWithOptions(server.getConnectString(), new ExponentialBackoffRetry(1000, 3), 1000, 1000);
            client.start();
            System.out.println(new String(client.getData().forPath(PATH)));
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            CloseableUtils.closeQuietly(client);
            CloseableUtils.closeQuietly(server);
        }

    }

    public static CuratorFramework createSimple(String connectionString) {
        ExponentialBackoffRetry retryPolicy = new ExponentialBackoffRetry(1000, 3);
        return CuratorFrameworkFactory.newClient(connectionString, retryPolicy);
    }

    public static CuratorFramework createWithOptions(String connectionString, RetryPolicy retryPolicy, int connectionTimeoutMs, int sessionTimeoutMs) {
        return CuratorFrameworkFactory.builder().connectString(connectionString)
                .retryPolicy(retryPolicy)
                .connectionTimeoutMs(connectionTimeoutMs)
                .sessionTimeoutMs(sessionTimeoutMs)
                .build();
    }



四个主要参数:


参数名

说明

connectionString

服务器列表,格式host1:port1,host2:port2,...

retryPolicy

重试策略,内建有四种重试策略,也可以自行实现RetryPolicy接口

sessionTimeoutMs

会话超时时间,单位毫秒,默认60000ms

connectionTimeoutMs

连接创建超时时间,单位毫秒,默认60000ms


虽然上面的代码看起来简单明了,但是ZooKeeper的客户端在后台默默做了许多事情:

    1与ZooKeeper服务端进行通信,包括:连接,发送消息,接受消息。

    2发送心跳信息,保持与ZooKeeper服务端的有效连接与Session的有效性。

    3错误处理,如果客户端当前连接的ZooKeeper服务端失效,自动切换到另一台有效的ZooKeeper服务端。

    4管理Watcher,处理异常调用和Watcher。


操作方法

CuratorFramework提供的方法:


方法名

描述

create()

开始创建操作, 可以调用额外的方法(比如方式mode 或者后台执行background) 并在最后调用forPath()指定要操作的ZNode

delete()

开始删除操作. 可以调用额外的方法(版本或者后台处理version or background)并在最后调用forPath()指定要操作的ZNode

checkExists()

开始检查ZNode是否存在的操作. 可以调用额外的方法(监控或者后台处理)并在最后调用forPath()指定要操作的ZNode

getData()

开始获得ZNode节点数据的操作. 可以调用额外的方法(监控、后台处理或者获取状态watch, background or get stat) 并在最后调用forPath()指定要操作的ZNode

setData()

开始设置ZNode节点数据的操作. 可以调用额外的方法(版本或者后台处理) 并在最后调用forPath()指定要操作的ZNode

getChildren()

开始获得ZNode的子节点列表。 以调用额外的方法(监控、后台处理或者获取状态watch, background or get stat) 并在最后调用forPath()指定要操作的ZNode

inTransaction()

开始是原子ZooKeeper事务. 可以复合create, setData, check, and/or delete 等操作然后调用commit()作为一个原子操作提交


通过以上方法可对数据节点进行操作。



高级特性

Curator-Recipes:封装了一些高级特性,如:Cache事件监听、选举、分布式锁、分布式计数器、分布式Barrier等,该组件建立在Framework的基础之上。

后续结合实例一起进行研究。