如何获取zookeeper中的注册内容,在Java项目中演示

news/2025/2/26 6:14:41

我来为你展示如何在Java项目中通过ZooKeeper获取已注册的内容。下面提供一个完整的示例,包括连接ZooKeeper、获取节点数据以及处理常见情况的代码。


示例代码

以下代码演示了如何从ZooKeeper中获取注册内容:

java">import org.apache.zookeeper.*;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.CountDownLatch;

public class ZookeeperGetContentExample {
    private static final String ZK_CONNECT_STRING = "localhost:2181"; // ZooKeeper地址
    private static final int SESSION_TIMEOUT = 5000; // 会话超时时间(ms)
    private static ZooKeeper zooKeeper;
    private static final CountDownLatch connectedSignal = new CountDownLatch(1);

    public static void main(String[] args) {
        try {
            // 建立连接
            connectToZookeeper();

            // 示例路径
            String path = "/my-service";

            // 获取单个节点内容
            getNodeContent(path);

            // 获取子节点列表
            getChildren(path);

            // 关闭连接
            zooKeeper.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 连接ZooKeeper
    private static void connectToZookeeper() throws IOException {
        zooKeeper = new ZooKeeper(ZK_CONNECT_STRING, SESSION_TIMEOUT, new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                if (event.getState() == Event.KeeperState.SyncConnected) {
                    connectedSignal.countDown();
                    System.out.println("成功连接到ZooKeeper");
                }
            }
        });

        try {
            connectedSignal.await(); // 等待连接成功
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    // 获取节点内容
    private static void getNodeContent(String path) throws KeeperException, InterruptedException {
        if (zooKeeper.exists(path, false) != null) {
            // 获取节点数据
            byte[] data = zooKeeper.getData(path, false, null);
            String content = data != null ? new String(data) : "无数据";
            System.out.println("路径 " + path + " 的内容: " + content);

            // 获取节点Stat信息(可选)
            Stat stat = new Stat();
            zooKeeper.getData(path, false, stat);
            System.out.println("节点版本: " + stat.getVersion());
            System.out.println("创建时间: " + stat.getCtime());
        } else {
            System.out.println("路径 " + path + " 不存在");
        }
    }

    // 获取子节点列表
    private static void getChildren(String path) throws KeeperException, InterruptedException {
        if (zooKeeper.exists(path, false) != null) {
            List<String> children = zooKeeper.getChildren(path, false);
            if (children.isEmpty()) {
                System.out.println("路径 " + path + " 下没有子节点");
            } else {
                System.out.println("路径 " + path + " 的子节点: " + children);
                // 遍历子节点并获取内容
                for (String child : children) {
                    String childPath = path + (path.equals("/") ? "" : "/") + child;
                    getNodeContent(childPath);
                }
            }
        } else {
            System.out.println("路径 " + path + " 不存在");
        }
    }
}

代码说明

  1. 依赖配置
    在Maven项目中,确保已添加ZooKeeper依赖(和之前注册示例相同):

    <dependency>
        <groupId>org.apache.zookeeper</groupId>
        <artifactId>zookeeper</artifactId>
        <version>3.8.4</version>
    </dependency>
    
  2. 主要功能

    • connectToZookeeper():建立与ZooKeeper的连接,使用CountDownLatch确保连接成功后再执行后续操作。
    • getNodeContent():获取指定路径的节点数据,并可选地获取节点的元信息(如版本号、创建时间等)。
    • getChildren():获取指定路径下的子节点列表,并递归获取每个子节点的内容。
  3. 关键API

    • zooKeeper.getData(path, watch, stat)
      • path:目标节点路径。
      • watch:是否设置监视器(这里设为false,表示不监听变化)。
      • stat:返回节点的元信息(如版本号、时间戳等)。
      • 返回值:节点的字节数组数据。
    • zooKeeper.getChildren(path, watch)
      • 返回指定路径下的子节点名称列表。
    • zooKeeper.exists(path, watch)
      • 检查节点是否存在,避免操作不存在的节点时抛出异常。
  4. 运行前提

    • ZooKeeper服务已启动并运行在localhost:2181(或修改为你实际的地址)。
    • 路径/my-service已有数据(可以通过之前的注册示例创建)。

输出示例

假设/my-service节点已注册内容"service-data", 并有一个子节点/my-service/child1包含"child-data",运行程序可能输出:

成功连接到ZooKeeper
路径 /my-service 的内容: service-data
节点版本: 0
创建时间: 1677654321000
路径 /my-service 的子节点: [child1]
路径 /my-service/child1 的内容: child-data
节点版本: 0
创建时间: 1677654322000

扩展功能

  1. 监听节点变化
    如果需要实时感知节点内容的变化,可以添加Watcher:

    java">byte[] data = zooKeeper.getData(path, new Watcher() {
        @Override
        public void process(WatchedEvent event) {
            System.out.println("节点 " + event.getPath() + " 发生变化,类型: " + event.getType());
            try {
                getNodeContent(path); // 再次获取最新数据
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }, null);
    
  2. 异常处理
    添加更健壮的错误处理:

    java">try {
        getNodeContent(path);
    } catch (KeeperException.NoNodeException e) {
        System.out.println("节点不存在: " + path);
    } catch (KeeperException.ConnectionLossException e) {
        System.out.println("连接丢失,重试中...");
        // 实现重试逻辑
    }
    
