目录
一、几个重要的类
二、JAVA的基础知识
三、大致了解
四 从入门到放弃的讲解
Code1:ZK
Code2:创建 Zookeeper实例,实例化ClientCnxn,实例化ClientCnxnSocketNIO
Code3:实例化ClientCnxnSocketNIO (which extends ClientCnxnSocket)
Code4:ClientCnxn的具体实例化
Code5:SendThread的具体实例化
Code6:EventThread的具体实例化
Code 7:SendThread核心run流程
Code 8:startConnect()
Code 9: clientCnxnSocket.connect
Code10:registerAndConnect()
Code11:primeConnection()
Code 12:doTransport()
Code13:findSendablePacket()
Code14:IO write
Code15:createBB()
Code 16:IO read
Code 17: readResponse
Code 18:EventThread run:
源码: Zookeeper 3.4.6.jar(吐血总结)
一、几个重要的类
1) ZookeeperMain: main函数为入口,由zkCli.sh脚本调用启动
2) ZooKeeper:客户端入口
3) ZooKeeper.SendThread: IO线程
4) ZooKeeper.EventThread: 事件处理线程,处理各类消息callback
5) ClientCnxn: 客户端与服务器端交互的主要类
6) ClientCnxnSocketNIO:继承自ClientCnxnSocket,专门处理IO, 利用JAVANIO
7) Watcher: 用于监控Znode节点
9) WatcherManager:用来管理Watcher,管理了ZK Client绑定的所有Watcher。
二、JAVA的基础知识
1)JAVA多线程
2)JAVANIO: 可参考:http://blog.csdn.net/cnh294141800/article/details/52996819
3)Socket编程(稍微了解即可)
4)JLine: 是一个用来处理控制台输入的Java类库
三、大致了解
上图就是对Zookeeper源码一个最好的解释,
(1) Client端发送Request(封装成Packet)请求到Zookeeper
(2) Zookeeper处理Request并将该请求放入Outgoing Queue(顾名思义,外出队列,就是让Zookeeper服务器处理的队列),
(3) Zookeeper端处理Outgoing Queue,并将该事件移到Pending Queue中
(4) Zookeeper端消费Pending Queue,并调用finishPacket(),生成Event
(5) EventThread线程消费Event事件,并且处理Watcher.
四 从入门到放弃的讲解
(1)应用 提供watch实例(new MyWatcher(null))
private class MyWatcher implements Watcher {
// 默认Watcher
public void process(WatchedEvent event) {
if (getPrintWatches()) {
ZooKeeperMain.printMessage("WATCHER::");
ZooKeeperMain.printMessage(event.toString());
}
}
}
(2)实例化zookeeper
实例化socket,默认使用ClientCnxnSocketNIO
实例化ClientCnxn
实例化SendThread
实例化EventThread
Code1:ZK
zk = new ZooKeeper(host Integer.parseInt(cl.getOption("timeout")),
new MyWatcher(), readOnly); // 初始化ZK
Code2:
public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher,
boolean canBeReadOnly)
throws IOException
{
…
watchManager.defaultWatcher = watcher; // 设置defaultWatcher 为 MyWatcher
ConnectStringParser connectStringParser = new ConnectStringParser(
connectString); // 解析-server 获取 IP以及PORT
HostProvider hostProvider = new StaticHostProvider(
connectStringParser.getServerAddresses());
cnxn = new ClientCnxn(connectStringParser.getChrootPath(),
hostProvider, sessionTimeout, this, watchManager,
getClientCnxnSocket(), canBeReadOnly); // 创建 ClientCnxn实例
cnxn.start(); // 启动cnxn中的SendThread and EventThread进程
}
Code3:实例化ClientCnxnSocketNIO (which extends ClientCnxnSocket)
private static ClientCnxnSocket getClientCnxnSocket() throws IOException {
String clientCnxnSocketName = System
.getProperty(ZOOKEEPER_CLIENT_CNXN_SOCKET);
if (clientCnxnSocketName == null) {
clientCnxnSocketName = ClientCnxnSocketNIO.class.getName();
}
try {
return (ClientCnxnSocket) Class.forName(clientCnxnSocketName)
.newInstance();
} catch (Exception e) {
IOException ioe = new IOException("Couldn't instantiate "
+ clientCnxnSocketName);
ioe.initCause(e);
throw ioe;
}
}
Code4:ClientCnxn的具体实例化
/* 另一个ClientCnxn构造函数, 可见时sessionId=0
public ClientCnxn(String chrootPath, HostProvider hostProvider, int sessionTimeout, ZooKeeper zooKeeper,
ClientWatchManager watcher, ClientCnxnSocket clientCnxnSocket, boolean canBeReadOnly)
throws IOException {
this(chrootPath, hostProvider, sessionTimeout, zooKeeper, watcher,
clientCnxnSocket, 0, new byte[16], canBeReadOnly);
}
*/
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;
//初始化client2个核心线程,SendThread是client的IO核心线程,EventThread从SendThread里拿到event
sendThread = new SendThread(clientCnxnSocket);
eventThread = new EventThread();
}
Code5:SendThread的具体实例化
SendThread(ClientCnxnSocket clientCnxnSocket) {
super(makeThreadName("-SendThread()"));
state = States.CONNE