首页 > 编程语言 >记录java中zookeeper客户端ZkClient一个小坑

记录java中zookeeper客户端ZkClient一个小坑

时间:2023-07-24 16:55:08浏览次数:43  
标签:NODE java String zookeeper zkClient ZkClient PATH 节点

项目中使用org.I0Itec.zkclient.ZkClient库作为zookeeper的连接工具,一直很稳定。不过有个奇怪的问题,从ZooInspetor中连接Zookeeper,看NodeData,会发现数据像图中这样,字符串前面有一段奇怪的字符:

一直不清楚"t%"这些像乱码一样的字符是什么东西。因为项目运行的比较稳定,也没报错,就一直没管。

最近涉及到跨语言,要使用Golang去连接相同的zookeeper,就有问题了。去研究了一下,倒是比较容易找到原因。下面是示例代码:

import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.serialize.SerializableSerializer;

public class ZooKeeperClient {

    private static final String ZOOKEEPER_SERVER = "localhost:2181";
    private static final String NODE_PATH = "/example_node";

    public static void main(String[] args) {
        // 创建一个 ZkClient 实例
        ZkClient zkClient = new ZkClient(ZOOKEEPER_SERVER);
    // 默认数据编码为 SerializableSerializer
    // zkClient.setZkSerializer(new BytesPushThroughSerializer());
    // 写入节点数据
        zkClient.writeData(NODE_PATH, "Hello, ZooKeeper!");
        // 读取节点数据
        String nodeData = zkClient.readData(NODE_PATH);
        System.out.println("节点数据:" + nodeData);
        // 注册节点数据监听器
        zkClient.subscribeDataChanges(NODE_PATH, new IZkDataListener() {
            @Override
            public void handleDataChange(String dataPath, Object data) throws Exception {
                System.out.println("节点数据变化:" + data);
            }
            @Override
            public void handleDataDeleted(String dataPath) throws Exception {
                System.out.println("节点数据被删除");
            }
        });
        // 修改节点数据,触发数据变化事件
        zkClient.writeData(NODE_PATH, "Updated data");
        // 等待一段时间,观察数据变化事件
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 删除节点
        zkClient.delete(NODE_PATH);
        // 关闭 ZkClient
        zkClient.close();
    }
}

问题就出在"默认数据编码为 SerializableSerializer"这里了。查看ZkCLient构造方法的源码:

 

new ZkClient(ZOOKEEPER_SERVER)构造的zk客户端,默认的使用的序列化策略为SerializableSerializer,它用于将节点数据以 Java 的序列化方式进行编码和解码。所以才导致了使用工具查看节点时,发现节点数据前面带有一段意义不明的字符串。

我的解决方法是:

1.zkClient.setZkSerializer(new BytesPushThroughSerializer());
2.zkClient.writeData(NODE_PATH, "Hello, ZooKeeper!".getBytes("UTF-8"));
3.String nodeData = new String(zkClient.readData(NODE_PATH), "UTF-8");

BytesPushThroughSerializer的实现也很简单,它直接将字节数组作为节点数据进行写入和读取,不做任何序列化和反序列化操作。如何有自定义的要求也可以自定义实现自己的 ZkSerializer 接口,根据具体需求选择适合的编码方式。至此问题解决

 

标签:NODE,java,String,zookeeper,zkClient,ZkClient,PATH,节点
From: https://www.cnblogs.com/feng-gamer/p/17577673.html

相关文章

  • 【idea编译问题】可以找打对应的class 但是 idea 提示 java: 找不到符号
    可以找打对应的class但是idea提示java:找不到符号这个问题有的时候,可能是lombock引起的,可以在maven编译的时候填写-Djps.track.ap.dependencies=false......
  • 一次Java垃圾收集调优实战
    1资料JDK5.0垃圾收集优化之--Don'tPause(花钱的年华) 编写对GC友好,又不泄漏的代码(花钱的年华) JVM调优总结 JDK6所有选项及默认值 2GC日志打印 GC调优是个很实验很伽利略的活儿,GC日志是先决的数据参考和最终验证:-XX:+PrintGCDetails-XX:+PrintGCTimeStamps(GC发生的......
  • JavaScript基础-数组(进阶)
    扩展运算符letarr1=[1,2],arr2=[3,4];letarr3=arr1.concat(arr2);letarr4=[...arr1,...arr2]console.log(arr4);用concat 连接然后...展开letarr1=[1,2];letarr2=[...arr1]console.log(arr1,arr2);把arr1的值传给arr2,输出[1,2][1,2]......
  • 【后端面经-Java】String与StringBuffer与StringBuilder的比较
    目录1.String2.StringBuffer3.StringBuilder4.性能提升5.总结和比较面试模拟参考资料1.String不可变查看String源码如下:publicfinalclassStringimplementsjava.io.Serializable,Comparable<String>,CharSequence{/**Thevalueisusedforcharacterstora......
  • Java基础--2021Java面试题系列教程--大白话解读
    前言序言再高大上的框架,也需要扎实的基础才能玩转,高频面试问题更是基础中的高频实战要点。适合阅读人群Java学习者和爱好者,有一定工作经验的技术人,准面试官等。阅读建议本教程是系列教程,包含Java基础,JVM,容器,多线程,反射,异常,网络,对象拷贝,JavaWeb,设计模式,Spring-SpringMVC,SpringB......
  • zookeeper部署
    下载官网路径:https://dlcdn.apache.org/zookeeper/单机部署#解压tar-zxfapache-zookeeper-3.8.1.tar.gz#进入配置文件目录cdapache-zookeeper-3.8.1/conf#拷贝模板文件cp-azoo_sample.cfgzoo.cfg#编辑文件vimzoo.cfg    tickTime=2000    initL......
  • javaScript 小知识
    ??运算符只有前面的值是undefined才会执行letstatus=undefined;lettext=status??"暂无"console.log(text)//暂无?.运算符这在有时候处理对象时非常有用,看下面案例,person.name返回undefined然后在调用toString这时肯定会报错,这时使用?.运算符就不会产生错误,?.......
  • java8 时间相关工具介绍
    System.currentTimeMillis()(java.util包下)Date表示当前日期和时间的日期对象Calendar日历TimeZone该类表示时区偏移量SimpleDateFormat格式化Date,建议使用jdk8后的DateTimeFormatter(java.time包下)TemporalUnit时间单位这个概念,这个是个接口,唯一的实现是枚举类ChronoUnitTemp......
  • 中文同义词库java
    中文同义词库Java在自然语言处理领域,同义词是指在语义上具有相似或相同意义的词语。使用同义词可以帮助我们对文本进行更准确的分析和理解。为了方便开发者进行中文文本处理,我们可以利用中文同义词库来实现同义词替换、文本相似度计算等功能。本文将介绍如何使用Java编程语言来......
  • 怎么找java项目日志输出的路径
    项目方案:Java项目日志输出路径的查找方法背景在Java项目开发过程中,日志是非常重要的一部分,可以帮助开发人员快速定位和解决问题。日志输出路径的查找方法决定了我们在开发和调试过程中如何查看和分析日志信息。本方案将介绍如何找到Java项目日志输出的路径,并提供代码示例。解决......