一.部署zookeeper集羣
zookeeper是一個針對大型分佈式系統的協調系統,提供的功能有統一名稱服務、分佈式同步等。
1.上傳zk安裝包
2.解壓 tar -xzvf zookeeper-3.4.6.tar.gz -C app/
3.配置(先在一臺節點上配置)
3.1添加一個zoo.cfg配置文件
進入配置文件目錄: cd /home/koushengrui/app/zookeeper-3.4.6/conf/
複製現有的配置文件模板,並命名爲zoo.cfg:cp zoo_sample.cfg zoo.cfg
3.2修改配置文件(zoo.cfg)
dataDir=/home/koushengrui/app/zookeeper-3.4.6/data
server.1=server1:2888:3888
server.2=server2:2888:3888
server.3=server3:2888:3888
其中2888是leader與follower通信的端口,3888是選舉通信的端口。
3.3在dataDir目錄中創建一個myid文件,裏面內容是server.N中的N(server.2裏面內容爲2)
echo "1" > myid
3.4將配置好的zk拷貝到其他節點
scp -r /home/koushengrui/app/zookeeper-3.4.6 server2:/home/koushengrui/app/ ,這裏不要加sudo
scp -r /home/koushengrui/app/zookeeper-3.4.6 server3:/home/koushengrui/app/
3.5注意:在其他節點上一定要修改myid的內容
在server2應該將myid的內容改爲2 (echo "2" > myid)
在server3應該講myid的內容改爲3 (echo "3" > myid)
4.啓動集羣
分別啓動zk
./zkServer.sh start
這個時候若嚴格按照上面步驟部署,且已經關閉防火牆的話(很重要,在防火牆這裏喫過大虧,如何關閉centos7的防火牆在之前博客有細講),則zookeeper應該已經正常啓動起來了,用下面命令看各節點的身份(是leader還是follower):
./zkServer.sh status
二.ZooKeeper簡單API的使用
zookeeper的每個節點稱爲znode,znode除了本身能夠包含一部分數據外,還能擁有子節點。znode的數據主要是協調的數據,如狀態、配置等信息,當znode的數據發生變化或者子節點發生變化時,基於Watcher機制,會發出相應的通知給訂閱其狀態變化的客戶端。
ZooKeeper有4個構造器:
ZooKeeper(String connectString, int sessionTimeout, Watcher watcher)
ZooKeeper(String connectString, int sessionTimeout, Watcher watcher, boolean canBeReadOnly)
ZooKeeper(String connectString, int sessionTimeout, Watcher watcher, long sessionId, byte[] sessionPasswd)
ZooKeeper(String connectString, int sessionTimeout, Watcher watcher, long sessionId, byte[] sessionPasswd, boolean canBeReadOnly)
可見,最簡單的是第一種,要傳3個參數。
如:
ZooKeeper zk = new ZooKeeper("192.168.2.128:2181,192.168.2.129:2181,192.168.2.130:2181", 2000, null);
第一個參數是zookeeper服務器的地址,ip:port形式,port是在zoo.cfg中配置的,默認是2181,比較推薦的做法是傳入zookeeper集羣中所有節點的地址以逗號拼成的字符串,如192.168.2.128:2181,192.168.2.129:2181,192.168.2.130:2181。因爲如果只寫單個節點的地址,如192.168.2.128:2181,萬一該節點剛好掉線了的話,之後調用zookeeper實例的方法時就會報錯。第二個參數是會話超時時間,以毫秒爲單位,超過了這個時間還沒有連上zookeeper集羣的話就會報錯,注意不能傳0。第三個參數是Watcher實例(Watcher是個接口,只有一個process(WatchedEvent
event)方法,需要我們寫一個Watcher接口的實現類,匿名類也可以),如果不爲null的話,則之後調用byte[] getData(String path, boolean watch, Stat stat)或者getChildren(String path, boolean watch)方法時,如果第二個傳入的是true,則就會將此Watcher實例註冊爲監聽。
注意ZooKeeper的Watcher是一次性的,主要觸發了,watcer就不再監聽了,要想繼續監聽,需要重新做註冊,可以在process()方法中註冊監聽,這樣在觸發了watcher之後又立刻註冊監聽,就可以達到一直監聽的目的。
示例:
public class TestCyclicWatcher {
static ZooKeeper zk = null;
static String path = "/test";
static {
try {
zk = new ZooKeeper("192.168.153.128:2181", 5000, new Watcher() {
public void process(WatchedEvent event) {
try {
zk.getData(path, true, null);
if (event.getType() != EventType.None) {
System.out.println(event.getPath());
System.out.println(event.getType());
System.out.println(event.getState());
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
System.out.println(new String(zk.getData(path, true, null)));
Thread.sleep(Integer.MAX_VALUE);
}
}