-
Notifications
You must be signed in to change notification settings - Fork 26.5k
当配置中心和注册中心在一个zk集群上,zk为未正常初始化问题 #4991
Copy link
Copy link
Closed
Labels
type/bugBugs to being fixedBugs to being fixedtype/need-triageNeed maintainers to triageNeed maintainers to triage
Milestone
Description
- I have searched the issues of this repository and believe that this is not a duplicate.
- I have checked the FAQ of this repository and believe that this is not a duplicate.
Environment
- Dubbo version: 2.7.3
- Operating System version: macOS 10.14.6
- Java version: 1.8
Steps to reproduce this issue
在我项目中,配置中心和注册中心都是使用zookeeper,而且是在一个集群上,只是 path 和对应的 username 和 password 不同,但是并未正常初始化两个不同的zk client。
项目启动时:
1、连接配置中心的地址,获取配置中心的配置信息
2、在初始化ReferenceBean和ServiceBean,会校验注册中心是否初始化
两者都通过 AbstractZookeeperTransporter#connect(URL url) 方法去连接zk
public abstract class AbstractZookeeperTransporter implements ZookeeperTransporter {
//缓存 zk client,key为zk地址
private final Map<String, ZookeeperClient> zookeeperClientMap = new ConcurrentHashMap<>();
@Override
public ZookeeperClient connect(URL url) {
ZookeeperClient zookeeperClient;
List<String> addressList = getURLBackupAddress(url);
// 这个地方会走缓存
if ((zookeeperClient = fetchAndUpdateZookeeperClientCache(addressList)) != null && zookeeperClient.isConnected()) {
logger.info("find valid zookeeper client from the cache for address: " + url);
return zookeeperClient;
}
。。。
}
ZookeeperClient fetchAndUpdateZookeeperClientCache(List<String> addressList) {
ZookeeperClient zookeeperClient = null;
for (String address : addressList) {
if ((zookeeperClient = zookeeperClientMap.get(address)) != null && zookeeperClient.isConnected()) {
break;
}
}
if (zookeeperClient != null && zookeeperClient.isConnected()) {
//将 zookeeperClient 放入 zookeeperClientMap 缓存中
writeToClientMap(addressList, zookeeperClient);
}
return zookeeperClient;
}
void writeToClientMap(List<String> addressList, ZookeeperClient zookeeperClient) {
for (String address : addressList) {
// 使用 address 作为key
zookeeperClientMap.put(address, zookeeperClient);
}
}
}
从上边可以看出,在初始化 配置中心的 zk client 后,就缓存到了 zookeeperClientMap 中。
当注册中心去初始化zk client 时,由于跟配置中心在一个集群上,所以 address相同,就会走缓存,返回 配置中心的 zk cliient。
总结:
如果配置中心和注册中心在一个集群上,zookeeperClientMap就不能使用address作为key。
通过上边两个图可以看出,配置中心 和 注册中心 传入的 URL信息里边的 path 是不相同的,将 zookeeperClientMap 的 key 使用 address + url.path 的方式生成,就可以解决这个问题
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
type/bugBugs to being fixedBugs to being fixedtype/need-triageNeed maintainers to triageNeed maintainers to triage
Type
Fields
Give feedbackNo fields configured for issues without a type.

