1. 程式人生 > >centOS7.0上安裝使用zookeeper環境

centOS7.0上安裝使用zookeeper環境

一、安裝jdk

首先zookeeper是java編寫的,需要安裝jdk,方法有3種,(以下操作來自:http://www.linuxidc.com/Linux/2016-09/134941.htm)

方法一:手動解壓JDK的壓縮包,然後設定環境變數

1.在/usr/目錄下建立java目錄

[[email protected] ~]# mkdir/usr/java
[[email protected] ~]# cd /usr/java

2.下載jdk,然後解壓

[[email protected] java]# curl -O http://download.Oracle.com/otn-pub/java/jdk/7u79-b15/jdk-7u79-linux-x64.tar.gz 
[

[email protected] java]# tar -zxvf jdk-7u79-linux-x64.tar.gz

3.設定環境變數

[[email protected] java]# vi /etc/profile

在profile中新增如下內容:

#set java environment
JAVA_HOME=/usr/java/jdk1.7.0_79
JRE_HOME=/usr/java/jdk1.7.0_79/jre
CLASS_PATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
export JAVA_HOME JRE_HOME CLASS_PATH PATH

讓修改生效:

[[email protected] java]# source /etc/profile

4.驗證JDK有效性

[[email protected] java]# java -version
java version "1.7.0_79"
Java(TM) SE Runtime Environment (build 1.7.0_79-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.79-b02, mixed mode)

方法二:用yum安裝JDK

1.檢視yum庫中都有哪些jdk版本(暫時只發現了openjdk)

[[email protected] ~]# yum search java|grep jdk
ldapjdk-javadoc.x86_64 : Javadoc for ldapjdk
java-1.6.0-openjdk.x86_64 : OpenJDK Runtime Environment
java-1.6.0-openjdk-demo.x86_64 : OpenJDK Demos
java-1.6.0-openjdk-devel.x86_64 : OpenJDK Development Environment
java-1.6.0-openjdk-javadoc.x86_64 : OpenJDK API Documentation
java-1.6.0-openjdk-src.x86_64 : OpenJDK Source Bundle
java-1.7.0-openjdk.x86_64 : OpenJDK Runtime Environment
java-1.7.0-openjdk-demo.x86_64 : OpenJDK Demos
java-1.7.0-openjdk-devel.x86_64 : OpenJDK Development Environment
java-1.7.0-openjdk-javadoc.noarch : OpenJDK API Documentation
java-1.7.0-openjdk-src.x86_64 : OpenJDK Source Bundle
java-1.8.0-openjdk.x86_64 : OpenJDK Runtime Environment
java-1.8.0-openjdk-demo.x86_64 : OpenJDK Demos
java-1.8.0-openjdk-devel.x86_64 : OpenJDK Development Environment
java-1.8.0-openjdk-headless.x86_64 : OpenJDK Runtime Environment
java-1.8.0-openjdk-javadoc.noarch : OpenJDK API Documentation
java-1.8.0-openjdk-src.x86_64 : OpenJDK Source Bundle
ldapjdk.x86_64 : The Mozilla LDAP Java SDK

2.選擇版本,進行安裝

//選擇1.7版本進行安裝
[[email protected] ~]# yum install java-1.7.0-openjdk
//安裝完之後,預設的安裝目錄是在: /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.75.x86_64

3.設定環境變數

[[email protected] ~]# vi /etc/profile

在profile檔案中新增如下內容

#set java environment
JAVA_HOME=/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.75.x86_64
JRE_HOME=$JAVA_HOME/jre
CLASS_PATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
export JAVA_HOME JRE_HOME CLASS_PATH PATH

讓修改生效

[[email protected] java]# source /etc/profile

4.驗證(同上一方法)

方法三:用rpm安裝JDK

1.下載rpm安裝檔案

[[email protected] ~]$ curl -O http://download.oracle.com/otn-pub/java/jdk/7u79-b15/jdk-7u79-linux-x64.rpm

2.使用rpm命令安裝

[[email protected]  ~]# rpm -ivh jdk-7u79-linux-x64.rpm

3.設定環境變數

[[email protected] java]# vi /etc/profile

在開啟的profile檔案中新增如下內容

#set java environment
JAVA_HOME=/usr/java/jdk1.7.0_79
JRE_HOME=/usr/java/jdk1.7.0_79/jre
CLASS_PATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
export JAVA_HOME JRE_HOME CLASS_PATH PATH

讓修改生效

[[email protected] java]# source /etc/profile

4.驗證(同上一方法)

注:和yum安裝類似,不用設定環境變數就可以執行java命令。rpm安裝方式預設會把jdk安裝到/usr/java/jdk1.7.0_79,然後通過三層連結,連結到/usr/bin,具體連結如下:

[[email protected] ~]# cd /bin
[[email protected] bin]# ll|grep java
lrwxrwxrwx. 1 root root    25 Mar 28 11:24 jar ->/usr/java/default/bin/jar
lrwxrwxrwx. 1 root root    26 Mar 28 11:24 java -> /usr/java/default/bin/java
lrwxrwxrwx. 1 root root    27 Mar 28 11:24 javac ->/usr/java/default/bin/javac
lrwxrwxrwx. 1 root root    29 Mar 28 11:24 javadoc ->/usr/java/default/bin/javadoc
lrwxrwxrwx. 1 root root    28 Mar 28 11:24 javaws ->/usr/java/default/bin/javaws
lrwxrwxrwx. 1 root root    30 Mar 28 11:24 jcontrol ->/usr/java/default/bin/jcontrol
[[email protected] bin]# cd /usr/java/
[[email protected] java]# ll
total 4
lrwxrwxrwx. 1 root root  16 Mar 28 11:24 default-> /usr/java/latest
drwxr-xr-x. 8 root root 4096 Mar 28 11:24 jdk1.7.0_79
lrwxrwxrwx. 1 root root  21 Mar 28 11:24 latest -> /usr/java/jdk1.7.0_79

方法四:Ubuntu 上使用apt-get安裝JDK

1.檢視apt庫都有哪些jdk版本

[email protected]:~# apt-cache search java|grep jdk
default-jdk - Standard Java or Java compatible Development Kit
default-jdk-doc - Standard Java or Java compatible Development Kit (documentation)
gcj-4.6-jdk - gcj and classpath development tools for Java(TM)
gcj-jdk - gcj and classpath development tools for Java(TM)
openjdk-6-dbg - Java runtime based on OpenJDK (debugging symbols)
openjdk-6-demo - Java runtime based on OpenJDK (demos and examples)
openjdk-6-doc - OpenJDK Development Kit (JDK) documentation
openjdk-6-jdk - OpenJDK Development Kit (JDK)
openjdk-6-jre-lib - OpenJDK Java runtime (architecture independent libraries)
openjdk-6-source - OpenJDK Development Kit (JDK) source files
openjdk-7-dbg - Java runtime based on OpenJDK (debugging symbols)
openjdk-7-demo - Java runtime based on OpenJDK (demos and examples)
openjdk-7-doc - OpenJDK Development Kit (JDK) documentation
openjdk-7-jdk - OpenJDK Development Kit (JDK)
openjdk-7-source - OpenJDK Development Kit (JDK) source files
uwsgi-plugin-jvm-openjdk-6 - Java plugin for uWSGI (OpenJDK 6)
uwsgi-plugin-jwsgi-openjdk-6 - JWSGI plugin for uWSGI (OpenJDK 6)
openjdk-6-jre - OpenJDK Java runtime, using Hotspot JIT
openjdk-6-jre-headless - OpenJDK Java runtime, using Hotspot JIT (headless)
openjdk-7-jre - OpenJDK Java runtime, using Hotspot JIT
openjdk-7-jre-headless - OpenJDK Java runtime, using Hotspot JIT (headless)
openjdk-7-jre-lib - OpenJDK Java runtime (architecture independent libraries)

2.選擇版本進行安裝

[email protected]:~# apt-get install openjdk-7-jdk

3.設定環境變數

[email protected]:~# vi /etc/profile

在開啟的profile檔案中新增如下內容

#set java environment
JAVA_HOME=/usr/lib/jvm/java-1.7.0-openjdk-amd64
JRE_HOME=$JAVA_HOME/jre
CLASS_PATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
export JAVA_HOME JRE_HOME CLASS_PATH PATH

讓修改生效

[email protected]:~# source /etc/profile

4.驗證(同上一方法)

二、安裝zookeeper

zookeeper有3種使用方法:叢集模式、偽叢集模式、單機模式。以下以偽叢集模式為例(來自:http://blog.csdn.net/catoop/article/details/50848555)

叢集部署

1. 下載

2. 安裝

因為資源有限,所以我在同一個伺服器上面建立3個目錄 server1、server2、server3 來模擬3臺伺服器叢集。 
cd server1 
tar -zxvf zookeeper-3.4.8.tar.gz 
mkdir data 
mkdir dataLog 
data 為資料目錄,dataLog 為日誌目錄。

3. 配置

cd zookeeper-3.4.8/conf 
建立檔案 zoo.cfg,內容如下:

tickTime=2000 
initLimit=5
syncLimit=2
dataDir=/opt/zookeeper/server1/data
dataLogDir=/opt/zookeeper/server1/dataLog
clientPort=2181
server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

tickTime:zookeeper中使用的基本時間單位, 毫秒值。 
initLimit:這個配置項是用來配置 Zookeeper 接受客戶端(這裡所說的客戶端不是使用者連線 Zookeeper 伺服器的客戶端,而是 Zookeeper 伺服器叢集中連線到 Leader 的 Follower 伺服器)初始化連線時最長能忍受多少個 tickTime 時間間隔數。這裡設定為5表名最長容忍時間為 5 * 2000 = 10 秒。 
syncLimit:這個配置標識 Leader 與 Follower 之間傳送訊息,請求和應答時間長度,最長不能超過多少個 tickTime 的時間長度,總的時間長度就是 2 * 2000 = 4 秒。 
dataDir 和 dataLogDir 看配置就知道幹嗎的了,不用解釋。 
clientPort:監聽client連線的埠號,這裡說的client就是連線到Zookeeper的程式碼程式。 
server.{myid}={ip}:{leader伺服器交換資訊的埠}:{當leader伺服器掛了後, 選舉leader的埠} 
maxClientCnxns:對於一個客戶端的連線數限制,預設是60,這在大部分時候是足夠了。但是在我們實際使用中發現,在測試環境經常超過這個數,經過調查發現有的團隊將幾十個應用全部部署到一臺機器上,以方便測試,於是這個數字就超過了。

修改zoo.cfg非常簡單,然後還需要建立myid檔案: 
cd server1/data
echo 1 > myid

然後拷貝server1為server2和server3,並修改其中的zoo.cfg配置,當然也要修改myid的內容為2和3。

下面給出3個server的zoo.cfg 內容:

# server1
tickTime=2000
initLimit=5
syncLimit=2
dataDir=/opt/zookeeper/server1/data
dataLogDir=/opt/zookeeper/server1/dataLog
clientPort=2181
server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
# server2
tickTime=2000
initLimit=5
syncLimit=2
dataDir=/opt/zookeeper/server2/data
dataLogDir=/opt/zookeeper/server2/dataLog
clientPort=2182
server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
# server3
tickTime=2000
initLimit=5
syncLimit=2
dataDir=/opt/zookeeper/server3/data
dataLogDir=/opt/zookeeper/server3/dataLog
clientPort=2183
server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

這裡做下說明:因為我們是在同一個機器上模擬的叢集,所以要注意server埠號和clientPort不要重複了,不然會出現埠衝突。所以,如果我們是3個不同的機器上做的3個server,那麼我們的zoo.cfg配置都是一樣的(注意server.{myid}=後面的IP地址使用具體的IP地址,如192.168.0.88)。還有就是,每一個server的myid內容都不能一樣,這也可以理解為不同server的標識。

4. 啟動

進入 zookeeper-3.4.8/bin 目錄,使用 ./zkServer.sh start 啟動zk服務。(你也可以使用 ./zkServer.sh start myzoo.cfg 指定配置檔案啟動,這在自動化運維的時候很有用) 
使用 tail -f zookeeper.out 檢視日誌。 
要說的是:在啟動第一個的時候,日誌中會出現一堆錯誤,仔細一看就能明白,是因為另外2個server還沒有啟動它連線不上的錯誤。然後當我們啟動第二個server的時候,日誌中的錯誤將會減少。最後我們把所有server都啟動起來後,日誌中便沒有錯誤了。

5. 測試

隨便進入一個zk目錄,連線一個server測試。 
cd zookeeper-3.4.8/bin 
./zkCli.sh -server 127.0.0.1:2181 
如果你要連線別的伺服器,請指定具體的IP地址。

幾個基本命令說明: 
ls 檢視指定節點中包含的子節點(如:ls / 或 ls /app1/server1) 
create 建立節點並賦值 
get 讀取節點內容 
set 改變節點內容 
delete 刪除節點 
注意zk中所有節點都基於路徑確定,如你要刪除 /app1/server1/nodeA 的命令為: 
delete /app1/server1/nodeA

下面是基本操作截圖: 
這裡寫圖片描述

Java程式Demo

建立一個Maven工程 
開啟pom.xml檔案新增zookeeper依賴

        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.6</version>
        </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

建立Demo.java,程式碼如下:

package com.shanhy.demo.zookeeper;

import java.io.IOException;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;

/**
 * Zookeeper測試
 *
 * @create    2016年3月10日
 */
public class Test {

    // 會話超時時間,設定為與系統預設時間一致
    private static final int SESSION_TIMEOUT = 30 * 1000;

    // 建立 ZooKeeper 例項
    private ZooKeeper zk;

    // 建立 Watcher 例項
    private Watcher wh = new Watcher() {
        /**
         * Watched事件
         */
        public void process(WatchedEvent event) {
            System.out.println("WatchedEvent >>> " + event.toString());
        }
    };

    // 初始化 ZooKeeper 例項
    private void createZKInstance() throws IOException {
        // 連線到ZK服務,多個可以用逗號分割寫
        zk = new ZooKeeper("192.168.19.130:2181,192.168.19.130:2182,192.168.19.130:2183", Test.SESSION_TIMEOUT, this.wh);

    }

    private void ZKOperations() throws IOException, InterruptedException, KeeperException {
        System.out.println("\n1. 建立 ZooKeeper 節點 (znode : zoo2, 資料: myData2 ,許可權: OPEN_ACL_UNSAFE ,節點型別: Persistent");
        zk.create("/zoo2", "myData2".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

        System.out.println("\n2. 檢視是否建立成功: ");
        System.out.println(new String(zk.getData("/zoo2", this.wh, null)));// 新增Watch

        // 前面一行我們添加了對/zoo2節點的監視,所以這裡對/zoo2進行修改的時候,會觸發Watch事件。
        System.out.println("\n3. 修改節點資料 ");
        zk.setData("/zoo2", "shanhy20160310".getBytes(), -1);

        // 這裡再次進行修改,則不會觸發Watch事件,這就是我們驗證ZK的一個特性“一次性觸發”,也就是說設定一次監視,只會對下次操作起一次作用。
        System.out.println("\n3-1. 再次修改節點資料 ");
        zk.setData("/zoo2", "shanhy20160310-ABCD".getBytes(), -1);

        System.out.println("\n4. 檢視是否修改成功: ");
        System.out.println(new String(zk.getData("/zoo2", false, null)));

        System.out.println("\n5. 刪除節點 ");
        zk.delete("/zoo2", -1);

        System.out.println("\n6. 檢視節點是否被刪除: ");
        System.out.println(" 節點狀態: [" + zk.exists("/zoo2", false) + "]");
    }

    private void ZKClose() throws InterruptedException {
        zk.close();
    }

    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
        Test dm = new Test();
        dm.createZKInstance();
        dm.ZKOperations();
        dm.ZKClose();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77

我想程式碼不用解釋了,該註釋的裡面都註釋了。

下面有一種特殊的情況的處理思路: 
有server1、server2、server3這三個服務,在client去連線zk的時候,指向server1初始化的過程中是沒有問題的,然而剛剛初始化完成,準備去連線server1的時候,server1因為網路等原因掛掉了。 
然而對client來說,它會拿server1的配置去請求連線,這時肯定會報連線被拒絕的異常以致啟動退出。 
所以優雅的解決這個問題的方法思路就是“在連線的時候判斷連線狀態,如果未連線成功,程式自動使用其他連線去請求連線”,這樣來避開這種罕見的異常問題。

程式碼如下:

    // 初始化 ZooKeeper 例項
    private void createZKInstance() throws IOException {
        // 連線到ZK服務,多個可以用逗號分割寫
        zk = new ZooKeeper("192.168.19.130:2181,192.168.19.130:2182,192.168.19.130:2183", Test.SESSION_TIMEOUT, this.wh);
        if(!zk.getState().equals(States.CONNECTED)){
            while(true){
                if(zk.getState().equals(States.CONNECTED)){
                    break;
                }
                try {
                    TimeUnit.SECONDS.sleep(5);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

上面的程式碼是基於zk提供的庫的API來你使用的,為了更易於使用,有人寫了開源的zkclient,我們可以直接使用它來操作zk。 
zkclient 開源地址:https://github.com/sgroschupf/zkclient 
maven 依賴配置:

        <!--zkclient -->
        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.7</version>
        </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

zkClient 針對 zk 的一次性watcher,做了重新封裝,然後定義了 stateChanged、znodeChanged、dataChanged 三種監聽器。

  1. 監聽children變化
  2. 監聽節點資料變化
  3. 監聽連線狀態變化

程式碼如下:

package com.shanhy.demo.zookeeper;

import java.util.List;
import java.util.concurrent.TimeUnit;

import org.I0Itec.zkclient.DataUpdater;
import org.I0Itec.zkclient.IZkChildListener;
import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.IZkStateListener;
import org.I0Itec.zkclient.ZkClient;
import org.apache.zookeeper.Watcher.Event.KeeperState;

/**
 * ZkClient的使用測試
 *
 * @author   單紅宇(365384722)
 * @myblog  http://blog.csdn.net/catoop/
 * @create    2016年3月11日
 */
public class ZkClientTest {

    public static void main(String[] args) {
        ZkClient zkClient = new ZkClient("192.168.19.130:2181,192.168.19.130:2182,192.168.19.130:2183");
        String node = "/myapp";

        // 訂閱監聽事件
        childChangesListener(zkClient, node);
        dataChangesListener(zkClient, node);
        stateChangesListener(zkClient);

        if (!zkClient.exists(node)) {
            zkClient.createPersistent(node, "hello zookeeper");
        }
        System.out.println(zkClient.readData(node));

        zkClient.updateDataSerialized(node, new DataUpdater<String>() {

            public String update(String currentData) {
                return currentData + "-123";
            }
        });
        System.out.println(zkClient.readData(node));

        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 訂閱children變化
     *
     * @param zkClient
     * @param path
     * @author SHANHY
     * @create  2016年3月11日
     */
    public static void childChangesListener(ZkClient zkClient, final String path) {
        zkClient.subscribeChildChanges(path, new IZkChildListener() {

            public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception {
                System.out.println("clildren of path " + parentPath + ":" + currentChilds);
            }

        });
    }

    /**
     * 訂閱節點資料變化
     *
     * @param zkClient
     * @param path
     * @author SHANHY
     * @create  2016年3月11日
     */
    public static void dataChangesListener(ZkClient zkClient, final String path){
        zkClient.subscribeDataChanges(path, new IZkDataListener(){

            public void handleDataChange(String dataPath, Object data) throws Exception {
                System.out.println("Data of " + dataPath + " has changed.");
            }

            public void handleDataDeleted(String dataPath) throws Exception {
                System.out.println("Data of " + dataPath + " has changed.");
            }

        });
    }

    /**
     * 訂閱狀態變化
     *
     * @param zkClient
     * @author SHANHY
     * @create  2016年3月11日
     */
    public static void stateChangesListener(ZkClient zkClient){
        zkClient.subscribeStateChanges(new IZkStateListener() {

            public void handleStateChanged(KeeperState state) throws Exception {
                System.out.println("handleStateChanged");
            }

            public void handleSessionEstablishmentError(Throwable error) throws Exception {
                System.out.println("handleSessionEstablishmentError");
            }

            public void handleNewSession() throws Exception {
                System.out.println("handleNewSession");
            }
        });
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116

ZkClient 做了便捷的包裝,對Watch做了增強處理。 
subscribeChildChanges實際上是通過exists和getChildren關注了兩個事件。這樣當create(“/path”)時,對應path上通過getChildren註冊的listener也會被呼叫。另外subscribeDataChanges實際上只是通過exists註冊了事件。因為從上表可以看到,對於一個更新,通過exists和getData註冊的watcher要麼都會觸發,要麼都不會觸發。

關於session超時的問題,ZkClient 貌似還是有對 Session Expired 處理的,在ZkClient.processStateChanged方法中。雖然能重新連線,但是連線上是一個新的 session,原有建立的ephemeral znode和watch會被刪除,程式上你可能需要處理這個問題。

最後說幾點關於ZkClient的注意事項: 
1. 建立節點的時候一定要先判斷節點是否存在,如果直接使用zkclient建立一個已經存在的節點,則會丟擲異常。 
2. 使用zkclient建立節點的時候,path描述的路徑,預新增的最終節點之前的所有父節點都必須要存在,否則會丟擲異常。所以根據自己需要做好處理。


相關推薦

centOS7.0安裝使用zookeeper環境

一、安裝jdk 首先zookeeper是java編寫的,需要安裝jdk,方法有3種,(以下操作來自:http://www.linuxidc.com/Linux/2016-09/134941.htm) 方法一:手動解壓JDK的壓縮包,然後設定環境變數 1.在/usr/目

CentOS7.0安裝Python3.6.1

python3.6.1 python3安裝 python安裝報錯 剛開始研究python,一直在糾結是學2.0還是3.0,聽說2.0版本將在2020年後被淘汰,於是就有了安裝3.0的需求。 本次安裝的python版本為:Python-3.6.1.tgz 操作系統信息:Linux cento

Centos7.0安裝Vertica9.1.1

Centos7.0上安裝Vertica9.1.1 1. 主機環境準備 IP 主機名 伺服器配置 Swap分割槽 檔案系統 磁碟大小 掛載點 OS

CentOS7.0安裝mysql重置root密碼

本人在CentOS7.0上安裝mysql後,無法通過root進入,因為安裝的時候,並沒有設定root密碼,似乎有個初始隨機密碼,但是不記得了,太麻煩,直接重置root密碼。    使用rpm包安裝完mysql後,按照一下步驟重置root密碼:    啟動mysql: #/e

CentOS7 安裝 Zookeeper-3.4.9 服務

sin cal 永久 int mit apache small www cti 在 CentOS7 上安裝 zookeeper-3.4.9 服務 1、創建 /usr/local/services/zookeeper 文件夾: mkdir -p /usr/local

Linux(centOS7.0)虛擬機環境安裝JDK1.8

rep csdn 完成 安裝jdk 1.7 頂部 安裝包 centos7 tps 閱讀目錄 1.檢查系統是否安裝了JDK 2.準備工作 3.配置環境變量 4.驗證是否安裝成功 回到頂部 1.檢查系統是否安裝了JDK   1.打開SecureCRT終端,輸入:jav

CentOS7 安裝 zookeeper-3.5.2 服務

stand enable pan ble imu alpha 日誌文件 logs req 1 [root@centos-linux src]# pwd 2 /usr/local/src 3 4 # 1、創建 /usr/local/src/zookeep

OpenStack教程-02.在CentOS7.5安裝OpenStack-Rocky-系統環境準備-計算節點(其他節點相同)

pen lis cli baseurl make 防火 計算 === 系統 上一篇文章介紹了openstack控制節點的環境配置方法,本篇文章分享一下openstack計算節點的環境配置方法,其他種類節點也基本適用 附:openstack控制節點系統環境配制方法:http

centos7.3部署zookeeper叢集環境

一、前期準備 1、下載zookeeper安裝包 zookeeper官方下載地址:http://www-eu.apache.org/dist/zookeeper/ zookeeper-3.5.3-beta.tar.gz 2、準備好要安裝的叢集環境的目標機器 3、將下載好的壓縮包拷貝

CentOS7 安裝 Zookeeper-3.4.10 服務

 1、建立 /usr/local/services/zookeeper 資料夾:     mkdir -p /usr/local/services/zookeeper   2、進入到 /usr/local/services/zookeeper 目錄中:     cd /usr/local/services/z

Centos7.0安裝jdk和tomcat以及環境配置

進入你的tomcat安裝目錄下的bin檔案[[email protected] ~]# cd java/apache-tomcat-9.0.0.M4/bin/ 然後啟動tomcat [[email protected] bin]# ./startup.sh Using CATALINA_B

CentOS7 安裝 Zookeeper-3.4.12

 1、建立 /usr/local/services/zookeeper 資料夾:    mkdir -p /usr/local/services/zookeeper2、進入到 /usr/local/services/zookeeper 目錄中:    cd /usr/loca

CentOS7.4安裝docker-compose環境

單機環境下,使用docker-compose編排容器最簡單。一 安裝Centos7.4 -----省略二 使用overlayfs2.1 檢查核心是否載入overlayfslsmod | grep overlay沒有任何輸出,說明核心沒有載入overlayfs2.2 核心載入o

centos7.2安裝python3和pip19.0.3

lin net 超鏈接 err edi com ldd grep centos 安裝libressl 下載地址: https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-2.7.4.tar.gz 或者 :https:/

CentOS7.0 搭建 Chroot 的 Bind DNS 服務器

n) 地址 授權 dns 部分 soa 自啟 named 就會 BIND(Berkeley internet Name Daemon)也叫做NAMED,是現今互聯網上使用最為廣泛的DNS 服務器程序。這篇文章將要講述如何在 chroot 監牢中運行 BIND,這樣它就無法訪

【CNMP系列】CentOS7.0安裝Nginx服務

系統資源 for proxy input strong network emc -c .com 話步前言,CNMP之路,系統起步:http://www.cnblogs.com/riverdubu/p/6425028.html 這回我來講解下CentOS7.0下如何安裝和配置

安裝和配置Storm環境第一步 安裝zookeeper環境 (一)

同步 自己 個數 get 5-0 安裝和配置 錯誤 resolve num 1.安裝配置Zookeeper 2.Storm的核心配置文件 $STORM_HOME/conf/storm.yaml 3.註意:如果要搭建Storm的HA(高可用性),nimbus即可. 4.把配

RHEL7.3系統安裝docker環境及docker的簡單使用

訪問 vim build info 環境 version .html 查看 hub 為RHEL7和Centos7上安裝epel源和docker源以及安裝和檢查 命令安裝 yum -y install epel-release 手動安裝 wget http://

centos7.0編譯安裝python3.6.2

python一、查看Linux系統版本信息[[email protected]/* */ ~]# cat /etc/redhat-release CentOS Linux release 7.0.1406 (Core) [[email protected]/* */ ~]# uname

docker centos7 容器安裝ssh

docker centos7 ssh在容器上執行 yum install passwd openssl openssh-server -y ssh-keygen -q -t rsa -b 2048 -f /etc/ssh/ssh_host_rsa_key -N ‘‘ ssh-keygen -q -t ec