zookeeper API使用 - 客户端连接

ZooKeeper 客户端对象

 /**
     * To create a ZooKeeper client object, the application needs to pass a
     * connection string containing a comma separated list of host:port pairs,
     * each corresponding to a ZooKeeper server.
     * <p>
     * Session establishment is asynchronous. This constructor will initiate
     * connection to the server and return immediately - potentially (usually)
     * before the session is fully established. The watcher argument specifies
     * the watcher that will be notified of any changes in state. This
     * notification can come at any point before or after the constructor call
     * has returned.
     * <p>
     * The instantiated ZooKeeper client object will pick an arbitrary server
     * from the connectString and attempt to connect to it. If establishment of
     * the connection fails, another server in the connect string will be tried
     * (the order is non-deterministic, as we random shuffle the list), until a
     * connection is established. The client will continue attempts until the
     * session is explicitly closed.
     * <p>
     * Added in 3.2.0: An optional "chroot" suffix may also be appended to the
     * connection string. This will run the client commands while interpreting
     * all paths relative to this root (similar to the unix chroot command).
     *
     * @param connectString
     *            comma separated host:port pairs, each corresponding to a zk
     *            server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002" If
     *            the optional chroot suffix is used the example would look
     *            like: "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002/app/a"
     *            where the client would be rooted at "/app/a" and all paths
     *            would be relative to this root - ie getting/setting/etc...
     *            "/foo/bar" would result in operations being run on
     *            "/app/a/foo/bar" (from the server perspective).
     * @param sessionTimeout
     *            session timeout in milliseconds
     * @param watcher
     *            a watcher object which will be notified of state changes, may
     *            also be notified for node events
     *
     * @throws IOException
     *             in cases of network failure
     * @throws IllegalArgumentException
     *             if an invalid chroot path is specified
     */
    public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher)
        throws IOException
    {
        this(connectString, sessionTimeout, watcher, false);
    }
  • connectString

  • sessionTimeout
    单位毫秒,表示zk等待客户端通信的最长时间,即zk与客户端有sessionTimeout的时间无法进行通信,则会终止session

  • watcher
    接收session事件

实例

package com.mb;

import lombok.extern.slf4j.Slf4j;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;

import java.util.concurrent.TimeUnit;

/**
 * @Author mubi
 * @Date 2019/4/4 10:42 PM
 */
@Slf4j
public class Master implements Watcher {
    ZooKeeper zk;
    String connectString;
    int sessionTimeout;

    Master(String connectString, int sessionTimeout){
        this.connectString = connectString;
        this.sessionTimeout = sessionTimeout;
    }

