int timeout = url.getParameter(TIMEOUT_KEY, DEFAULT_CONNECTION_TIMEOUT_MS);
这里的大概逻辑是,如果yaml配置registry注册zookeeper部分参数当中含有 timeout话,那么就返回配置当中定义的超时时间,如果yaml没有进行配置,那么,就用默认的超时时间,默认即常量DEFAULT_CONNECTION_TIMEOUT_MS,值是5 * 1000,也就是5秒,这个参数其实就是本篇文章的核心。
若自定义形式配置该参数,形式如下timeout: 20000——
dubbo:
application:
name: testervice
registry:
address: zookeeper://120.77.217.245
timeout: 20000
第二步、获取客户端过期时间——
int sessionExpireMs = url.getParameter(ZK_SESSION_EXPIRE_KEY, DEFAULT_SESSION_TIMEOUT_MS);
同理,无自定义配置话,则使用默认值DEFAULT_SESSION_TIMEOUT_MS = 60 * 1000,即6分钟;
第三步、创建一个设置过期时间为6分钟,连接超时为5秒,重试策略为每秒重试一次,连接服务端为url.getBackupAddress()(注:我这里得到的是120.77.217.245:9090,即配置的zookeeper连接url)的CuratorFramework客户端实例——
CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder()
.connectString(url.getBackupAddress())
.retryPolicy(new RetryNTimes(1, 1000))
.connectionTimeoutMs(timeout)
.sessionTimeoutMs(sessionExpireMs);
client = builder.build();
第四步、添加连接状态的监控,可以监控操作节点与连接情况——
client.getConnectionStateListenable().addListener(new CuratorConnectionStateListener(url));
第五步、开启客户端——
client.start();
最后一步,监控客户端连接情况,若能连接成功,则证明创建客户端成功,反之,失败。可见,若出现zookeeper not connected,问题就在于客户端连接过程是失败的,至于为何失败,原理就在client.blockUntilConnected(timeout, TimeUnit.MILLISECONDS)代码里。
boolean connected = client.blockUntilConnected(timeout, TimeUnit.MILLISECONDS);
if (!connected) {
throw new IllegalStateException(“zookeeper not connected”);
}
进入到 client.blockUntilConnected(timeout, TimeUnit.MILLISECONDS)源码里,这里的maxWaitTime即前边的timeout,默认值是5秒,大概分析一下下边代码——
public synchronized boolean blockUntilConnected(int maxWaitTime, TimeUnit units) throws InterruptedException
{
//获取当前时间
long startTime = System.currentTimeMillis();
//这里是true
boolean hasMaxWait = (units != null);
//maxWaitTimeMs等于5000毫秒,即5秒
long maxWaitTimeMs = hasMaxWait ? TimeUnit.MILLISECONDS.convert(maxWaitTime, units) : 0;
while ( !isConnected() )
{
//hasMaxWait为true
if ( hasMaxWait )
{
//倒数5秒
long waitTime = maxWaitTimeMs - (System.currentTimeMillis() - startTime);
//执行到这里,已经过去5秒话,就执行以下方法,返回isConnected()值
if ( waitTime <= 0 )
{
return isConnected();
}
//还没到5秒话,假如执行到这里还有3秒,那么就会执行Object.wait(long timeout)方法,即该线程阻塞3秒后再自动唤醒,接着继续执行
wait(waitTime);
}
else
{
wait();
}
}
return isConnected();
}
该方法的核心会等待maxWaitTime时间,时间一到,就会返回isConnected()值,这里其实很好理解,就是客户端发起连接后,这里用一个while循环来等待指定的超时时间,默认是5秒,若5秒过了,就返回isConnected()值,而这里的isConnected()就是验证是否连接成功了,
那么,这里就剩最后一个答案了,isConnected()是什么?
public synchronized boolean isConnected(){
return (currentConnectionState != null) && currentConnectionState.isConnected();
}
这里应该是判断客户端连接状态,即在client.start()方法里,会有一个状态,若创建连接成功,那么currentConnectionState.isConnected()就能得到true值,这里更像是一个观察模式,观察指定的连接超时时间内,是否连接成功。
根据debug,发现未连接成功时,值是null,得到的即为false,当我们把默认为5秒的连接超时设置为timeout: 20000,等待连接过程,发现连接成功了,返回currentConnectionState的值为RECONNECTED。
可见,之前出现zookeeper not connected异常问题,就是连接超时设置太短了!
currentConnectionState.isConnected()得到的是一个枚举值,RECONNECTED返回的是true——
CONNECTED {
public boolean isConnected() {
return true;
}
},
SUSPENDED {
public boolean isConnected() {
return false;
}
},
RECONNECTED {
public boolean isConnected() {
return true;
}
},
LOST {
public boolean isConnected() {
return false;
}
},
READ_ONLY {
public boolean isConnected() {
return true;
总结
至此,文章终于到了尾声。总结一下,我们谈论了简历制作过程中需要注意的以下三个部分,并分别给出了一些建议:
- 技术能力:先写岗位所需能力,再写加分能力,不要写无关能力;
- 项目经历:只写明星项目,描述遵循 STAR 法则;
- 简历印象:简历遵循三大原则:清晰,简短,必要,要有的放矢,不要海投;
以及最后为大家准备的福利时间:简历模板+Java面试题+热门技术系列教程视频
过程中需要注意的以下三个部分,并分别给出了一些建议:
- 技术能力:先写岗位所需能力,再写加分能力,不要写无关能力;
- 项目经历:只写明星项目,描述遵循 STAR 法则;
- 简历印象:简历遵循三大原则:清晰,简短,必要,要有的放矢,不要海投;
以及最后为大家准备的福利时间:简历模板+Java面试题+热门技术系列教程视频
[外链图片转存中…(img-Gwq5vtFP-1720130316492)]
[外链图片转存中…(img-P01VOjla-1720130316493)]
[外链图片转存中…(img-diMRGgCD-1720130316494)]