Zookeeper客户端Curator---Getting Started

先说个小插曲,前几天有个网站转载我的文章没有署名作者,我有点不开心就给他们留言了,然后今天一看他们把文章删了。其实我的意思并不是你允许转载,我想表达的是我的付出需要被尊重。也不知道是谁的错~

==================================

官网上的入门教程非常简单,如下:

学习Zookeeper

使用Curator的用户默认是了解Zookeeper的,Zookeeper的入门在这里:http: //zookeeper.apache.org/doc/trunk/zookeeperStarted.html

使用Curator

Curator的jar包可以从Maven中央仓库获得。各种工具罗列在主页上 main page。Maven,Gradle,Ant等用户可以轻松地将Curator包含进其构建脚本中。

大多数用户希望使用Curator的预制recipes(基于framework,提供高级特性),所以,curator-recipes是个正确的选择。如果您只想使用Zookeeper添加连接管理和重试策略的封装好的工具,那么使用curator-framework。

获取一个连接

Curator使用流式风格。如果你之前没有使用过这个,可能看起来很奇怪,因此建议您事先熟悉一下风格。ps:其实就是链式风格(Demo demo = new DemoBuilder().first().second().last().build();)

Curator连接的实例(CuratorFramework)来自于CuratorFrameworkFactory。每一个你连接的Zookeeper集群只需要一个CuratorFramework实例:

CuratorFrameworkFactory.newClient(zookeeperConnectionString, retryPolicy)

这将会使用默认值去连接一个Zookeeper集群。唯一需要指定的是 重试策略。大多数情况下,您应该使用:

RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3)
CuratorFramework client = CuratorFrameworkFactory.newClient(zookeeperConnectionString, retryPolicy);
client.start();

客户端必须启动(不再使用必须关闭)

直接调用Zookeeper

一旦你有一个CuratorFramework实例,你可以直接调用ZooKeeper,就像使用ZooKeeper中提供的原始Zookeeper对象一样。例如:

client.create().forPath("/my/path", myData)

这里的好处是:由CuratorFramework管理Zookeeper连接,并且当出现连接问题时会重试。

Recipes(高级特性)

分布式锁

InterProcessMutex lock = new InterProcessMutex(client, lockPath);
if ( lock.acquire(maxWait, waitUnit) )
{
    try
    {
        // do some work inside of the critical section here
    }
    finally
    {
        lock.release();
    }
}

Leader选举

LeaderSelectorListener listener = new LeaderSelectorListenerAdapter()
{
    public void takeLeadership(CuratorFramework client) throws Exception
    {
        // this callback will get called when you are the leader
        // do whatever leader work you need to and only exit
        // this method when you want to relinquish leadership
    }
}

LeaderSelector selector = new LeaderSelector(client, path, listener);
selector.autoRequeue();  // not required, but this is behavior that you will probably expect
selector.start();

更多的特性翻译接下来的文章会有。

一个小例子

导入的jar包:

curator-recipes这个包没用到,ZkClient那个包是另外一个客户端,这里也用不到,除了这两个其他都是要导入的

package zookeeper.curator;

import java.util.List;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.api.BackgroundCallback;
import org.apache.curator.framework.api.CuratorEvent;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;

public class CuratorBase {

    private static String connectString = "192.168.127.129:2181,192.168.127.130:2181,192.168.127.131:2181";

