Java操作zookeeper

Posted Firm陈

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java操作zookeeper相关的知识,希望对你有一定的参考价值。

一、Curator介绍

curator是Apache Zookeeper的java客户端库。它的目标是简化Zookeeper客户端的使用,最初是Netfix研发,后来捐给了Apache基金会,目前是Apache的顶级项目。
有兴趣的话可以看看curator的官网:http://curator.apache.org/

二、API常用操作


注意:以下的所有代码都是在同一个测试类CuratorTest中编写!

1.建立、关闭连接

	private CuratorFramework client;
	
    public CuratorFramework getClient()
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 10);
//        CuratorFramework client = CuratorFrameworkFactory.newClient("122.36.96.113:2181", 60 * 1000,
//                15 * 1000, retryPolicy);
        CuratorFramework client = CuratorFrameworkFactory.builder().connectString("122.36.96.113:2181")
                .sessionTimeoutMs(60 * 1000)
                .connectionTimeoutMs(15 * 1000)
                .retryPolicy(retryPolicy)
                .namespace("luzelong") //指定操作的根目录
                .build();
        return client;
    

    /**
     * 建立连接
     * @Before:在所有Test方法调用前都会执行的方法
     */
    @Before
    public void testConnect()
        client = getClient();
        client.start();
    
    
    /**
     * 关闭连接
     * @After:在所有Test方法调用后都会执行的方法
     */
    @After
    public void close()
        if (client != null) 
            client.close();
        
    

2.创建节点

    @Test
    public void createTest() throws Exception 
        //由于client设置了namespace为luzelong,所以节点会创建在 /luzelong 下面

        //1.基本创建 : 如果创建节点,没有指定数据,则默认将当前客户端的ip作为数据存储
        String path1 = client.create().forPath("/app1");
        //2.创建交接点带有数据
        String path2 = client.create().forPath("/app2","hhhh".getBytes());
        //3.设置节点的类型 , 下面的案例是创建临时节点
        String path3 = client.create().withMode(CreateMode.EPHEMERAL).forPath("/app3","hhhh".getBytes());
        //4.创建多级节点  /app4/p1
        String path4 = client.create().creatingParentsIfNeeded().forPath("/app4/p1");

    

3.查询节点

    @Test
    public void testGet() throws Exception 
        //1.查询数据: get
        byte[] bytes = client.getData().forPath("/app1");
        System.out.println(new String(bytes));

        //2.查询子节点: ls
        List<String> strings = client.getChildren().forPath("/app4");
        System.out.println(strings);

        //3.查询节点状态: ls -s
        Stat stat = new Stat();
        client.getData().storingStatIn(stat).forPath("/app4/p1");
        System.out.println(stat);

    

4.修改节点数据

    @Test
    public void testSet() throws Exception 
        //1.修改数据
        client.setData().forPath("/app1","jjy".getBytes());

        //2.根据版本修改(需要先查询版本号,CAS思想)
        Stat stat = new Stat();
        client.getData().storingStatIn(stat).forPath("/app2");
        int version = stat.getVersion();
        client.setData().withVersion(version).forPath("/app2","yy".getBytes());
    

5.删除节点

    @Test
    public void testDel() throws Exception 
        //1.删除叶子节点  delete
        client.delete().forPath("/app1");

        //2.删除非叶子节点: deleteall
        client.delete().deletingChildrenIfNeeded().forPath("/app4");

        //3.必须成功删除
        client.delete().guaranteed().forPath("/app1");

        //4.带回调的删除
        client.delete().inBackground(new BackgroundCallback() 
            @Override
            public void processResult(CuratorFramework curatorFramework, CuratorEvent curatorEvent) throws Exception 
                System.out.println("我被删除了,curatorEvent="+curatorEvent);
            
        ).forPath("/app1");
    

三、Watch事件监听

