zookeeper 客户端源码解读(二)
关于2个线程
在 1.1.2.1.2 ClientCnxn.start 里创建了两个线程,这两个线程是干什么用的呢?
SendThread

改变状态为 connecting

其父类继承自 Thread 类,这里不贴图了,重点看一下 SendThread 里的 run 方法:
@Override
public void run() {
//初始化clientCnxnSocket,sessionId用于 Log and Exception messages
clientCnxnSocket.introduce(this,sessionId);
//初始化当前时间 now = Time.currentElapsedTime() = System.nanoTime() / 1000000;
clientCnxnSocket.updateNow();
//初始化最后发信时间和最后收信时间this.lastSend = now;this.lastHeard = now;
clientCnxnSocket.updateLastSendAndHeard();
int to;
//最后ping读写服务器时间
long lastPingRwServer = Time.currentElapsedTime();
//最大发ping信号间隔
final int MAX_SEND_PING_INTERVAL = 10000; //10 seconds
InetSocketAddress serverAddress = null;
//如果状态是活的:this != CLOSED && this != AUTH_FAILED;
while (state.isAlive()) {
try {
//如果有Channel注册到Selector了(有SelectionKey,
//如果这些不太懂,需要了解 NIO,可以看看我这方面的博客),isConnected返回true
//这里 if 里的意思是:没有连接(其实就是表面意思=。=)
if (!clientCnxnSocket.isConnected()) {
//这个isFirstConnect默认值是true
//这里 if 里的意思是:不是第一次连接。
//证明之前是连接过的,走到这里说明是重连
if(!isFirstConnect){
try {
//睡 1 s,为什么?重连间隔
Thread.sleep(r.nextInt(1000));
} catch (InterruptedException e) {
LOG.warn("Unexpected exception", e);
}
}
// don't re-establish connection if we are closing
//如果正在关闭或者状态是关闭的或认证失败的
if (closing || !state.isAlive()) {
break;
}
//如果读写服务器地址不为空,用读写服务器地址
if (rwServerAddress != null) {
serverAddress = rwServerAddress;
rwServerAddress = null;
} else {
//挨个访问服务器地址列表里的地址,间隔 1 s
serverAddress = hostProvider.next(1000);
}
//开始连接
startConnect(serverAddress);
clientCnxnSocket.updateLastSendAndHeard();
}
if (state.isConnected()) {
// determine whether we need to send an AuthFailed event.
if (zooKeeperSaslClient != null) {
boolean sendAuthEvent = false;
if (zooKeeperSaslClient.getSaslState(

本文深入解析ZooKeeper客户端中的两个关键线程:SendThread和EventThread。SendThread负责建立与服务器的连接,处理连接状态变化及数据传输;EventThread则用于处理客户端事件,如连接状态变更和数据包接收。文章详细介绍了SendThread的工作流程,包括连接建立、心跳发送、超时处理等,并阐述了其在重连机制中的作用。
最低0.47元/天 解锁文章
1588

被折叠的 条评论
为什么被折叠?



