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(){})这个就是异步创建节点啦,不阻塞线程。

 更多内容以后再说。

 

转载于:https://www.cnblogs.com/LUA123/p/7296359.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
zookeeper-3.4.5-cdh5.16.2.tar.gz 是一个压缩文件,其中包含的是 ZooKeeper 分布式协调服务的安装包。ZooKeeper 是一个开源的分布式应用程序协调服务,它为分布式系统提供了高度可靠的协调功能。 在这个压缩文件中,"zookeeper-3.4.5" 表示 ZooKeeper 的版本号为 3.4.5,而 "cdh5.16.2" 则表示此版本是基于 Cloudera 发行版 5.16.2。Cloudera 是一个提供基于 Apache Hadoop 的大数据解决方案的公司,他们针对 ZooKeeper 进行了一些修改和适配,以便更好地与其它 Cloudera 软件产品集成。 .tar.gz 是一个常见的压缩格式,通常用于在 Linux 系统中打包和分发文件。使用该格式,文件被打包成一个.tar 文件,然后使用 gzip 压缩算法进行压缩,最终生成一个.tar.gz 文件。 为了使用这个安装包,我们可以按照以下步骤进行操作: 1. 首先,我们需要解压缩.tar.gz 文件。可以使用命令 "tar -zxvf zookeeper-3.4.5-cdh5.16.2.tar.gz" 解压缩该文件。执行完该命令后,会生成一个目录,其中包含了 ZooKeeper 安装包的所有文件。 2. 进入解压后的目录,在其中可以找到 ZooKeeper 的配置文件、示例配置文件和一些其他的脚本文件。 3. 根据自己的需求,修改配置文件。一般需要修改的配置包括 ZooKeeper 服务器集群的地址和端口,以及一些日志和存储文件的路径。 4. 配置完毕后,可以启动 ZooKeeper 服务器。通过运行脚本文件 "bin/zkServer.sh",以指定的模式(例如单机模式、主从模式等)启动服务器。 5. 一旦服务器启动,您就可以使用 ZooKeeper 客户端与其进行交互了。客户端提供了一组命令,可以帮助您管理分布式系统中的节点和数据。 总之,zookeeper-3.4.5-cdh5.16.2.tar.gz 是一个用于安装和部署 ZooKeeper 的文件压缩包,通过解压缩、配置和启动等步骤,您可以在您的分布式系统中使用 ZooKeeper 提供的协调功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值