ZooKeeper允许用户在指定节点上注册一些Watcher,并且在一些特定事件触发的时候,ZooKeeper服务端会将事件通知到感兴趣的客户端上去,该机制是ZooKeeper实现分布式协调服务的重要特性。
ZooKeeper中引入了Watcher机制来实现了发布/订阅功能能,能够让多个订阅者同时监听某一个对象,当一个对象自身状态变化时,会通知所有订阅者。
Curator引入了Cache来实现对ZooKeeper服务端事件的监听。
zooKeeper提供了三种Watcher:
NodeCache:只是监听某一个特定的节
PathChildrenCache:监控一个ZNode的子节点.
TreeCache:可以监控整个树上的所有节点,类似于PathChildrenCache和NodeCache的组合。

1.NodeCache

    @Test
    public void testNodeCache() throws Exception 
        //1.创建NodeCache对象
        final NodeCache nodeCache = new NodeCache(client,"/app2");

        //2.注册监听
        nodeCache.getListenable().addListener(new NodeCacheListener() 
            @Override
            public void nodeChanged() throws Exception 
                System.out.println("节点变化了~~~");
                byte[] data = nodeCache.getCurrentData().getData();
                System.out.println("监修改节点后的数据为: " + new String(data));
            
        );

        //3.开启监听,如果设置为true,则开启监听加载缓存数据
        nodeCache.start(true);

        while (true)
    

运行上面的代码,由于最后一行是个死循环所以程序会一直等待!这个时候其他客户端 修改|删除|创建这个节点,控制台就会执行监听事件中的方法!
如下就是利用zkCli.sh工具来模拟另一个客户端的操作行为:


2.PathChildrenCache

 	/**
     * 演示 pathChildrenCache:监听某个节点的所有子节点们(不会监听自己)
     */
    @Test
    public void testPathChildren() throws Exception 
        //1.创建监听对象
        PathChildrenCache pathChildrenCache = new PathChildrenCache(client,"/app2",true);
        //2.绑定监听器
        pathChildrenCache.getListenable().addListener(new PathChildrenCacheListener() 
            @Override
            public void childEvent(CuratorFramework curatorFramework, PathChildrenCacheEvent pathChildrenCacheEvent) throws Exception 
                System.out.println("子节点变化了~~~~");
                System.out.println(pathChildrenCacheEvent);
                
                //监听子节点的数据变更,并且拿到变更后的数据
                //1.获取类型
                PathChildrenCacheEvent.Type type = pathChildrenCacheEvent.getType();
                //2.判断类型是否是update
                if (type.equals(PathChildrenCacheEvent.Type.CHILD_UPDATED)) 
                    byte[] data = pathChildrenCacheEvent.getData().getData();
                    System.out.println("修改后子节点的数据为:" + new String(data));
                
            
        );
        //3.开启监听
        pathChildrenCache.start();

        while (true)
    

运行上面的代码,由于最后一行是个死循环所以程序会一直等待!这个时候其他客户端在监听的节点下创建一个新的节点,控制台就会执行监听方法:
如下就是利用zkCli.sh工具来模拟另一个客户端的操作行为:


3.TreeCache

    /**
     * 演示TreeCache:监听某个节点自己和所有子节点们
     */
    @Test
    public void testTreeCache() throws Exception 
        //1.创建监听对象
        TreeCache treeCache = new TreeCache(client,"/app2");

        //2.注册监听
        treeCache.getListenable().addListener(new TreeCacheListener()
            @Override
            public void childEvent(CuratorFramework curatorFramework, TreeCacheEvent treeCacheEvent) throws Exception 
                System.out.println("节点变化了~~");
                System.out.println(treeCacheEvent);
            
        );

        //3.开启
        treeCache.start();
        while (true)
    

具体的演示和上面的两个基本一样,它不仅监听自己还监听它的子节点,相当于是上面两种Cache的并集

四、POM.xml文件参考

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>curator-zk</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>4.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>4.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.36</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.19</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

以上是关于Java操作zookeeper的主要内容,如果未能解决你的问题,请参考以下文章

java中操作zookeeper,curator操作zookeeper

java操作zookeeper

Zookeeper客户端java代码操作

Java 中zookeeper操作

Java代码操作zookeeper

Java API操作ZooKeeper