Java 操作zk

    xiaoxiao2022-07-12  137

    一、节点操作

    4 种 持久和临时 无序和有序

    1.1持久化节点

    public static void createPersistent() { if(!zkClient.exists("/java")) { String create = zkClient.create("/java", "java", CreateMode.PERSISTENT); System.out.println(create); } if(zkClient.exists("/java/io/inputstream/fileInputstream")) { // NoNode , 这个低估创建是自己实现的算法 zkClient.createPersistent("/java/io/inputstream/fileInputstream", true); // 这个使用最多,它可以递归创建节点,zookeeper 原生不支持递归创建 } } /** * 创建一个持久的顺序节点 */ public static void createPerSeq() { // zk 不支持创建同名的节点 // /java0000000004 /java0000000005 /java0000000006 // String create = zkClient.create("/java", "java", CreateMode.PERSISTENT_SEQUENTIAL); String create = zkClient.createPersistentSequential("/java", "java"); // 快捷创建节点 System.out.println(create); }

    1.2创建临时节点

    若创建它的客户端断开连接后(和zkServer 断开),则节点会自动删除

    /** * 临时节点,若创建它的客户端断开连接,则自动死掉 * 使用多一点 */ public static void createEm() { zkClient.createEphemeral("/test"); try { System.out.println("挂起jvm,线程在此一致等待"); System.in.read(); } catch (IOException e) { e.printStackTrace(); } // zkClient.close(); } // 创建一个临时的顺序节点 使用少 public static void createEmSeq() { zkClient.createEphemeralSequential("/test1", "test"); }

    1.3订阅子节点的改变(重要)

    /** * 订阅节点的改变(重要) */ public static void subScribe() { zkClient.subscribeChildChanges("/com.sxt.AddService", new IZkChildListener() { /** * 若该父节点的字节有变化,则会执行该方法 */ @Override public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception { System.out.println(parentPath+",下的字节点有变化"); System.out.println("当前最新的子节点为"+currentChilds); } }); System.out.println("开始监听"); try { System.in.read(); } catch (IOException e) { e.printStackTrace(); } }

    1.4其他的订阅操作

    public static void otherSub() { // zkClient.subscribeStateChanges(new IZkStateListener() { // // @Override // public void handleStateChanged(KeeperState state) throws Exception { // System.out.println("当前状态为"+state); // } // // @Override // public void handleSessionEstablishmentError(Throwable error) throws Exception { // System.out.println("写数据的异常"+error); // 写数据和时有异常会监听到 // } // // @Override // public void handleNewSession() throws Exception { // System.out.println("新连接"); // 触发条件是在一个客户端里面 // } // });// 订阅服务器的状态改变(zkServer状态的改变,服务器死机了,启动) zkClient.subscribeDataChanges("/java", new IZkDataListener() { // 该监听针对的是自己(客户端)内部数据改变 @Override public void handleDataDeleted(String dataPath) throws Exception { System.out.println(dataPath); } @Override public void handleDataChange(String dataPath, Object data) throws Exception { System.out.println(dataPath+":::"+data); } }); // 订阅节点数据改变的通知 System.out.println("开始监听"); try { System.in.read(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }

    1.5修改节点的数据

    /** * 给节点写数据 */ public static void changeData() { zkClient.writeData("/java", "23456"); }

    二、注册中心

    2.1 服务提供者启动->注册自己

    2.2 服务消费者调用->获取服务列表

    2.3 性能问题

    服务消费者每次调用时,都有从zk 上获取一次数据

    在高并发调用,每次去获取远程的服务列表,是个性能问题 若每次拉取服务要2 s -0s 远程需要1 s =3s->1s

    2.4 缓存的思想

    查询数据:管理员的菜单

    2.4 缓存的脏读

    缓存里面的时间和数据源里面的数据不一致导致 Eg: 现在有个服务挂了,zk 上会自动删除它,但是缓存列表里面还有它

    若:zk 上节点有变化,能修改我的缓存(订阅的功能)

    /** * 1 第一次从zk 上面拉取 ? * 2 拉取之后保存起来 * 3 以后的获取数据都从缓存里面找 * * @param serverName * @return */ public static List<String>fetchServerListCache(String serverName){ if(serverList.containsKey(serverName)) { // 代表之前获取过该服务的列表 System.out.println("从缓存里面获取"); List<String> list = serverList.get(serverName); return list; } List<String> fetchServerList = fetchServerList(serverName); //不包含,说明之前没有拉取过,我先拉取到,保存起来 serverList.put(serverName, fetchServerList); // 拉取成功后,我开始关注这个节点,若该节点有变化,我修改缓存里面的数据 zkClient.subscribeChildChanges("/"+serverName, new IZkChildListener() { @Override public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception { System.out.println("有服务死机或上线,需要更新服务的列表"); System.out.println("缓存里面的服务列表为"+serverList.get(serverName)); System.out.println("最新的为"+currentChilds); System.out.println("开始更新"); serverList.put(serverName, currentChilds); System.out.println("修改成功"); } }); return fetchServerList; }
    最新回复(0)