最近在学习Dubbo和zookeeper,
问题:
在使用Dubbo时候,使用zookeeper作为配置元数据中心时候,使用如下配置
dubbo:
metadata-report:
address: zookeeper://127.0.0.1:2183?backup=127.0.0.1:2182,127.0.0.1:2181
password: 123456a
username: allUser
group: /spring_study_project/second_demo
注册中心和配置中心没有问题,但是metadata报错,根据错误信息显示zookeeper没有权限,但是反复确认后用用户名和密码正确
java.lang.IllegalStateException: KeeperErrorCode = NoAuth for /spring_study_project/second_demo/mapping
at org.apache.dubbo.remoting.zookeeper.curator.CuratorZookeeperClient.createPersistent(CuratorZookeeperClient.java:100)
at org.apache.dubbo.remoting.zookeeper.AbstractZookeeperClient.create(AbstractZookeeperClient.java:89)
at org.apache.dubbo.remoting.zookeeper.AbstractZookeeperClient.createOrUpdate(AbstractZookeeperClient.java:188)
at org.apache.dubbo.metadata.store.zookeeper.ZookeeperMetadataReport.registerServiceAppMapping(ZookeeperMetadataReport.java:200)
at org.apache.dubbo.registry.client.metadata.MetadataServiceNameMapping.map(MetadataServiceNameMapping.java:94)
at org.apache.dubbo.config.ServiceConfig.lambda$exported$1(ServiceConfig.java:257)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
at org.apache.dubbo.config.ServiceConfig.exported(ServiceConfig.java:253)
at org.apache.dubbo.config.spring.ServiceBean.exported(ServiceBean.java:123)
at org.apache.dubbo.config.ServiceConfig.doExport(ServiceConfig.java:362)
at org.apache.dubbo.config.ServiceConfig.export(ServiceConfig.java:233)
解决方案:
之前看过另外一种配置账户密码的方式,然后zookeeper正常创建metadata
#protocol://username:password@host:port/path?k1=v1&k2=v2
dubbo:
metadata-report:
address: zookeeper://allUser:123456a@127.0.0.1:2183?backup=127.0.0.1:2182,127.0.0.1:2181
group: /spring_study_project/second_demo
问题原因:
就比较好奇为啥,有这个配置username和password配置,为啥不生效,那就只能在代码中查找问题,
在MetaDataReportConfig.java 类中有把配置转换成URL类,其中address就是配置文件中的address,然后把address转换成URL对象
转换成URL对象后,获取url.getUsername()为空,所以返回的ServiceConfigURL没有用户名和密码
所以在CuratorZookeeperClient创建zookeeper Client时候使用URL对象读取userInformation 为空,创建的连接对象是错误的。
#MetaDataReportConfig.java
Map<String, String> map = new HashMap<String, String>();
URL url = URL.valueOf(address, getScopeModel());
// Issue : https://github.com/apache/dubbo/issues/6491
// Append the parameters from address
map.putAll(url.getParameters());
// Append or overrides the properties as parameters
appendParameters(map, this);
// Normalize the parameters
map.putAll(convert(map, null));
// put the protocol of URL as the "metadata"
map.put("metadata", isEmpty(url.getProtocol()) ? map.get(PROTOCOL_KEY) : url.getProtocol());
return new ServiceConfigURL("metadata", url.getUsername(), url.getPassword(), url.getHost(),
url.getPort(), url.getPath(), map).setScopeModel(getScopeModel());
# CuratorZookeeperClient.java
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();