zookeeper客户端和服务端交互分析

实例化zookeeper客户端后,客户端会创建ClientCnxn,其表示与服务端的连接交互对象。ClientCnxn将创建两个线程SendThread和EventThread线程。发送线程主要完成请求的发送和从服务端过来的应答的读取,对于读取的应答需要进一步处理的转由事件线程来处理。

客户端和服务端之间有session的概念,客户端随机连接到zookeeper server集群中的一台机器后,建立session后,会通过心跳的方式来维持该session。

这里先看一下心跳时间间隔。

 

public ClientCnxn(String chrootPath, HostProvider hostProvider, int sessionTimeout, ZooKeeper zooKeeper,
            ClientWatchManager watcher, ClientCnxnSocket clientCnxnSocket,
            long sessionId, byte[] sessionPasswd, boolean canBeReadOnly) {
        this.zooKeeper = zooKeeper;
        this.watcher = watcher;
        this.sessionId = sessionId;
        this.sessionPasswd = sessionPasswd;
        this.sessionTimeout = sessionTimeout;
        this.hostProvider = hostProvider;
        this.chrootPath = chrootPath;

        connectTimeout = sessionTimeout / hostProvider.size();
        readTimeout = sessionTimeout * 2 / 3;
        readOnly = canBeReadOnly;

        sendThread = new SendThread(clientCnxnSocket);
        eventThread = new EventThread();

    }


从ClientCnxn构造可知,读超时时间设置为会话超时时间的2/3,实际上述构造时的session超时时间是客户端自己要求的超时时间,与服务端建立连接过程中,会与服务端协调一个超时时间,客户端最终使用的协调获得的超时时间。

SendThread线程运行过程中

 if (state.isConnected()) {
                        int timeToNextPing = readTimeout / 2
                                - clientCnxnSocket.getIdleSend();
                        if (timeToNextPing <= 0) {
                            sendPing();
                            clientCnxnSocket.updateLastSend();
                        } else {
                            if (timeToNextPing < to) {
                                to = timeToNextPing;
                            }
                        }
                    }


计算时取读超时时间的一半,即会话超时的1/3。还需关注的是会话超时的判断逻辑,即在连接的状态下,客户端有2/3个会话周期没有收到服务端的消息后,即认为是会话时效。

 if (state.isConnected()) {
       //......
         to = readTimeout - clientCnxnSocket.getIdleRecv();
     } else {
         to = connectTimeout - clientCnxnSocket.getIdleRecv();
     }


 

 

你可能感兴趣的:(java,zookeeper)