    public static void main(String[] args) throws Exception {

        // 重试策略,初试时间1s,重试3次
        RetryPolicy policy = new ExponentialBackoffRetry(1000, 3);

        CuratorFramework curator = CuratorFrameworkFactory.newClient(connectString, policy);
        curator.start();
        //获取状态
        System.out.println(curator.getState());

        System.out.println("============Create=============");
        //创建节点
        String cPath1 = curator.create()
                .creatingParentsIfNeeded()
                .withMode(CreateMode.PERSISTENT).inBackground(new BackgroundCallback() {

            @Override
            public void processResult(CuratorFramework curatorFramework, CuratorEvent event) throws Exception {
                System.out.println(">>>>>>>>>>>>>>>>>>>>>>>");
                System.out.println("Code:" + event.getResultCode());
                System.out.println("Name:" + event.getName());
                System.out.println("Path:" + event.getPath());
                System.out.println("Type:" + event.getType());
                System.out.println("CurrentThread:" + Thread.currentThread().getName());
                System.out.println("<<<<<<<<<<<<<<<<<<<<<<<");
            }
        }).forPath("/root/rt", "123".getBytes());
        System.out.println("MainThread:" + Thread.currentThread().getName());
        Thread.sleep(2000); //暂停2s,为了等异步执行完,否则下面会报错:KeeperErrorCode = NoNode for /root/rr
        System.out.println(cPath1);
        String cPath2 = curator.create().withMode(CreateMode.PERSISTENT).forPath("/root/rr", "456".getBytes());
        System.out.println(cPath2);
        String cPath3 = curator.create().withMode(CreateMode.PERSISTENT).forPath("/root/re", "789".getBytes());
        System.out.println(cPath3);

        System.out.println("===========getData==============");
        //获取节点数值
        byte[] data = curator.getData().forPath("/root/rt");
        System.out.println("数值:" + new String(data));

        System.out.println("============setData=============");
        //修改节点数据
        Stat stat = curator.setData().forPath("/root/rt", "abc".getBytes());
        System.out.println(stat);

        System.out.println("============getChildren=============");
        //获取子节点
        List<String> childPath = curator.getChildren().forPath("/root");
        for (String path : childPath) {
            System.out.println(path + ":" + new String(curator.getData().forPath("/root/" + path)));
        }

        System.out.println("============Detele=============");
        //删除节点
        curator.delete().forPath("/root/rt");
        System.out.println("是否存在:" + curator.checkExists().forPath("/root/rt"));
        curator.delete().deletingChildrenIfNeeded().forPath("/root");
        System.out.println("是否存在:" + curator.checkExists().forPath("/root"));

        curator.close();      //关闭

    }
}

log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration monitorInterval="1800">

    <Filter type="ThresholdFilter" level="trace"/>

      <Appenders>
          <Console name="console" target="SYSTEM_OUT">
            <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
        </Console>
      </Appenders>
      <Loggers>
        <Root level="WARN">
            <!-- TRACE < DEBUG < INFO < WARN < ERROR < FATAL
            -->
            <AppenderRef ref="console"/>
        </Root>
      </Loggers>
</Configuration>

结果:

STARTED
============Create=============
MainThread:main
>>>>>>>>>>>>>>>>>>>>>>>
Code:0
Name:/root/rt
Path:/root/rt
Type:CREATE
CurrentThread:main-EventThread
<<<<<<<<<<<<<<<<<<<<<<<
null
/root/rr
/root/re
===========getData==============
数值:123
============setData=============
51539607575,51539607578,1502067208571,1502067210604,1,0,0,0,3,0,51539607575

============getChildren=============
rr:456
rt:abc
re:789
============Detele=============
是否存在:null
是否存在:null

关于代码也没啥可解释的,顾名思义。

比如creatingParentsIfNeeded(),就是如果需要的话就创建父节点,这个方法的好处是可以递归创建节点。

inBackground(new BackgroundCallback(){})这个就是异步创建节点啦,不阻塞线程。

更多内容以后再说。

时间: 2024-10-01 07:05:57

Zookeeper客户端Curator---Getting Started的相关文章

第三章 zookeeper客户端-curator详解

一.简介 Curator是Netflix公司开源的一套zookeeper客户端框架. Curator包含了几个包: curator-framework:对zookeeper的底层api的一些封装 curator-client:提供一些客户端的操作,例如重试策略等 curator-recipes:封装了一些高级特性,如:Cache事件监听.选举.分布式锁.分布式计数器.分布式Barrier等. 我们需要根据ZK的版本来选择对应的curator版本,否则会出现兼容性问题 二.环境 jdk 1.8 z

Zookeeper客户端Curator基本API

