21.服务分组实现
分析服务分组的test case
我们假设的场景是,多idc机房,一个zk注册中心,我们通过分组设置达到,本机房的consumer调用本机房的provider。为了分析,我们假设了两个idc机房idc001和idc002
provider端的节点1服务配置上加上group:
<dubbo:service interface="com.code260.ss.dubbo.demov.facade.service.HelloService" ref="m00001.app001.xx.helloService"
group="idc001"/>
节点2的group设置为idc002。
consumer端节点1的ref配置上加上group:
<dubbo:reference id="helloService" interface="com.code260.ss.dubbo.demov.facade.service.HelloService" group="idc001"/>
与provider一样,节点2的group设置为idc002。
我们把case跑起来就能发现group为idc001的消费者调用group为idc001的provider,002的调用002的。
分析分组调用
从上面的case我们可以看出,我们要解决的问题,分组的消费组如何调用到对应分组的provider。
我直接贴下调用栈,这是启动consumer时构造proxy的场景,对于那种后起来的加进来的provider与之类似。
UrlUtils.isMatch(URL, URL) line: 375
ZookeeperRegistry.toUrlsWithoutEmpty(URL, List<String>) line: 258
ZookeeperRegistry.toUrlsWithEmpty(URL, String, List<String>) line: 268
ZookeeperRegistry.doSubscribe(URL, NotifyListener) line: 167
ZookeeperRegistry(FailbackRegistry).subscribe(URL, NotifyListener) line: 189
RegistryDirectory<T>.subscribe(URL) line: 133
RegistryProtocol.doRefer(Cluster, Registry, Class<T>, URL) line: 271
RegistryProtocol.refer(Class<T>, URL) line: 254
ProtocolFilterWrapper.refer(Class<T>, URL) line: 60
ProtocolListenerWrapper.refer(Class<T>, URL) line: 63
Protocol$Adpative.refer(Class, URL) line: not available
ReferenceBean<T>(ReferenceConfig<T>).createProxy(Map<String,String>) line: 392
我们在前面 09.消费者如何发现服务 一文中写过,在发现服务时,是靠添加监听器时并拿到children时,获得了provider列表。此处,是接着发现服务后的逻辑继续处理,在ZookeeperRegistry.doSubscribe发现了provider列表后,会通过UrlUtils.isMatch来匹配这个provider是要留下,匹配的字段里就有group,即比较consumer的group和provider是否一致,不一致的就丢弃了。version的机制也是在这里处理。
贴一下 比对的代码:
public static boolean isMatch(URL consumerUrl, URL providerUrl) {
String consumerInterface = consumerUrl.getServiceInterface();
String providerInterface = providerUrl.getServiceInterface();
if( ! (Constants.ANY_VALUE.equals(consumerInterface) || StringUtils.isEquals(consumerInterface, providerInterface)) ) return false;
if (! isMatchCategory(providerUrl.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY),
consumerUrl.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY))) {
return false;
}
if (! providerUrl.getParameter(Constants.ENABLED_KEY, true)
&& ! Constants.ANY_VALUE.equals(consumerUrl.getParameter(Constants.ENABLED_KEY))) {
return false;
}
String consumerGroup = consumerUrl.getParameter(Constants.GROUP_KEY);
String consumerVersion = consumerUrl.getParameter(Constants.VERSION_KEY);
String consumerClassifier = consumerUrl.getParameter(Constants.CLASSIFIER_KEY, Constants.ANY_VALUE);
String providerGroup = providerUrl.getParameter(Constants.GROUP_KEY);
String providerVersion = providerUrl.getParameter(Constants.VERSION_KEY);
String providerClassifier = providerUrl.getParameter(Constants.CLASSIFIER_KEY, Constants.ANY_VALUE);
return (Constants.ANY_VALUE.equals(consumerGroup) || StringUtils.isEquals(consumerGroup, providerGroup) || StringUtils.isContains(consumerGroup, providerGroup))
&& (Constants.ANY_VALUE.equals(consumerVersion) || StringUtils.isEquals(consumerVersion, providerVersion))
&& (consumerClassifier == null || Constants.ANY_VALUE.equals(consumerClassifier) || StringUtils.isEquals(consumerClassifier, providerClassifier));
}
当然这是分析的单分组的,如果是多分组的即group=”idc001,idc003”这种还有一些其他逻辑处理。
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!