1 消费端如何通过注册中心获取远程服务的invoker?

RegistryDirectory.subscribe从注册中心中获取provider的url,通过DubboProtocol的refer方法生成Invoker。

以下代码为RegistryDirectory在收到zookeeper服务变更provider信息时(项目启动时从zookeeper获取到provider地址),把获取到的服务地址信息转成invoker的详细过程。

/**
* 将urls转成invokers,如果url已经被refer过,不再重新引用。
*
* @param urls
* @param overrides
* @param query
* @return invokers
*/
private Map<String, Invoker<T>> toInvokers(List<URL> urls) {
Map<String, Invoker<T>> newUrlInvokerMap = new HashMap<String, Invoker<T>>();
if(urls == null || urls.size() == 0){
return newUrlInvokerMap;
}
Set<String> keys = new HashSet<String>();
String queryProtocols = this.queryMap.get(Constants.PROTOCOL_KEY);
for (URL providerUrl : urls) {
//如果reference端配置了protocol,则只选择匹配的protocol
if (queryProtocols != null && queryProtocols.length() >0) {
boolean accept = false;
String[] acceptProtocols = queryProtocols.split(",");
for (String acceptProtocol : acceptProtocols) {
if (providerUrl.getProtocol().equals(acceptProtocol)) {
accept = true;
break;
}
}
if (!accept) {
continue;
}
}
if (Constants.EMPTY_PROTOCOL.equals(providerUrl.getProtocol())) {
continue;
}
if (! ExtensionLoader.getExtensionLoader(Protocol.class).hasExtension(providerUrl.getProtocol())) {
logger.error(new IllegalStateException("Unsupported protocol " + providerUrl.getProtocol() + " in notified url: " + providerUrl + " from registry " + getUrl().getAddress() + " to consumer " + NetUtils.getLocalHost()
+ ", supported protocol: "+ExtensionLoader.getExtensionLoader(Protocol.class).getSupportedExtensions()));
continue;
}
URL url = mergeUrl(providerUrl); String key = url.toFullString(); // URL参数是排序的
if (keys.contains(key)) { // 重复URL
continue;
}
keys.add(key);
// 缓存key为没有合并消费端参数的URL,不管消费端如何合并参数,如果服务端URL发生变化,则重新refer
Map<String, Invoker<T>> localUrlInvokerMap = this.urlInvokerMap; // local reference
Invoker<T> invoker = localUrlInvokerMap == null ? null : localUrlInvokerMap.get(key);
if (invoker == null) { // 缓存中没有,重新refer
try {
boolean enabled = true;
if (url.hasParameter(Constants.DISABLED_KEY)) {
enabled = ! url.getParameter(Constants.DISABLED_KEY, false);
} else {
enabled = url.getParameter(Constants.ENABLED_KEY, true);
}
if (enabled) {
invoker = new InvokerDelegete<T>(protocol.refer(serviceType, url), url, providerUrl);
}
} catch (Throwable t) {
logger.error("Failed to refer invoker for interface:"+serviceType+",url:("+url+")" + t.getMessage(), t);
}
if (invoker != null) { // 将新的引用放入缓存
newUrlInvokerMap.put(key, invoker);
}
}else {
newUrlInvokerMap.put(key, invoker);
}
}
keys.clear();
return newUrlInvokerMap;
}

最新文章

  1. egret调用页面js的方法。
  2. 多值(in),范围值(between..and)
  3. 破解excel密码保护
  4. js简单解密(eval解密)
  5. iptables规则组成
  6. 【UFLDL】Exercise: Convolutional Neural Network
  7. 4-JS对象
  8. XAML中的Path
  9. [转载]Thread.Sleep(0)妙用
  10. php 在线 mysql 大数据导入程序
  11. Kruskal算法的简单实现
  12. sublime text注册码(秘钥)
  13. .equals()到底是什么意思?
  14. .net webapi 接收 xml 格式数据的三种情况
  15. 谈谈Java中的代理模式
  16. JAVA常用工具类异常处理
  17. Linux - history命令的常用方法
  18. Ehcache缓存配置和基本使用
  19. 使用MultipartEntity对文字、图片、视频进行综合上传
  20. JSP复习

热门文章

  1. [转载]ubuntu常用命令
  2. React源码深度解析视频 某课网(完整版)
  3. 好用的 python 工具集合
  4. pytorch简单框架
  5. 终于要开始做大名鼎鼎的BombLab了!
  6. linux 网卡配置详情
  7. kotlin函数式编程入门及图片处理
  8. maven地址配置为阿里maven仓库,附ali maven官方指南链接
  9. Spring EntityResolver &quot;.dtd&quot; 和 &quot;.xsd&quot;检验
  10. docker 创建容器时指定容器ip