启动Dubbo项目注册Zookeeper时提示zookeeper not connected异常原理解析 (2)

进入到 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异常问题,就是连接超时设置太短了!

image


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; } };

当返回true话,那么!connected就为false,就不会执行以下异常提示了——

if (!connected) { throw new IllegalStateException("zookeeper not connected"); }

根据上边分析,可见启动Dubbo项目注册Zookeeper时提示zookeeper not connected异常,是因为没有在配置里设置连接超时,而是使用了默认的5秒,导致5秒内没有成功连接,就出现连接异常而无法成功连接,当调长时间后,就正常连接成功了,同时也说明了,这次本地连接zookeeper集群的时间超过了五秒。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zggxzd.html