Zookeeper 叢集管理應用

來源:互聯網
上載者:User
使用情境

整個系統中分master和server兩種角色,每個master、server都需要知道叢集內當前可用的server列表。

原處理方式:master負責叢集server資訊的收集和分發。server啟動後和master建立長串連並心跳檢測,master收集server的新增和disconnect,並將收集到的資訊分發給所有server。

原存在問題:master和server耦合較重;master比較難擴充。

使用方式概述

每個server對應一個Zookeeper的一個子節點,所有master和push通過擷取所有子節點取得server列表,當server disconnect時Zookeeper通知所有機器重新擷取Server列表。

詳細

根節點路勁:/service/serverlist

1.初始化Zookeeper串連

publicstatic void initZk() {        try{            #####初始化,如果當前有alive的zk串連就不初始化了            if(zk == null|| !zk.getState().isAlive()) {                synchronized(obj) {                    if(zk == null|| !zk.getState().isAlive()) {                        ###把之前的close掉                        closeZk();                        PropertyReader p = newPropertyReader(ZK_PROPERTIES_FILE);                        String zkServerStr = p.getValueAsString("zookeeper.server", ZK_SERVER_STR_DEFAULT);                        intsessionTimeout = p.getValueAsInt("zookeeper.sessionTimeout", ZK_SESSION_TIMEOUT);                        ###重建立立串連                        zk = newZooKeeper(zkServerStr, sessionTimeout,newDefaultWatcher());                    }                }            }        }catch(Exception e) {            thrownew RuntimeException("Zookeeper Init Error!", e);        }    }

2.server在啟動時添加代表自己的臨時節點並watch其父節點

####如果之前myNodeName已經存在,則刪除ZkUtils.deleteNode(myNodeName);####先看看父節點有沒有,沒有就建立下,父節點得是持久的ZkUtils.createNode(rootNode,CreateMode.PERSISTENT);####添加對父節點child變動的watcherZkUtils.addChildWatch(rootNode,ServerListWatcher.getInstance());###建立自己的節點mynodeZkUtils.createNode(myNodeName,CreateMode.EPHEMERAL);

3.master在啟動時watch父節點

####先看看父節點有沒有,沒有就建立下,父節點得是持久的ZkUtils.createNode(rootNode,CreateMode.PERSISTENT);####添加對父節點child變動的watcherZkUtils.addChildWatch(rootNode,ServerListWatcher.getInstance());

4.監聽該父節點的child變化並處理

publicvoid process(WatchedEvent event) {        try{            ###如果是expired,需要重新初始化一遍            if(event.getState() == KeeperState.Expired) {                while(true) {                    try{                        // 重新初始化zk串連                        ZkUtils.initZk();                        // 重新初始化相關zk節點                        PushZkUtils.initPushZkNodes();                        // 擷取nodeList                        getAndSaveNodeList();                        // 如果成功,則break;                        break;                    }catch(RuntimeException e) {                        AsyncLogger.getInstance().info(LogManager.SERVICE_LOG,"ServerListWatcher:Init Error!");                        // 5s後重新執行                        Thread.sleep(5* 1000);                    }                }            }            ###如果是斷開重連,需要重新擷取下list,以免丟失事件            if(event.getState() == KeeperState.SyncConnected) {                getAndSaveNodeList();            }            ###如果是child變化,及PushServer列表有變,則擷取列表,儲存本地            if(event.getType() == EventType.NodeChildrenChanged) {                AsyncLogger.getInstance().info(LogManager.SERVICE_LOG,"ServerListWatcher:Node Child Changed Event Received");                // 儲存到本地,等待同步線程檢查                getAndSaveNodeList();            }        }catch(Exception e) {        }    }

注意事項watcher的使用

1.watcher分類

watcher主要有以下添加方式,不同添加方式監控不同的動作。( 設定watcher時,如果對應服務端已經不存在node,watcher是不會留在服務端)

###擷取節點資料,第一個方法中watch=true代表使用zookeeper建立時傳入的預設watcher,監控動作sets data on the node, or deletes the node.publicbyte[] getData(String path, booleanwatch, Stat stat)publicbyte[] getData(finalString path, Watcher watcher, Stat stat) ###判斷節點是否存在,第一個方法中watch=true代表使用zookeeper建立時傳入的預設watcher,監控動作creates/delete the node or sets  the data on the node.publicStat exists(finalString path, Watcher watcher)publicStat exists(String path, booleanwatch)###擷取節點child,第一個方法中watch=true代表使用zookeeper建立時傳入的預設watcher,監控動作deletes the node of the given path or creates/delete a child under the nodepublicList<String> getChildren(finalString path, Watcher watcher)publicList<String> getChildren(String path, booleanwatch)

2.watcher的使用注意

下面幾個點需要在使用的時候多加註意

  • watcher是一次性的,每次處理事件之後需要重新加上。在處理和重新加上的間隔之間事件變化無法得知。

     

    ###擷取的時候把watcher重新加一次List<String> nodes = ZkUtils.getChildren(ZkUtils.ZK_PUSH_SERVER_LIST_ROOT_NODE,ServerListWatcher.getInstance()); 
  • 用戶端與zookeeper Disconnect時發生的事件可能會丟失。

     

    ###如果是斷開重連,需要重新擷取下list,以免丟失事件            if(event.getState() == KeeperState.SyncConnected) {                getAndSaveNodeList();            }
  • 如果session到期,所有watcher就木有了。

     

    if(event.getState() == KeeperState.Expired) {                while(true) {                    try{                        // 重新初始化zk串連                        ZkUtils.initZk();                        // 重新初始化相關zk節點                        PushZkUtils.initPushZkNodes();                        // 擷取nodeList                        getAndSaveNodeList();                        // 如果成功,則break;                        break;                    }catch(RuntimeException e) {                        AsyncLogger.getInstance().info(LogManager.SERVICE_LOG,"ServerListWatcher:Init Error!");                        // 5s後重新執行                        Thread.sleep(5*1000);                    }                }
CONNECTIONLOSS和SESSIONEXPIRED

因為網路環境等原因,這兩個異常還是會時不時出現一下,需要對這些情況有所考慮。

ConnectionLoss表示認為該串連不可用,zk的java client會自動拿著當前的sessionId去其他的zkServer建立串連。

如果在SessionTimeout的時間之內重建立立串連成功,則一切恢複正常,臨時節點和watcher不會發生丟失。

如果在SessionTimeout時間之後才串連上zkServer,則zkServer會返回Session Expired,這個時候前一個session不可用,臨時節點和watcher丟失,需要手動去沖新進行初始化。

ps:Zk執行個體化的時候會傳入一個SessionTimeOut的參數,zk服務端在接收到這個參數後會和本地配置minSessionTimeout(預設2*tickTime)和maxSessionTimeout(預設20*tickTime)進行比較並進行截取。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.