-
Notifications
You must be signed in to change notification settings - Fork 26.5k
dubbo2.7.5中多注册中心集群选址策略,只有preferred有效 #5654
Description
dubbo2.7.5中新增了4种多注册中心选址策略,分别为preferred,zone,weight,任意可用,
但是目前zone,weight是无效的,
原因在于在通过registryUrl创建RegistryDirectory时,会将registryUrl中的参数清楚, 但是仅仅保留了preferred这个参数. 代码见org.apache.dubbo.registry.integration.RegistryDirectory#RegistryDirectory,
该方法调用 turnRegistryUrlToConsumerUrl(url);将registryUrl做了转换,导致丢失了zone,weight两个参数
public RegistryDirectory(Class<T> serviceType, URL url) {
super(url);
if (serviceType == null) {
throw new IllegalArgumentException("service type is null.");
}
if (url.getServiceKey() == null || url.getServiceKey().length() == 0) {
throw new IllegalArgumentException("registry serviceKey is null.");
}
this.serviceType = serviceType;
this.serviceKey = url.getServiceKey();
this.queryMap = StringUtils.parseQueryString(url.getParameterAndDecoded(REFER_KEY));
//注意: 这里将registryUrl做了转换
this.overrideDirectoryUrl = this.directoryUrl = turnRegistryUrlToConsumerUrl(url);
String group = directoryUrl.getParameter(GROUP_KEY, "");
this.multiGroup = group != null && (ANY_VALUE.equals(group) || group.contains(","));
}
org.apache.dubbo.registry.integration.RegistryDirectory#turnRegistryUrlToConsumerUrl
该方法中只保留了PREFERRED_KEY即preferred这个参数,并设置前缀registry,但是丢失了zone,weight,导致这两个选址策略无效
private URL turnRegistryUrlToConsumerUrl(URL url) {
// save any parameter in registry that will be useful to the new url.
String isDefault = url.getParameter(PREFERRED_KEY);
if (StringUtils.isNotEmpty(isDefault)) {
queryMap.put(REGISTRY_KEY + "." + PREFERRED_KEY, isDefault);
}
return URLBuilder.from(url)
.setPath(url.getServiceInterface())
.clearParameters()
.addParameters(queryMap)
.removeParameter(MONITOR_KEY)
.build();
}
解决方案
方案1: 在turnRegistryUrlToConsumerUrl方法中,按照和preferred同样的方式,将zone,weight,添加上,
**方案缺点: ** 如果后期有更多关于注册中心的参数都可能需要这么做,容易忘记编码
方案2:(建议方式) 在turnRegistryUrlToConsumerUrl方法中,保留所有的RegistryConfig参数,并设置registry参数
**方案缺点: ** parameter参数多几个字段而已,无伤大雅
方案3: 在org.apache.dubbo.registry.integration.RegistryDirectory#RegistryDirectory类中,保存取原始的registryUrl, 即可获取RegistryConfig中的所有参数,
**方案缺点: **需要修改的类和方法比较多.
大致需要修改如下:
RegistryDirectory 添加成员变量,保存原始registryUrl
org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterInvoker 添加返回directory的方法
ZoneAwareClusterInvoker 中判断去除前缀