【Zookeeper】zookeeper客戶端KeeperErrorCode = ConnectionLoss

九師兄發表於2020-11-19

在這裡插入圖片描述

1.概述

今天執行進去zk shell想執行一個命令,結果直接報錯

zookeeper】bin/zkCli.sh
0] ls /

然後直接報錯如下

org.apache.zookeeper.KeeperException$ConnectionLossException: KeeperErrorCode = ConnectionLoss for /
 at org.apache.zookeeper.KeeperException.create(KeeperException.java:99)
 at org.apache.zookeeper.KeeperException.create(KeeperException.java:51)
 at org.apache.zookeeper.ZooKeeper.exists(ZooKeeper.java:1045)
 at org.apache.zookeeper.ZooKeeper.exists(ZooKeeper.java:1073)
 at com.taobao.pamirs.schedule.zk.ScheduleStrategyDataManager4ZK.loadManagerFactoryInfo(ScheduleStrategyDataManager4ZK.java:295)
 at com.taobao.pamirs.schedule.strategy.TBScheduleManagerFactory.refresh(TBScheduleManagerFactory.java:164)
 at com.taobao.pamirs.schedule.strategy.ManagerFactoryTimerTask.run(TBScheduleManagerFactory.java:438)
 at java.util.TimerThread.mainLoop(Timer.java:555)
 at java.util.TimerThread.run(Timer.java:505)

2.原因

原因:

一般是由於連線還未完成就執行zookeeper的get/create/exsit操作引起的.

解決方法:

利用"CountDownLatch 類 + zookeeper的watcher + zookeeper的getStat" 實現連線完成後再呼叫.

可防止此錯誤發生.

import java.util.concurrent.CountDownLatch;  
  
  
import org.apache.zookeeper.WatchedEvent;  
import org.apache.zookeeper.Watcher;  
import org.apache.zookeeper.Watcher.Event.KeeperState;  
import org.apache.zookeeper.ZooKeeper;  
import org.apache.zookeeper.ZooKeeper.States;  
import org.apache.zookeeper.data.Stat;  
public class Conf{  
    public static void waitUntilConnected(ZooKeeper zooKeeper, CountDownLatch connectedLatch) {  
        if (States.CONNECTING == zooKeeper.getState()) {  
            try {  
                connectedLatch.await();  
            } catch (InterruptedException e) {  
                throw new IllegalStateException(e);  
            }  
        }  
    }  
   
    static class ConnectedWatcher implements Watcher {  
   
        private CountDownLatch connectedLatch;  
   
        ConnectedWatcher(CountDownLatch connectedLatch) {  
            this.connectedLatch = connectedLatch;  
        }  
   
        @Override  
        public void process(WatchedEvent event) {  
           if (event.getState() == KeeperState.SyncConnected) {  
               connectedLatch.countDown();  
           }  
        }  
    }  
    static public Conf Instance(){  
        if(static_ == null){  
            static_ = new Conf();  
        }  
        return static_;  
    }  
    public boolean Init(String hostports, int times){  
        try{  
            CountDownLatch connectedLatch = new CountDownLatch(1);  
            Watcher watcher = new ConnectedWatcher(connectedLatch);  
            zk_ = new ZooKeeper(hostports, times, watcher);  
            waitUntilConnected(zk_, connectedLatch);  
        }  
        catch(Exception e){  
            System.out.println(e);  
            return false;  
        }  
        return true;  
    }  
    public String Get(String keys){  
        String re = "";  
        String ppath = "/zookeeper";  
        int oldpos = -1;  
        int pos = 0;  
        while(true){  
            pos = keys.indexOf(".", oldpos + 1);  
            if(pos < 0){  
                ppath += "/";  
                String str = keys.substring(oldpos + 1);  
                ppath += str;  
                break;  
            }  
            ppath += "/";  
            String str = keys.substring(oldpos + 1,  pos);  
            ppath += str;  
            oldpos = pos;  
        }  
        Stat stat = new Stat();  
        try{  
            byte[] b = zk_.getData(ppath, false, stat);    //獲取節點的資訊及儲存的資料  
            re = new String(b);  
        }  
        catch(Exception e){  
            System.out.println(e);  
        }  
        return re;  
    }  
    private Conf(){  
          
    }  
    private ZooKeeper zk_;  
    static private Conf static_;  
    public static void main(String args[]){  
        String hostports = "192.168.1.88:2181,192.168.1.88:2182,192.168.1.88:2183";  
          
        Conf.Instance().Init(hostports, 1000);  
          
        String str = Conf.Instance().Get("conf.logicpoint.subscriberserverip");  
        str = Conf.Instance().Get("conf.logicpoint.subscriberserverport");  
        System.out.println(str);  
        while(true){  
            try{Thread.sleep(100);}  
            catch(Exception e){  
                  
            }  
        }  
          
    }  
}  

相關文章