    void startZK() {
        try {
            zk = new ZooKeeper(connectString, sessionTimeout, this);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    void stopZK() {
        try {
            zk.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    @Override
    public void process(WatchedEvent event) {
        log.info("event:{}", event);
    }

    public static void main(String[] args){
        Master m = new Master("127.0.0.1:2181",10_000);
        log.info("start");
        m.startZK();
        try {
            TimeUnit.SECONDS.sleep(20);
            m.stopZK();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

}

连接日志分析

  • 启动zk服务器, 然后运行master日志输出
[2019-04-05 10:29:13:264] [INFO] - org.apache.zookeeper.Environment.logEnv(Environment.java:100) - Client environment:java.library.path=/usr/local/mysql/lib:/Users/mubi/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.
[2019-04-05 10:29:13:264] [INFO] - org.apache.zookeeper.Environment.logEnv(Environment.java:100) - Client environment:java.io.tmpdir=/var/folders/mt/9sz41nps4_5_7rshbz3nkrsh0000gn/T/
[2019-04-05 10:29:13:264] [INFO] - org.apache.zookeeper.Environment.logEnv(Environment.java:100) - Client environment:java.compiler=<NA>
[2019-04-05 10:29:13:265] [INFO] - org.apache.zookeeper.Environment.logEnv(Environment.java:100) - Client environment:os.name=Mac OS X
[2019-04-05 10:29:13:265] [INFO] - org.apache.zookeeper.Environment.logEnv(Environment.java:100) - Client environment:os.arch=x86_64
[2019-04-05 10:29:13:265] [INFO] - org.apache.zookeeper.Environment.logEnv(Environment.java:100) - Client environment:os.version=10.14.3
[2019-04-05 10:29:13:265] [INFO] - org.apache.zookeeper.Environment.logEnv(Environment.java:100) - Client environment:user.name=mubi
[2019-04-05 10:29:13:266] [INFO] - org.apache.zookeeper.Environment.logEnv(Environment.java:100) - Client environment:user.home=/Users/mubi
[2019-04-05 10:29:13:266] [INFO] - org.apache.zookeeper.Environment.logEnv(Environment.java:100) - Client environment:user.dir=/Users/mubi/git_workspace/java8
[2019-04-05 10:29:13:267] [INFO] - org.apache.zookeeper.ZooKeeper.<init>(ZooKeeper.java:441) - Initiating client connection, connectString=127.0.0.1:2181 sessionTimeout=10000 watcher=com.mb.Master@59494225
[2019-04-05 10:29:13:270] [DEBUG] - org.apache.zookeeper.ClientCnxn.<clinit>(ClientCnxn.java:119) - zookeeper.disableAutoWatchReset is false
[2019-04-05 10:29:13:295] [INFO] - org.apache.zookeeper.ClientCnxn$SendThread.logStartConnect(ClientCnxn.java:1028) - Opening socket connection to server 127.0.0.1/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error)
[2019-04-05 10:29:13:388] [INFO] - org.apache.zookeeper.ClientCnxn$SendThread.primeConnection(ClientCnxn.java:878) - Socket connection established to 127.0.0.1/127.0.0.1:2181, initiating session
[2019-04-05 10:29:13:390] [DEBUG] - org.apache.zookeeper.ClientCnxn$SendThread.primeConnection(ClientCnxn.java:951) - Session establishment request sent on 127.0.0.1/127.0.0.1:2181
[2019-04-05 10:29:13:402] [TRACE] - org.apache.zookeeper.ClientCnxnSocket.readConnectResult(ClientCnxnSocket.java:125) - readConnectResult 37 0x[0,0,0,0,0,0,27,10,1,0,c,ffffffe9,5f,73,0,12,0,0,0,10,77,ffffffd3,ffffffce,65,71,60,ffffffa5,4a,ffffff87,ffffffde,65,58,ffffff98,ffffff92,56,fffffff7,0,]
[2019-04-05 10:29:13:404] [INFO] - org.apache.zookeeper.ClientCnxn$SendThread.onConnected(ClientCnxn.java:1302) - Session establishment complete on server 127.0.0.1/127.0.0.1:2181, sessionid = 0x1000ce95f730012, negotiated timeout = 10000
[2019-04-05 10:29:13:406] [INFO] - com.mb.Master.process(Master.java:42) - event:WatchedEvent state:SyncConnected type:None path:null
[2019-04-05 10:29:16:736] [DEBUG] - org.apache.zookeeper.ClientCnxn$SendThread.readResponse(ClientCnxn.java:744) - Got ping response for sessionid: 0x1000ce95f730012 after 5ms
[2019-04-05 10:29:20:072] [DEBUG] - org.apache.zookeeper.ClientCnxn$SendThread.readResponse(ClientCnxn.java:744) - Got ping response for sessionid: 0x1000ce95f730012 after 0ms
[2019-04-05 10:29:23:410] [DEBUG] - org.apache.zookeeper.ClientCnxn$SendThread.readResponse(ClientCnxn.java:744) - Got ping response for sessionid: 0x1000ce95f730012 after 0ms
[2019-04-05 10:29:26:746] [DEBUG] - org.apache.zookeeper.ClientCnxn$SendThread.readResponse(ClientCnxn.java:744) - Got ping response for sessionid: 0x1000ce95f730012 after 0ms
[2019-04-05 10:29:30:084] [DEBUG] - org.apache.zookeeper.ClientCnxn$SendThread.readResponse(ClientCnxn.java:744) - Got ping response for sessionid: 0x1000ce95f730012 after 0ms
[2019-04-05 10:29:33:291] [DEBUG] - org.apache.zookeeper.ZooKeeper.close(ZooKeeper.java:676) - Closing session: 0x1000ce95f730012
[2019-04-05 10:29:33:292] [DEBUG] - org.apache.zookeeper.ClientCnxn.close(ClientCnxn.java:1373) - Closing client for session: 0x1000ce95f730012
[2019-04-05 10:29:33:301] [DEBUG] - org.apache.zookeeper.ClientCnxn$SendThread.readResponse(ClientCnxn.java:845) - Reading reply sessionid:0x1000ce95f730012, packet:: clientPath:null serverPath:null finished:false header:: 1,-11  replyHeader:: 1,4294967400,0  request:: null response:: null
[2019-04-05 10:29:33:302] [DEBUG] - org.apache.zookeeper.ClientCnxn.disconnect(ClientCnxn.java:1357) - Disconnecting client for session: 0x1000ce95f730012
[2019-04-05 10:29:33:302] [DEBUG] - org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1149) - An exception was thrown while closing send thread for session 0x1000ce95f730012 : Unable to read additional data from server sessionid 0x1000ce95f730012, likely server has closed socket
[2019-04-05 10:29:33:302] [INFO] - org.apache.zookeeper.ZooKeeper.close(ZooKeeper.java:687) - Session: 0x1000ce95f730012 closed
[2019-04-05 10:29:33:302] [INFO] - org.apache.zookeeper.ClientCnxn$EventThread.run(ClientCnxn.java:521) - EventThread shut down for session: 0x1000ce95f730012

Process finished with exit code 0
  • 客户端连接信息
  • session 建立的请求 和 建立完成
Session establishment complete on server 127.0.0.1/127.0.0.1:2181, sessionid = 0x1000ce95f73000d, negotiated timeout = 10000
  • WatchedEvent
[2019-04-05 10:29:13:406] [INFO] - com.mb.Master.process(Master.java:42) - event:WatchedEvent state:SyncConnected type:None path:null
  • 心跳
    zookeeper服务端通过zookeeper客户端上报心跳来确定zookeeper客户端的存活状态
[2019-04-05 10:17:18:767] [DEBUG] - org.apache.zookeeper.ClientCnxn$SendThread.readResponse(ClientCnxn.java:744) - Got ping response for sessionid: 0x1000ce95f73000d after 5ms
  • session关闭
[2019-04-05 10:17:35:357] [DEBUG] - org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1149) - An exception was thrown while closing send thread for session 0x1000ce95f73000d : Unable to read additional data from server sessionid 0x1000ce95f73000d, likely server has closed socket
[2019-04-05 10:17:35:358] [DEBUG] - org.apache.zookeeper.ClientCnxn.disconnect(ClientCnxn.java:1357) - Disconnecting client for session: 0x1000ce95f73000d
[2019-04-05 10:17:35:358] [INFO] - org.apache.zookeeper.ZooKeeper.close(ZooKeeper.java:687) - Session: 0x1000ce95f73000d closed

zk服务有服务节点挂掉, 客户端连接的变化

public static void main(String[] args){
        String connectString = "127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183";
        int sessionTimeout = 10_000;
        Master m = new Master(connectString, sessionTimeout);
        log.info("start");
        m.startZK();
        try {
            TimeUnit.SECONDS.sleep(20);
//            m.stopZK();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

  • 日志分析
[2019-04-05 10:45:35:851] [INFO] - org.apache.zookeeper.ZooKeeper.<init>(ZooKeeper.java:441) - Initiating client connection, connectString=127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183 sessionTimeout=10000 watcher=com.mb.Master@59494225
[2019-04-05 10:45:35:855] [DEBUG] - org.apache.zookeeper.ClientCnxn.<clinit>(ClientCnxn.java:119) - zookeeper.disableAutoWatchReset is false
[2019-04-05 10:45:35:877] [INFO] - org.apache.zookeeper.ClientCnxn$SendThread.logStartConnect(ClientCnxn.java:1028) - Opening socket connection to server 127.0.0.1/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error)
[2019-04-05 10:45:35:960] [INFO] - org.apache.zookeeper.ClientCnxn$SendThread.primeConnection(ClientCnxn.java:878) - Socket connection established to 127.0.0.1/127.0.0.1:2181, initiating session
[2019-04-05 10:45:35:962] [DEBUG] - org.apache.zookeeper.ClientCnxn$SendThread.primeConnection(ClientCnxn.java:951) - Session establishment request sent on 127.0.0.1/127.0.0.1:2181
[2019-04-05 10:45:35:975] [TRACE] - org.apache.zookeeper.ClientCnxnSocket.readConnectResult(ClientCnxnSocket.java:125) - readConnectResult 37 0x[0,0,0,0,0,0,27,10,1,0,d,33,ffffffb9,66,0,1,0,0,0,10,ffffffcb,27,1d,5f,ffffff85,ffffffa9,7,ffffffcd,4b,ffffffc7,f,36,a,6e,ffffffa4,ffffffe6,0,]
[2019-04-05 10:45:35:979] [INFO] - org.apache.zookeeper.ClientCnxn$SendThread.onConnected(ClientCnxn.java:1302) - Session establishment complete on server 127.0.0.1/127.0.0.1:2181, sessionid = 0x1000d33b9660001, negotiated timeout = 10000
[2019-04-05 10:45:35:988] [INFO] - com.mb.Master.process(Master.java:42) - event:WatchedEvent state:SyncConnected type:None path:null
[2019-04-05 10:45:39:315] [DEBUG] - org.apache.zookeeper.ClientCnxn$SendThread.readResponse(ClientCnxn.java:744) - Got ping response for sessionid: 0x1000d33b9660001 after 4ms
[2019-04-05 10:45:42:652] [DEBUG] - org.apache.zookeeper.ClientCnxn$SendThread.readResponse(ClientCnxn.java:744) - Got ping response for sessionid: 0x1000d33b9660001 after 0ms
[2019-04-05 10:45:45:990] [DEBUG] - org.apache.zookeeper.ClientCnxn$SendThread.readResponse(ClientCnxn.java:744) - Got ping response for sessionid: 0x1000d33b9660001 after 0ms
[2019-04-05 10:45:46:587] [INFO] - org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1161) - Unable to read additional data from server sessionid 0x1000d33b9660001, likely server has closed socket, closing socket connection and attempting reconnect
[2019-04-05 10:45:46:696] [INFO] - com.mb.Master.process(Master.java:42) - event:WatchedEvent state:Disconnected type:None path:null
[2019-04-05 10:45:47:285] [INFO] - org.apache.zookeeper.ClientCnxn$SendThread.logStartConnect(ClientCnxn.java:1028) - Opening socket connection to server 127.0.0.1/127.0.0.1:2182. Will not attempt to authenticate using SASL (unknown error)
[2019-04-05 10:45:47:289] [INFO] - org.apache.zookeeper.ClientCnxn$SendThread.primeConnection(ClientCnxn.java:878) - Socket connection established to 127.0.0.1/127.0.0.1:2182, initiating session
[2019-04-05 10:45:47:289] [DEBUG] - org.apache.zookeeper.ClientCnxn$SendThread.primeConnection(ClientCnxn.java:951) - Session establishment request sent on 127.0.0.1/127.0.0.1:2182
[2019-04-05 10:45:47:290] [TRACE] - org.apache.zookeeper.ClientCnxnSocket.readConnectResult(ClientCnxnSocket.java:125) - readConnectResult 37 0x[0,0,0,0,0,0,27,10,1,0,d,33,ffffffb9,66,0,1,0,0,0,10,ffffffcb,27,1d,5f,ffffff85,ffffffa9,7,ffffffcd,4b,ffffffc7,f,36,a,6e,ffffffa4,ffffffe6,0,]
[2019-04-05 10:45:47:290] [INFO] - org.apache.zookeeper.ClientCnxn$SendThread.onConnected(ClientCnxn.java:1302) - Session establishment complete on server 127.0.0.1/127.0.0.1:2182, sessionid = 0x1000d33b9660001, negotiated timeout = 10000
[2019-04-05 10:45:47:291] [INFO] - com.mb.Master.process(Master.java:42) - event:WatchedEvent state:SyncConnected type:None path:null
[2019-04-05 10:45:50:629] [DEBUG] - org.apache.zookeeper.ClientCnxn$SendThread.readResponse(ClientCnxn.java:744) - Got ping response for sessionid: 0x1000d33b9660001 after 2ms
[2019-04-05 10:45:53:965] [DEBUG] - org.apache.zookeeper.ClientCnxn$SendThread.readResponse(ClientCnxn.java:744) - Got ping response for sessionid: 0x1000d33b9660001 after 0ms

Process finished with exit code 0
  • 最开始建立连接到了 127.0.0.1:8081

  • 接着 127.0.0.1:8081 挂掉了, 客户端watch到了Disconnected事件

[2019-04-05 10:45:46:587] [INFO] - org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1161) - Unable to read additional data from server sessionid 0x1000d33b9660001, likely server has closed socket, closing socket connection and attempting reconnect
[2019-04-05 10:45:46:696] [INFO] - com.mb.Master.process(Master.java:42) - event:WatchedEvent state:Disconnected type:None path:null
  • 客户端接着再次发送连接请求,并连接上了,且sessionid 未改变
[2019-04-05 10:45:47:289] [DEBUG] - org.apache.zookeeper.ClientCnxn$SendThread.primeConnection(ClientCnxn.java:951) - Session establishment request sent on 127.0.0.1/127.0.0.1:2182
[2019-04-05 10:45:47:290] [TRACE] - org.apache.zookeeper.ClientCnxnSocket.readConnectResult(ClientCnxnSocket.java:125) - readConnectResult 37 0x[0,0,0,0,0,0,27,10,1,0,d,33,ffffffb9,66,0,1,0,0,0,10,ffffffcb,27,1d,5f,ffffff85,ffffffa9,7,ffffffcd,4b,ffffffc7,f,36,a,6e,ffffffa4,ffffffe6,0,]
[2019-04-05 10:45:47:290] [INFO] - org.apache.zookeeper.ClientCnxn$SendThread.onConnected(ClientCnxn.java:1302) - Session establishment complete on server 127.0.0.1/127.0.0.1:2182, sessionid = 0x1000d33b9660001, negotiated timeout = 10000

注意点

不要自己尝试着去管理Zookeeper客户端连接。Zookeeper客户端库会监控与服务之间的连接,客户端库不仅告诉我们连接发生的问题,还会主动尝试重新建立通信。一般客户端开发库会很快重建session,以便最小化影响,所以不要关闭session后重新启动一个新的session,这样会增加系统负载,并导致更长时间的中断

发布了441 篇原创文章 · 获赞 110 · 访问量 57万+

猜你喜欢

转载自blog.csdn.net/qq_26437925/article/details/89040699