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,这样会增加系统负载,并导致更长时间的中断