閱讀307 返回首頁    go 阿裏雲 go 技術社區[雲棲]


跟著實例學習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();

            //https://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);
        }

    }

}

最後更新:2017-05-23 10:32:09

  上一篇:go  Disruptor 2.0更新摘要
  下一篇:go  跟著實例學習ZooKeeper的用法: Curator框架應用