在使用zookeper的时候一般不使用原生的API,Curator,解决了很多Zookeeper客户端非常底层的细节开发工作,包括连接重连.反复注册Watcher和NodeExistsException异常等等. Curator包含了几个包: curator-framework:对zookeeper的底层api的一些封装 curator-client:提供一些客户端的操作,例如重试策略等 curator-recipes:封装了一些高级特性,如:Cache事件监听.选举.分布式锁.分布式计数器.分

zookeeper开源客户端curator

zookeeper的原生api相对来说比较繁琐,比如:对节点添加监听事件,当监听触发后,我们需要再次手动添加监听,否则监听只生效一次:再比如,断线重连也需要我们手动代码来判断处理等等.对于curator的介绍,从网上百度了一段:Curator是Netflix开源的一套zookeeper客户端框架,用它来操作zookeeper更加方便,按Curator官方所比喻的,guava to JAVA,curator to zookeeper,Curator采用了fluent风格的代码,非常简洁. ----

八:Zookeeper开源客户端Curator的api测试

curator是Netflix公司开源的一套ZooKeeper客户端,Curator解决了很多ZooKeeper客户端非常底层的细节开发工作.包括连接重连,反复注册Watcher等.实现了Fluent风格的API接口,目前已经为Apache的顶级项目,是全世界使用最广泛的ZooKeeper客户端之一 第一:maven依赖 1 <dependency> 2 <groupId>org.apache.curator</groupId> 3 <artifactId>

Zookeeper开源客户端Curator之基本功能讲解

简介 Curator是Netflix公司开源的一套Zookeeper客户端框架.了解过Zookeeper原生API都会清楚其复杂度.Curator帮助我们在其基础上进行封装.实现一些开发细节,包括接连重连.反复注册Watcher和NodeExistsException等.目前已经作为Apache的顶级项目出现,是最流行的Zookeeper客户端之一.从编码风格上来讲,它提供了基于Fluent的编程风格支持. 除此之外,Curator还提供了Zookeeper的各种应用场景:Recipe.共享锁服

ZooKeeper与Curator注册和监控

Curator提供了对zookeeper客户端的封装,并监控连接状态和会话session,特别是会话session过期后,curator能够重新连接zookeeper,并且创建一个新的session. 对于zk的使用者来说,session的概念至关重要,如果想了解更多session的说明,请访问:http://zookeeper.apache.org/doc/trunk/zookeeperProgrammers.html zk客户端和zk服务器间主要可能存在下面几种异常情况: 1.     短暂

Zookeeper客户端对比选择_4

Zookeeper客户端对比选择 本文思维导图 使用框架的好处是自带一套实用的API,但是Zookeeper虽然非常强大,但是社区却安静的可怕,版本更新较慢,下面会先从zookeeper原生API的不足说起,然后引出现在流行的开源客户端工具. 1.原生API 1.创建连接的时候是异步的,所以我们在开发的时候需要人工的写代码等待创建节点的状态,如果需要的话. 2.连接时无超时重连机制.本人觉得这个非常重要,因为在现实使用中,网络是不可信的,在创建节点的时候要考虑到网络的不稳定性.因此,超时重连机制

zookeeper客户端

session会话机制 client请求和服务端建立连接,服务端会保留和标记当前client的session,包含session过期时间,sessionId,然后服务端开始在session过期时间的基础上倒计时,在这段时间内,client需要向server发送心跳包,目的是然server重置session过期时间 使用quit命令,退出可端,但是server端的session不会立即消失,使用ls / 依然可以看到创建的临时节点 节点的类型: 持久节点,不加任何参数,默认创建的是持久节点 临时节

ZooKeeper客户端原生API的使用以及ZkClient第三方API的使用

这两部分内容的介绍主要讲的是节点及节点内容和子节点的操作,并且讲解的节点的事件监听以及ACL授权 ZooKeeper客户端原生API的使用 百度网盘地址: http://pan.baidu.com/s/1jI3b8n8 ZkClient第三方API的使用 ZkClient是Github上一个开源的ZooKeeper客户端.ZkClient在ZooKeeper原生API之上进行了包装,是一个更加易用的ZooKeeper客户端.同时ZkClient在内部实现了诸如Session超时重连.Watche