CuratorFramework节点监听二 TreeCache

本文介绍了CuratorFramework的TreeCache如何实现永久监听指定节点及子节点的变化,包括创建、数据变更、删除等事件。通过详细步骤阐述了设置监听器的方法,并给出了与Spring集成的配置建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

节点监听

2.TreeCache

特点:

(1)永久监听指定节点下的节点的变化
(2)可以监听到指定节点下所有节点的变化,比如说指定节点”/example”, 在下面添加”node1”可以监听到,但是添加”node1/n1”也能被监听到
(3)可以监听到的事件:节点创建、节点数据的变化、节点删除等

使用方式:

(1)创建curatorframework的client
(2)添加TreeCache
(3)启动client 和 TreeCache
(4)注册监听器

例子

package cache;

import com.google.common.collect.Lists;
import discovery.ExampleServer;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.TreeCache;
import org.apache.curator.framework.recipes.cache.TreeCacheEvent;
import org.apache.curator.framework.recipes.cache.TreeCacheListener;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.test.TestingServer;
import org.apache.curator.utils.CloseableUtils;
import org.apache.curator.utils.ZKPaths;
import org.apache.zookeeper.KeeperException;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;

/**
 * Created by yanan.sun on 16-10-19.
 */
@Component
public class TreeCacheExample {
    private static final String PATH = "/mq_monitor";
    private static final TestingServer server = buildTestServer();
    private static CuratorFramework client = CuratorFrameworkFactory.newClient("192.168.27.55:2181", new ExponentialBackoffRetry(1000, 3));
    private static TreeCache treeCache = new TreeCache(client, PATH);
    private static TestingServer buildTestServer() {
        try {
            return new TestingServer();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        start();
        try {
            processCommands(client, treeCache);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void start() {
        try {
            client.start();
            treeCache.start();
        }catch (Exception e){
            System.out.println("error occurs");
        }
    }

    private static void addListener(TreeCache cache) {
        // a PathChildrenCacheListener is optional. Here, it's used just to log changes
        TreeCacheListener treeCacheListener = new TreeCacheListener() {
            @Override
            public void childEvent(CuratorFramework client, TreeCacheEvent event) throws Exception {
                switch (event.getType()) {
                    case NODE_ADDED:
                        System.out.println("Node add " + ZKPaths.getNodeFromPath(event.getData().getPath()));
                        break;
                    case NODE_REMOVED:
                        System.out.println("Node removed " + ZKPaths.getNodeFromPath(event.getData().getPath()));
                        break;
                    case NODE_UPDATED:
                        System.out.println("Node updated " + ZKPaths.getNodeFromPath(event.getData().getPath()));
                        break;

                }
            }
        };
        cache.getListenable().addListener(treeCacheListener);
    }

    public void destroy() {
        CloseableUtils.closeQuietly(treeCache);
        CloseableUtils.closeQuietly(client);
        CloseableUtils.closeQuietly(server);
    }

    private static void processCommands(CuratorFramework client, TreeCache cache) throws Exception {
        // More scaffolding that does a simple command line processor

        printHelp();

        List<ExampleServer> servers = Lists.newArrayList();
        try {
            addListener(cache);

            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
            boolean done = false;
            while (!done) {
                System.out.print("> ");

                String line = in.readLine();
                if (line == null) {
                    break;
                }

                String command = line.trim();
                String[] parts = command.split("\\s");
                if (parts.length == 0) {
                    continue;
                }
                String operation = parts[0];
                String args[] = Arrays.copyOfRange(parts, 1, parts.length);

                if (operation.equalsIgnoreCase("help") || operation.equalsIgnoreCase("?")) {
                    printHelp();
                } else if (operation.equalsIgnoreCase("q") || operation.equalsIgnoreCase("quit")) {
                    done = true;
                } else if (operation.equals("set")) {
                    setValue(client, command, args);
                } else if (operation.equals("remove")) {
                    remove(client, command, args);
                } else if (operation.equals("list")) {
                    //list(cache);
                }

                Thread.sleep(1000); // just to allow the console output to catch up
            }
        } finally {
            for (ExampleServer server : servers) {
                CloseableUtils.closeQuietly(server);
            }
        }
    }

 /*   private static void list(TreeCache cache, String path) {
        if (cache.getCurrentData(path) == null) {
            System.out.println("* empty *");
        } else {
            for (ChildData data : cache.getCurrentData(path)) {
                System.out.println(data.getPath() + " = " + new String(data.getData()));
            }
        }
    }*/

    private static void remove(CuratorFramework client, String command, String[] args) throws Exception {
        if (args.length != 1) {
            System.err.println("syntax error (expected remove <path>): " + command);
            return;
        }

        String name = args[0];
        /*if (name.contains("/")) {
            System.err.println("Invalid node name" + name);
            return;
        }
        String path = ZKPaths.makePath(PATH, name);*/
        String path = PATH + "/" + name;

        try {
            client.delete().forPath(path);
        } catch (KeeperException.NoNodeException e) {
            // ignore
        }
    }

    private static void setValue(CuratorFramework client, String command, String[] args) throws Exception {
        if (args.length != 2) {
            System.err.println("syntax error (expected set <path> <value>): " + command);
            return;
        }

        String name = args[0];
        /*if (name.contains("/")) {
            System.err.println("Invalid node name" + name);
            return;
        }
        String path = ZKPaths.makePath(PATH, name);*/
        String path = PATH + "/" + name;

        byte[] bytes = args[1].getBytes();
        try {
            if (client.checkExists().forPath(path) != null) {
                System.out.println("path " + path + "exist");
            } else {
                client.create().creatingParentsIfNeeded().forPath(path, bytes);
            }
//            client.setData().forPath(path, bytes);
        } catch (KeeperException.NoNodeException e) {
            // client.create().creatingParentsIfNeeded().forPath(path, bytes);
        }
    }

    private static void printHelp() {
        System.out.println("An example of using PathChildrenCache. This example is driven by entering commands at the prompt:\n");
        System.out.println("set <name> <value>: Adds or updates a node with the given name");
        System.out.println("remove <name>: Deletes the node with the given name");
        System.out.println("list: List the nodes/values in the cache");
        System.out.println("quit: Quit the example");
        System.out.println();
    }
}

依赖

<dependencies>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-client</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-framework</artifactId>
            <version>2.8.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-test</artifactId>
            <version>2.8.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-x-discovery</artifactId>
            <version>2.7.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>4.2.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.2.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.2.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>4.2.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>

扩展

如果与spring结合,希望容器启动的时候同时对节点进行监听,则可以去掉类里面的main方法,并在spring中做如下配置:

<bean id="treeCacheExample" class="cache.TreeCacheExample" init-method="start" destroy-method="destroy"></bean>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值