本文主要针对使用springboot整合dubbo框架时使用zookeeper作为注册中心,在服务启动连接zookeeper产生的问题做一个详细的讲解。 主要针对两个异常
(1)java.lang.IllegalStateException: java.lang.IllegalStateException: zookeeper not connected
(2)java.lang.IllegalStateException: failed to connect to zookeeper server
关于两个异常的详细信息见下方异常信息
1、异常详细信息
(1) java.lang.IllegalStateException: java.lang.IllegalStateException: zookeeper not connected
java.lang.IllegalStateException: java.lang.IllegalStateException: zookeeper not connected
at org.apache.dubbo.config.deploy.DefaultApplicationDeployer.prepareEnvironment(DefaultApplicationDeployer.java:678) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.config.deploy.DefaultApplicationDeployer.startConfigCenter(DefaultApplicationDeployer.java:261) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.config.deploy.DefaultApplicationDeployer.initialize(DefaultApplicationDeployer.java:185) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.config.deploy.DefaultModuleDeployer.prepare(DefaultModuleDeployer.java:470) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.config.spring.context.DubboConfigApplicationListener.initDubboConfigBeans(DubboConfigApplicationListener.java:71) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.config.spring.context.DubboConfigApplicationListener.onApplicationEvent(DubboConfigApplicationListener.java:57) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.config.spring.context.DubboConfigApplicationListener.onApplicationEvent(DubboConfigApplicationListener.java:35) ~[dubbo-3.0.7.jar:3.0.7]
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) ~[spring-context-5.2.15.RELEASE.jar:5.2.15.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) ~[spring-context-5.2.15.RELEASE.jar:5.2.15.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) ~[spring-context-5.2.15.RELEASE.jar:5.2.15.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127) ~[spring-context-5.2.15.RELEASE.jar:5.2.15.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.registerListeners(AbstractApplicationContext.java:842) ~[spring-context-5.2.15.RELEASE.jar:5.2.15.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:548) ~[spring-context-5.2.15.RELEASE.jar:5.2.15.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143) ~[spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:755) [spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) [spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:402) [spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) [spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1247) [spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1236) [spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE]
at com.bao.Application.main(Application.java:11) [classes/:na]
Caused by: java.lang.IllegalStateException: zookeeper not connected
at org.apache.dubbo.remoting.zookeeper.curator.CuratorZookeeperClient.<init>(CuratorZookeeperClient.java:89) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.remoting.zookeeper.curator.CuratorZookeeperTransporter.createZookeeperClient(CuratorZookeeperTransporter.java:26) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.remoting.zookeeper.AbstractZookeeperTransporter.connect(AbstractZookeeperTransporter.java:69) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.configcenter.support.zookeeper.ZookeeperDynamicConfiguration.<init>(ZookeeperDynamicConfiguration.java:63) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.configcenter.support.zookeeper.ZookeeperDynamicConfigurationFactory.createDynamicConfiguration(ZookeeperDynamicConfigurationFactory.java:47) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.common.config.configcenter.AbstractDynamicConfigurationFactory.lambda$getDynamicConfiguration$0(AbstractDynamicConfigurationFactory.java:39) ~[dubbo-3.0.7.jar:3.0.7]
at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660) ~[na:1.8.0_131]
at org.apache.dubbo.common.config.configcenter.AbstractDynamicConfigurationFactory.getDynamicConfiguration(AbstractDynamicConfigurationFactory.java:39) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.config.deploy.DefaultApplicationDeployer.getDynamicConfiguration(DefaultApplicationDeployer.java:715) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.config.deploy.DefaultApplicationDeployer.prepareEnvironment(DefaultApplicationDeployer.java:671) ~[dubbo-3.0.7.jar:3.0.7]
... 20 common frames omitted
Caused by: java.lang.IllegalStateException: zookeeper not connected
at org.apache.dubbo.remoting.zookeeper.curator.CuratorZookeeperClient.<init>(CuratorZookeeperClient.java:85) ~[dubbo-3.0.7.jar:3.0.7]
... 29 common frames omitted
(2)java.lang.IllegalStateException: failed to connect to zookeeper server
java.lang.RuntimeException: Can not create registry service-discovery-registry://192.168.0.106:2181/org.apache.dubbo.registry.RegistryService?application=privoder_application&block-until-connected-wait=3&blockUntilConnectedWait=3&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=21212&qos.enable=false®istry=zookeeper&release=3.0.7&timeout=250000
at org.apache.dubbo.registry.support.AbstractRegistryFactory.getRegistry(AbstractRegistryFactory.java:92) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.registry.RegistryFactoryWrapper.getRegistry(RegistryFactoryWrapper.java:33) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.registry.RegistryFactory$Adaptive.getRegistry(RegistryFactory$Adaptive.java) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.registry.integration.RegistryProtocol.getRegistry(RegistryProtocol.java:393) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.registry.integration.RegistryProtocol.export(RegistryProtocol.java:242) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper.export(ProtocolListenerWrapper.java:64) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.qos.protocol.QosProtocolWrapper.export(QosProtocolWrapper.java:74) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.rpc.cluster.filter.ProtocolFilterWrapper.export(ProtocolFilterWrapper.java:58) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.rpc.protocol.ProtocolSerializationWrapper.export(ProtocolSerializationWrapper.java:47) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.rpc.Protocol$Adaptive.export(Protocol$Adaptive.java) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.config.ServiceConfig.doExportUrl(ServiceConfig.java:641) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.config.ServiceConfig.exportRemote(ServiceConfig.java:619) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.config.ServiceConfig.exportUrl(ServiceConfig.java:578) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.config.ServiceConfig.doExportUrlsFor1Protocol(ServiceConfig.java:410) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.config.ServiceConfig.doExportUrls(ServiceConfig.java:396) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.config.ServiceConfig.doExport(ServiceConfig.java:361) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.config.ServiceConfig.export(ServiceConfig.java:233) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.config.deploy.DefaultModuleDeployer.exportServiceInternal(DefaultModuleDeployer.java:341) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.config.deploy.DefaultModuleDeployer.exportServices(DefaultModuleDeployer.java:313) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.config.deploy.DefaultModuleDeployer.start(DefaultModuleDeployer.java:145) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.config.spring.context.DubboDeployApplicationListener.onContextRefreshedEvent(DubboDeployApplicationListener.java:111) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.config.spring.context.DubboDeployApplicationListener.onApplicationEvent(DubboDeployApplicationListener.java:100) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.config.spring.context.DubboDeployApplicationListener.onApplicationEvent(DubboDeployApplicationListener.java:45) ~[dubbo-3.0.7.jar:3.0.7]
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) ~[spring-context-5.2.15.RELEASE.jar:5.2.15.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) ~[spring-context-5.2.15.RELEASE.jar:5.2.15.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) ~[spring-context-5.2.15.RELEASE.jar:5.2.15.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:404) ~[spring-context-5.2.15.RELEASE.jar:5.2.15.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:361) ~[spring-context-5.2.15.RELEASE.jar:5.2.15.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:898) ~[spring-context-5.2.15.RELEASE.jar:5.2.15.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:554) ~[spring-context-5.2.15.RELEASE.jar:5.2.15.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143) ~[spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:755) [spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) [spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:402) [spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) [spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1247) [spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1236) [spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE]
at com.bao.Application.main(Application.java:11) [classes/:na]
Caused by: java.lang.IllegalStateException: Create zookeeper service discovery failed.
at org.apache.dubbo.registry.zookeeper.ZookeeperServiceDiscovery.<init>(ZookeeperServiceDiscovery.java:77) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.registry.zookeeper.ZookeeperServiceDiscoveryFactory.createDiscovery(ZookeeperServiceDiscoveryFactory.java:27) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.registry.client.AbstractServiceDiscoveryFactory.lambda$getServiceDiscovery$0(AbstractServiceDiscoveryFactory.java:53) ~[dubbo-3.0.7.jar:3.0.7]
at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660) ~[na:1.8.0_131]
at org.apache.dubbo.registry.client.AbstractServiceDiscoveryFactory.getServiceDiscovery(AbstractServiceDiscoveryFactory.java:53) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.registry.client.ServiceDiscoveryRegistry.getServiceDiscovery(ServiceDiscoveryRegistry.java:122) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.registry.client.ServiceDiscoveryRegistry.createServiceDiscovery(ServiceDiscoveryRegistry.java:109) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.registry.client.ServiceDiscoveryRegistry.<init>(ServiceDiscoveryRegistry.java:86) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.registry.client.ServiceDiscoveryRegistryFactory.createRegistry(ServiceDiscoveryRegistryFactory.java:35) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.registry.support.AbstractRegistryFactory.getRegistry(AbstractRegistryFactory.java:89) ~[dubbo-3.0.7.jar:3.0.7]
... 37 common frames omitted
Caused by: java.lang.IllegalStateException: failed to connect to zookeeper server
at org.apache.dubbo.registry.zookeeper.util.CuratorFrameworkUtils.buildCuratorFramework(CuratorFrameworkUtils.java:75) ~[dubbo-3.0.7.jar:3.0.7]
at org.apache.dubbo.registry.zookeeper.ZookeeperServiceDiscovery.<init>(ZookeeperServiceDiscovery.java:72) ~[dubbo-3.0.7.jar:3.0.7]
... 46 common frames omitted
2、缘起
前几天用springboot写了一个web项目,对外提供的是http请求接口,使用java程序调用不是很方便,于是想把它构建一个dubbo项目,方便服务间调用。在经过一系列的改造后,终于迎来了测试阶段。由于我是使用zookeeper作为注册中心,所以需要安装zookeeper(不会的可以自己查一下,网上教材很多)。由于嫌虚拟机麻烦,就直接在本机win10上启动了zookeeper,然后测试,程序服务注册和调用一切正常,No Problem!!!事情到这里本来是个美好的故事,然而……
为了更接近真实的开发环境,我决定在程序调试完毕后,将zookeeper安装到linux虚拟机中,然而就是这个决定,改变了故事的结局——感觉遇到了一个天坑。
3、求知
项目启动就报了第一个异常,本着有事问度娘的原则,第一个问题直接秒杀。简单说一下吧。
根据异常定位到 package org.apache.dubbo.remoting.zookeeper.curator 包下的CuratorZookeeperClient类,其构造方法代码(截取部分,全部代码可自行查看)如下
public class CuratorZookeeperClient extends AbstractZookeeperClient<CuratorZookeeperClient.NodeCacheListenerImpl, CuratorZookeeperClient.CuratorWatcherImpl> {
private final CuratorFramework client;
public CuratorZookeeperClient(URL url) {
super(url);
try {
int timeout = url.getParameter(TIMEOUT_KEY, DEFAULT_CONNECTION_TIMEOUT_MS);
int sessionExpireMs = url.getParameter(SESSION_KEY, DEFAULT_SESSION_TIMEOUT_MS);
CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder()
.connectString(url.getBackupAddress())
.retryPolicy(new RetryNTimes(1, 1000))
.connectionTimeoutMs(timeout)
.sessionTimeoutMs(sessionExpireMs);
String userInformation = url.getUserInformation();
if (StringUtils.isNotEmpty(userInformation)) {
builder = builder.authorization("digest", userInformation.getBytes());
}
client = builder.build();
client.getConnectionStateListenable().addListener(new CuratorConnectionStateListener(url));
client.start();
//第一个异常出现在这里
boolean connected = client.blockUntilConnected(timeout, TimeUnit.MILLISECONDS);
if (!connected) {
throw new IllegalStateException("zookeeper not connected");
}
} catch (Exception e) {
close();
throw new IllegalStateException(e.getMessage(), e);
}
}
}
解释一下这个CuratorZookeeperClient,它是对原生zookeeper客户端的一个封装,就好比mybatis是对原生JDBC的封装一样。CuratorZookeeperClient里面有个CuratorFramework类型的属性client,在这个属性中真正封装了一个zookeeper客户端。CuratorZookeeperClient的构造方法中传了一个URL对象,这个URL对象中封装了创建zookeeper客户端需要的参数信息,如下
zookeeper://192.168.0.106:2181/org.apache.dubbo.config.ConfigCenterConfig?block-until-connected-wait=3&blockUntilConnectedWait=3&check=true&config-file=dubbo.properties&group=dubbo&highest-priority=false&namespace=dubbo&timeout=30000
这就是一个URL地址,类似于http的get请求,“?”前面是协议和zookeeper主机地址,后面是参数。然后将参数提取出来,传到需要的方法中。而这些参数则是通过配置文件application.yml或application.properties文件配置的,如图
这里的参数会自动解析到URL中,当然不是所有的参数都会封装到URL中,只是封装一部分,如果没有定义相应参数,则会采用默认值。
public class CuratorZookeeperClient extends AbstractZookeeperClient<CuratorZookeeperClient.NodeCacheListenerImpl, CuratorZookeeperClient.CuratorWatcherImpl> {
private final CuratorFramework client;
public CuratorZookeeperClient(URL url) {
super(url);
try {
int timeout = url.getParameter(TIMEOUT_KEY, DEFAULT_CONNECTION_TIMEOUT_MS);
int sessionExpireMs = url.getParameter(SESSION_KEY, DEFAULT_SESSION_TIMEOUT_MS);
CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder()
.connectString(url.getBackupAddress())
.retryPolicy(new RetryNTimes(1, 1000))
.connectionTimeoutMs(timeout)
.sessionTimeoutMs(sessionExpireMs);
String userInformation = url.getUserInformation();
if (StringUtils.isNotEmpty(userInformation)) {
builder = builder.authorization("digest", userInformation.getBytes());
}
client = builder.build();
client.getConnectionStateListenable().addListener(new CuratorConnectionStateListener(url));
client.start();
//第一个异常出现在这里
boolean connected = client.blockUntilConnected(timeout, TimeUnit.MILLISECONDS);
if (!connected) {
throw new IllegalStateException("zookeeper not connected");
}
} catch (Exception e) {
close();
throw new IllegalStateException(e.getMessage(), e);
}
}
}
第一个异常出现的位置见代码注释,根据网友的解答,这里的异常是因为等待连接超时引起的。这里的timeout默认是30秒,就是说如果30秒内没有连接成功,就会报错。通常情况下本机的zookeeper连接可以在30秒内完成,但是虚拟机那边连接就贼慢。
到这里第一个异常就解决了,只需要配置timeout参数大一些即可,如图所示。
4、入坑
正当我微微一笑,心想不过如此,so easy时,转身掉进了一个天坑。
好家伙,知道原因后我这暴脾气直接给timeout干到250秒,等待项目起飞时,第二个异常来了。此时的我根本不知道事情的严重性,依然稳如一条老狗,默默打开百度……n分钟后,我特么傻了,整个网上都没有对这个异常的解决的帖子(反正我是没找到)。第二个异常信息里面有三个异常,我都搜了一遍,还是没找到。我真是醉了,难道这么多人都没遇到这个问题吗?然后怎么办呢,只能根据控制台信息排查。通过第二个异常的倒数第三行,我来到了这个类,如下(删除了部分源码,只留了报错的部分)
package org.apache.dubbo.registry.zookeeper.util;
public abstract class CuratorFrameworkUtils {
public static CuratorFramework buildCuratorFramework(URL connectionURL) throws Exception {
CuratorFramework curatorFramework = CuratorFrameworkFactory.builder()
.connectString(connectionURL.getBackupAddress())
.retryPolicy(buildRetryPolicy(connectionURL))
.build();
curatorFramework.start();
//这段代码是不是似曾相识?
curatorFramework.blockUntilConnected(BLOCK_UNTIL_CONNECTED_WAIT.getParameterValue(connectionURL),
BLOCK_UNTIL_CONNECTED_UNIT.getParameterValue(connectionURL));
if (!curatorFramework.getState().equals(CuratorFrameworkState.STARTED)) {
throw new IllegalStateException("zookeeper client initialization failed");
}
if (!curatorFramework.getZookeeperClient().isConnected()) {
//这里抛异常了
throw new IllegalStateException("failed to connect to zookeeper server");
}
return curatorFramework;
}
}
我一看这个代码,似曾相识啊,好家伙,这不是跟上一个异常一样吗?设置一下超时时间就行了吗?感觉不过如此,事实证明还是太年轻了啊。
通过源码中这个方法
curatorFramework.blockUntilConnected(BLOCK_UNTIL_CONNECTED_WAIT.getParameterValue(connectionURL),
BLOCK_UNTIL_CONNECTED_UNIT.getParameterValue(connectionURL));
我找到了这个枚举类。
package org.apache.dubbo.registry.zookeeper.util;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.registry.client.ServiceInstance;
import org.apache.curator.framework.CuratorFramework;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
/**
* The enumeration for the parameters of {@link CuratorFramework}
*
* @see CuratorFramework
* @since 2.7.5
*/
public enum CuratorFrameworkParams {
BLOCK_UNTIL_CONNECTED_WAIT("blockUntilConnectedWait", 10, Integer::valueOf),
/**
* The unit of time related to blocking on connection to Zookeeper.
*/
BLOCK_UNTIL_CONNECTED_UNIT("blockUntilConnectedUnit", TimeUnit.SECONDS, TimeUnit::valueOf),
;
private final String name;
private final Object defaultValue;
private final Function<String, Object> converter;
<T> CuratorFrameworkParams(String name, T defaultValue, Function<String, T> converter) {
this.name = name;
this.defaultValue = defaultValue;
this.converter = (Function<String, Object>) converter;
}
/**
* Get the parameter value from the specified {@link URL}
*
* @param url the Dubbo registry {@link URL}
* @param <T> the type of value
* @return the parameter value if present, or return <code>null</code>
*/
public <T> T getParameterValue(URL url) {
String param = url.getParameter(name);
Object value = param != null ? converter.apply(param) : defaultValue;
return (T) value;
}
}
发现这个BLOCK_UNTIL_CONNECTED_WAIT对象中设置了一个默认值10,也就是说10秒内连接不上就会报异常。好家伙,前面是30都不行,这里居然给个10。
为此我还把这段代码拿出来亲自测试了一下,测试代码如下
import org.apache.curator.CuratorZookeeperClient;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
public class TestCurator {
public static void main(String[] args) throws Exception {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
CuratorFramework client = CuratorFrameworkFactory.builder()
.connectString("192.168.0.106:2181")
// .connectString("localhost:2181")
.sessionTimeoutMs(5000) // 会话超时时间
.connectionTimeoutMs(5000) // 连接超时时间
.retryPolicy(retryPolicy)
.namespace("base")
.build();
client.start();
long l = System.currentTimeMillis();
//这里不传参数表示无限制等待
client.blockUntilConnected();
long l1 = System.currentTimeMillis();
long l2 = l1 - l;
//输出等待连接毫秒数
System.out.println(l2);
CuratorZookeeperClient zookeeperClient = client.getZookeeperClient();
boolean connected = zookeeperClient.isConnected();
System.out.println(connected);
}
}
经过测试,快则需要30+秒,慢则需要60+秒,有兴趣的可以自己测一下。
不过连接本机zookeeper居然啥事儿没有,看来本机还是快啊。根据经验,参数配置在配置文件中,只需输入参数名就会有提示。
没想到从这里就是噩梦的开始……
根据枚举对象中参数名称blockUntilConnectedWait,准备去配置文件中设置该属性的值。正当我输入该变量名称时,居然没有提示,没有提示意味着没有该变量属性。到这里,问题看上去已经解决了90%,只要找到变量设置一下值就行了。但是,其实就解决了10%,问题就出在这个变量去哪里设置?我找了好久也没看到这个变量的名字,然后默默打开了百度……结果啥也没有。这里问题就严重了,这得去源码里面找啊。最开始肯定去看dubbo的自动配置类啊,如下图,结果dubbo有两个自动配置的包。
我一眼就看到了第一个,忽略了第二个(不知道为啥有两个,一个不好吗),结果第一个包里没找到属性配置类(其实在第二个包里)。我反复看了几遍,这个自动配置类跟之前看过的其他组件的自动配置类套路咋不一样,找了半天没找到,我就以为URL的参数绑定肯定是在dubbo启动的时候通过spring完成的。肯定是spring封装好的URL直接给dubbo,然后dubbo给zookeeper(回头想想,我特么真佩服我的脑洞)。
然后我就从@EnableDubbo注解开始,一步一步调试dubbo。就想找到那个URL组装的地方,看看blockUntilConnectedWait属性怎么搞进去。卧槽了,真的,我特么从0点一直调试到4点多,就为了找那个URL组装的地方。结果没找到,我真的裂开,要吐了。
终于,我不知怎么看到了第二个自动配置的jar包,我进去一看,瞬间懂了,那个属性配置类就在这个包里面,参数是通过配置类自动映射绑定上去的,跟我之前想的一样,只不过没看到这个包。然后我把所有的属性配置类都看了一遍,还是没找到blockUntilConnectedWait这个属性。给我气的,我当时直接想去源码中把BLOCK_UNTIL_CONNECTED_WAIT对象的默认值给改了。
然后以为是idea配置文件提示有问题,强行设置blockUntilConnectedWait属性,但是不起作用。一看都特么快5点了,放弃了……
早上八点就起来了,吃完早饭坐在电脑前一遍一遍的看属性配置类的属性。直到我看到这个parameters参数
真是山重水复疑无路,柳暗花明又一村啊,我赶紧通过这个新的参数试了一下。
终于,设置成功了,这谁能想的到,事实证明,还是得看源码。至此,项目终于可以起飞了。
4、结语
![b657f36e7ce841ef862f36860cf73771.png](https://img-blog.csdnimg.cn/b657f36e7ce841ef862f36860cf73771.png)
版权归原作者 夜尽天明~ 所有, 如有侵权,请联系我们删除。