跟着实例学习ZooKeeper的用法: 临时节点

使用Curator也可以简化Ephemeral Node (临时节点)的操作。 临时节点驻存在ZooKeeper中,当连接和session断掉时被删除。

比如通过ZooKeeper发布服务,服务启动时将自己的信息注册为临时节点,当服务断掉时ZooKeeper将此临时节点删除,这样client就不会得到服务的信息了。

PersistentEphemeralNode类代表临时节点。 通过下面的构造函数创建:

public PersistentEphemeralNode(CuratorFramework client,
                               PersistentEphemeralNode.Mode mode,
                               String basePath,                               byte[] data)

参数说明:

  • client – client instance
  • mode – creation/protection mode
  • basePath – the base path for the node
  • data – data for the node

其它参数还好理解, 不好理解的是PersistentEphemeralNode.Mode。

  • EPHEMERAL: 以ZooKeeper的 CreateMode.EPHEMERAL方式创建节点。
  • EPHEMERAL_SEQUENTIAL: 如果path已经存在,以CreateMode.EPHEMERAL创建节点,否则以CreateMode.EPHEMERAL_SEQUENTIAL方式创建节点。
  • PROTECTED_EPHEMERAL: 以CreateMode.EPHEMERAL创建,提供保护方式。
  • PROTECTED_EPHEMERAL_SEQUENTIAL: 类似EPHEMERAL_SEQUENTIAL,提供保护方式。

保护方式是指一种很边缘的情况: 当服务器将节点创建好,但是节点名还没有返回给client,这时候服务器可能崩溃了,然后此时ZK session仍然合法, 所以此临时节点不会被删除。对于client来说, 它无法知道哪个节点是它们创建的。

即使不是sequential-ephemeral,也可能服务器创建成功但是客户端由于某些原因不知道创建的节点。

Curator对这些可能无人看管的节点提供了保护机制。 这些节点创建时会加上一个GUID。 如果节点创建失败正常的重试机制会发生。 重试时, 首先搜索父path, 根据GUID搜索节点,如果找到这样的节点, 则认为这些节点是第一次尝试创建时创建成功但丢失的节点,然后返回给调用者。

节点必须调用start方法启动。 不用时调用close方法。

PersistentEphemeralNode 内部自己处理错误状态。

我们的例子创建了两个节点,一个是临时节点,一个事持久化的节点。 可以看到, client重连后临时节点不存在了。

package com.colobu.zkrecipe.node;import java.util.concurrent.TimeUnit;import org.apache.curator.framework.CuratorFramework;import org.apache.curator.framework.CuratorFrameworkFactory;import org.apache.curator.framework.recipes.nodes.PersistentEphemeralNode;import org.apache.curator.framework.recipes.nodes.PersistentEphemeralNode.Mode;import org.apache.curator.framework.state.ConnectionState;import org.apache.curator.framework.state.ConnectionStateListener;import org.apache.curator.retry.ExponentialBackoffRetry;import org.apache.curator.test.KillSession;import org.apache.curator.test.TestingServer;import org.apache.curator.utils.CloseableUtils;public class PersistentEphemeralNodeExample {    private static final String PATH = "/example/ephemeralNode";    private static final String PATH2 = "/example/node";    public static void main(String[] args) throws Exception {
        TestingServer server = new TestingServer();
        CuratorFramework client = null;
        PersistentEphemeralNode node = null;        try {
            client = CuratorFrameworkFactory.newClient(server.getConnectString(), new ExponentialBackoffRetry(1000, 3));
            client.getConnectionStateListenable().addListener(new ConnectionStateListener() {                @Override
                public void stateChanged(CuratorFramework client, ConnectionState newState) {
                    System.out.println("client state:" + newState.name());

                }
            });
            client.start();            //http://zookeeper.apache.org/doc/r3.2.2/api/org/apache/zookeeper/CreateMode.html
            node = new PersistentEphemeralNode(client, Mode.EPHEMERAL,PATH, "test".getBytes());
            node.start();
            node.waitForInitialCreate(3, TimeUnit.SECONDS);
            String actualPath = node.getActualPath();
            System.out.println("node " + actualPath + " value: " + new String(client.getData().forPath(actualPath)));

            client.create().forPath(PATH2, "persistent node".getBytes());
            System.out.println("node " + PATH2 + " value: " + new String(client.getData().forPath(PATH2)));
            KillSession.kill(client.getZookeeperClient().getZooKeeper(), server.getConnectString());
            System.out.println("node " + actualPath + " doesn't exist: " + (client.checkExists().forPath(actualPath) == null));
            System.out.println("node " + PATH2 + " value: " + new String(client.getData().forPath(PATH2)));

        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            CloseableUtils.closeQuietly(node);
            CloseableUtils.closeQuietly(client);
            CloseableUtils.closeQuietly(server);
        }

    }

}

原文发布于微信公众号 - IT技术精选文摘(ITHK01)

原文发表时间:2017-11-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏海说

基于dbunit进行mybatis DAO层Excel单元测试

DAO层测试难点 可重复性,每次运行单元测试,得到的数据是重复的 独立性,测试数据与实际数据相互独立 数据库中脏数据预处理 不能给数据库中数据带来变化 DAO层...

3690
来自专栏专注 Java 基础分享

Java--JDBC连接数据库

     我们知道Java中的jdbc是用来连接应用程序和数据系统的,本篇文章主要就来看看关于JDBC的实现和使用细节。主要包含以下几点内容: JDBC的基本知...

3305
来自专栏我和PYTHON有个约会

Django来敲门~第一部分【5.1.项目配置settings.py详解】

我们创建好了一个Python项目(mysite/)之后,需要在项目中添加模块应用(polls/),在模块应用中添加处理功能逻辑,如添加模块中的视图处理函数(po...

953
来自专栏Felix的技术分享

《一个操作系统的实现》笔记(5)--内核雏形

1824
来自专栏lgp20151222

zookeeper的简单搭建,java使用zk的例子和一些坑

由于本人的码云太多太乱了,于是决定一个一个的整合到一个springboot项目里面。

1433
来自专栏腾讯Bugly的专栏

Android GC 原理探究

作者:陈昱全 知乎主页:https://www.zhihu.com/people/chen-yu-quan 前言 想写一篇关于android GC的想法来源于追...

3958
来自专栏草根专栏

用VSCode开发一个asp.net core 2.0+angular 5项目(4): Angular5全局错误处理

angular 5 全局错误处理 参考文档: https://angular.io/api/core/ErrorHandler 首先按照文档在客户端项目建立ap...

3375
来自专栏JadePeng的技术博客

XNginx - nginx 集群可视化管理工具

之前团队的nginx管理,都是运维同学每次去修改配置文件,然后重启,非常不方便,一直想找一个可以方便管理nginx集群的工具,翻遍web,未寻到可用之物,于是自...

1.2K4
来自专栏YG小书屋

ElasticSearch 5.6源码解析HTTP/TCP请求

4563
来自专栏逆向技术

x64内核HOOK技术之拦截进程.拦截线程.拦截模块

            x64内核HOOK技术之拦截进程.拦截线程.拦截模块 一丶为什么讲解HOOK技术. 在32系统下, 例如我们要HOOK SSDT表,那么...

4747

扫码关注云+社区