  3. 服务发现场景
    在实际应用中,可以用此方法实现服务发现:

    java">String servicePath = "/services/service1";
    getNodeContent(servicePath); // 获取服务注册信息,如IP和端口
    

注意事项

  • 权限控制:如果节点设置了ACL(如ZooDefs.Ids.CREATOR_ALL_ACL),需要在客户端添加认证信息:
    java">zooKeeper.addAuthInfo("digest", "username:password".getBytes());
    
  • 性能考虑:频繁获取大数据或深层子节点可能影响性能,建议根据需求优化调用频率。
  • 连接管理:生产环境中应实现连接池或重试机制,避免连接断开导致失败。


http://www.niftyadmin.cn/n/5868163.html

相关文章

smolagents学习笔记系列(六)Secure code execution

这篇文章锁定官网教程 Secure code execution 章节的内容&#xff0c;主要介绍了smolagents是如何安全地执行LLM的输出结果。 官网链接&#xff1a;https://huggingface.co/docs/smolagents/v1.9.2/en/tutorials/secure_code_execution 为了不浪费你的时间&#xff0c;下面这…

JAVAweb之过滤器,监听器

文章目录 过滤器认识生命周期FilterConfigFilterChain过滤器执行顺序应用场景代码 监听器认识ServletContextListenerHttpSessionListenerServletRequestListener代码 过滤器 认识 Java web三大组件之一&#xff0c;与Servlet相似。过滤器是用来拦截请求的&#xff0c;而非处…

python绑定udp时使用127.0.0.1作为ip,无法sendto,报错Invalid argument

在 Python 中使用 UDP 套接字进行通信时&#xff0c;绑定127.0.0.1作为 IP 地址后无法使用sendto方法发送数据&#xff0c;可能由多种原因导致 这里是其中一个原因&#xff1a; 127.0.0.1 是本地回环地址&#xff0c;只能用于本机内部的进程间通信&#xff0c; 如果你绑定到 …

《OpenCV》—— 背景建模

背景建模是什么&#xff1f; 背景建模的意义&#xff1f; 通过背景建模&#xff0c;我们可以实现很多应用&#xff0c;例如运动检测、目标跟踪 背景建模的方法 帧差法 帧差法的原理 基于 K 近邻的前景分割算法&#xff08;KNN&#xff09; 原理 基于 K 近邻的前景分割算法…

pytest下放pytest.ini文件就导致报错:ERROR: file or directory not found: #

pytest下放pytest.ini文件就导致报错&#xff1a;ERROR: file or directory not found: # 如下&#xff1a; 项目文件目录如下&#xff1a; pytest.ini文件内容&#xff1a; [pytest] addopts -v -s --alluredir ./allure-results # 自动添加的命令行参数&#xff1a;# -…

【利用conda配置管理Python版本和依赖环境】

1. 创建新的Python环境 # conda create -n [虚拟环境名] python[python指定的版本] # -y直接安装不用询问&#xff0c;没有时&#xff0c;会提示询问等待用户确定才安装 conda create -n pygnu python3.10 -y验证并检查新建的Python环境 conda activate pygun python --versi…

uni-app 开发 App 、 H5 横屏签名(基于lime-signature)

所用插件&#xff1a;lime-signature 使用到 CSS 特性 绝对定位transform 旋转transform-origin transform 原点 复习一下定位元素&#xff08;相对定位、绝对定位、粘性定位&#xff09; 代码# <template><view class"signature-page"><view clas…

Java多线程中的死锁问题

1.什么是死锁 线程在获取资源的时候&#xff0c;由于获取不到&#xff0c;导致线程卡死&#xff08;阻塞&#xff09;&#xff0c;程序就不执行了。 2.发生死锁的情况 1.一个线程获取一把锁 一个线程如果同时获取一把锁两次&#xff0c;如果是可重入锁&#xff0c;就没有问…