apache-zookeeper

org.apache.zookeeper.KeeperException$ConnectionLossException: KeeperErrorCode = ConnectionLoss occur when I get zk's child Nodes


the case as follow: I call client.getChildren().forPath("/path".No problem under normal circumstances.

But if the childNodes is too many,the Exception:org.apache.zookeeper.KeeperException$ConnectionLossException: KeeperErrorCode = ConnectionLoss for /path occured.

the code:

        RetryNTimes retryNTimes = new RetryNTimes(1, 1000);
        CuratorFramework client = CuratorFrameworkFactory.newClient("xx.xx.xx.xx:2181",
                50000, 50000, retryNTimes);
        client.start();
        List<String> childNodes = client.getChildren().forPath("/path");

the zkServer is three node cluster.the version is 3.4.13.

the curator version in my client is 2.12.0

someone do me a favor


Solution

  • finally,I find the source reason.the child nodes is too many.so the packet's length from server is more than client packet's length limit(1024 * 4096).so I set the System properties -Djute.maxbuffer = 10485760.the problem is solved.

    the relational code:

     public static final int packetLen = Integer.getInteger("jute.maxbuffer",
                4096 * 1024);
    
       protected void readLength() throws IOException {
            int len = incomingBuffer.getInt();
            if (len < 0 || len >= ClientCnxn.packetLen) {
                throw new IOException("Packet len" + len + " is out of range!");
            }
            incomingBuffer = ByteBuffer.allocate(len);
        }
    
            private void conLossPacket(Packet p) {
            if (p.replyHeader == null) {
                return;
            }
            switch (state) {
            case AUTH_FAILED:
                p.replyHeader.setErr(KeeperException.Code.AUTHFAILED.intValue());
                break;
            case CLOSED:
                p.replyHeader.setErr(KeeperException.Code.SESSIONEXPIRED.intValue());
                break;
            default:
                p.replyHeader.setErr(KeeperException.Code.CONNECTIONLOSS.intValue());
            }
            finishPacket(p);
        }
      
    

    the logic as follow:

    org.apache.zookeeper.ClientCnxn.SendThread#run; -> clientCnxnSocket.doTransport(to, pendingQueue, outgoingQueue, ClientCnxn.this); -> doIO(pendingQueue, outgoingQueue, cnxn); -> readLength(); -> cleanup(); -> conLossPacket(p)

    the Exception:"org.apache.zookeeper.KeeperException$ConnectionLossException: KeeperErrorCode = ConnectionLoss for /path" maybe mislead user.