Dubbo源码解析 --- DIRECTORY和ROUTER


今天看一下DirectoryRouter

我们直接从代码看起(一贯风格),先看后总结,对着总结再来看,相信会收获很多。我们先看com.alibaba.dubbo.config.ReferenceConfigcreateProxy

if (urls.size() == 1) {invoker = refprotocol.refer(interfaceClass, urls.get(0));
}
复制代码

这里我们之前说过了,根据扩展点,我们知道这里的protocol目前是RegistryProtocol,点进去:

return doRefer(cluster, registry, type, url);
复制代码

这里的cluster同样是扩展点,点进去:

RegistryDirectory<T> directory = new RegistryDirectory<T>(type, url);
directory.setRegistry(registry);
directory.setProtocol(protocol);
// all attributes of REFER_KEY
Map<String, String> parameters = new HashMap<String, String>(directory.getUrl().getParameters());
URL subscribeUrl = new URL(Constants.CONSUMER_PROTOCOL, parameters.remove(Constants.REGISTER_IP_KEY), 0, type.getName(), parameters);
if (!Constants.ANY_VALUE.equals(url.getServiceInterface())&& url.getParameter(Constants.REGISTER_KEY, true)) {registry.register(subscribeUrl.addParameters(Constants.CATEGORY_KEY, Constants.CONSUMERS_CATEGORY,Constants.CHECK_KEY, String.valueOf(false)));
}
directory.subscribe(subscribeUrl.addParameter(Constants.CATEGORY_KEY,Constants.PROVIDERS_CATEGORY+ "," + Constants.CONFIGURATORS_CATEGORY+ "," + Constants.ROUTERS_CATEGORY));Invoker invoker = cluster.join(directory);
ProviderConsumerRegTable.registerConsuemr(invoker, url, subscribeUrl, directory);
return invoker;
复制代码

这里出现了第一个东西:DIRECTORY,这里会用clusterjoin方法生成一个InvokerInvoker invoker = cluster.join(directory);,这里的clusterdebug一下,是FailoverCluster,生成的就是FailoverClusterInvoker。这里我们都没有发现这个Directory的作用,先别急,我们至少知道了AbstractClusterInvoker中有一个Directory的实例。

再看我们的AbstractClusterInvokerinvoke方法,这是Dubbo所有集群invoker的入口:

checkWhetherDestroyed();
LoadBalance loadbalance;
//注意这里
List<Invoker<T>> invokers = list(invocation);
if (invokers != null && invokers.size() > 0) {loadbalance = ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(invokers.get(0).getUrl().getMethodParameter(invocation.getMethodName(), Constants.LOADBALANCE_KEY, Constants.DEFAULT_LOADBALANCE));
} else {loadbalance = ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(Constants.DEFAULT_LOADBALANCE);
}
RpcUtils.attachInvocationIdIfAsync(getUrl(), invocation);
return doInvoke(invocation, invokers, loadbalance);
复制代码

这里有个list方法,返回的是invoker集合,doInvoke方法下沉到了子类,之前我们说过,这里会根据负载均衡策略选出一个invoker执行,那么我们看下list方法是如何选取invoker集合的:

//使用directory去选取
List<Invoker<T>> invokers = directory.list(invocation);
return invokers;
复制代码

点进去进入到AbstractDirectorylist方法:

List<Invoker<T>> invokers = doList(invocation);
//本地的routers
List<Router> localRouters = this.routers; // local reference
if (localRouters != null && localRouters.size() > 0) {for (Router router : localRouters) {try {if (router.getUrl() == null || router.getUrl().getParameter(Constants.RUNTIME_KEY, false)) {invokers = router.route(invokers, getConsumerUrl(), invocation);}} catch (Throwable t) {logger.error("Failed to execute router: " + getUrl() + ", cause: " + t.getMessage(), t);}}
}
复制代码

继续看一下doList,这里同样下沉到子类,子类有两个,分别是:RegistryDirectoryStaticDirectory,这两个的区别我们别的文章再说,这里简单提一下:RegistryDirectory中的invoker集合是动态的(实现了NotifyListener接口),而StaticDirectory中的invoker集合是固定的。

那么StaticDirectory返回的集合就是固定的,而RegistryDirectory是动态的,我们在注册中心对invoker做改动,都会引起RegistryDirectoryinvoker集合的变化。

这里我们大概就能理解这个Directory,实际上,这个东西就是Invoker的集合。

doList结束,下面就出现了我们说的Router,默认有三种实现:ConditionRouterMockInvokersSelector(虽然叫Selector)和ScriptRouter。这篇文章先不具体展开讨论每种Router的实现方式。

router返回的并不是一个Invoker,而是invoker集合,我们可以认为,router的作用就是把Directory中符合路由规则的invoker筛选出来,然后在这些invoker中,根据负载均衡策略和集群容错策略执行invoke方法。

总结一下: Directorinvoker的集合,是AbstractClusterInvoker的属性,可以认为是本集群下的所有InvokerRouter:从Directory中挑选出符合要求的Invoker集合。 LoadBalance:从Router挑选的invoker中再选出其中一个作为最终选择去执行invoke方法。

Dubbo源码解析 --- DIRECTORY和ROUTER相关推荐

  1. Dubbo源码解析 —— Router

    作者:肥朝 原文地址:http://www.jianshu.com/p/278e782eef85 友情提示:欢迎关注公众号[芋道源码].????关注后,拉你进[源码圈]微信群和[肥朝]搞基嗨皮. 友情 ...

  2. dubbo源码解析-集群容错架构设计

    前言 本来是想把整个dubbo源码解析一次性弄完,再做成一个系列来发布的,但是正巧最近有位好朋友要去杭州面试,就和我交流了一下.本着对dubbo源码略有心得的心态,在交流过程中也发表了个人的一些粗劣的 ...

  3. dubbo源码解析-逻辑层设计之服务降级

    Dubbo源码解析系列文章均来自肥朝简书 前言 在dubbo服务暴露系列完结之后,按计划来说是应该要开启dubbo服务引用的讲解.但是现在到了年尾,一些朋友也和我谈起了明年跳槽的事.跳槽这件事,无非也 ...

  4. dubbo源码解析之框架粗谈

    dubbo框架设计 一.dubbo框架整体设计 二.各层说明 三.dubbo工程模块分包 四.依赖关系 五.调用链 文章系列 [一.dubbo源码解析之框架粗谈] [二.dubbo源码解析之dubbo ...

  5. Dubbo源码解析-Dubbo服务消费者_Dubbo协议(一)

    前言: 在介绍完Dubbo 本地模式(Injvm协议)下的服务提供与消费后,上文我们又介绍了Dubbo远程模式(dubbo协议)下的服务暴露过程,本质上就是通过Netty将dubbo协议端口暴露出去, ...

  6. dubbo(5) Dubbo源码解析之服务调用过程

    来源:https://juejin.im/post/5ca4a1286fb9a05e731fc042 Dubbo源码解析之服务调用过程 简介 在前面的文章中,我们分析了 Dubbo SPI.服务导出与 ...

  7. dubbo源码解析(九)远程通信——Transport层

    远程通讯--Transport层 目标:介绍Transport层的相关设计和逻辑.介绍dubbo-remoting-api中的transport包内的源码解析. 前言 先预警一下,该文篇幅会很长,做好 ...

  8. dubbo源码解析-zookeeper创建节点

    前言 在之前dubbo源码解析-本地暴露中的前言部分提到了两道高频的面试题,其中一道dubbo中zookeeper做注册中心,如果注册中心集群都挂掉,那发布者和订阅者还能通信吗?在上周的dubbo源码 ...

  9. dubbo源码解析(二)

    大家好,我是烤鸭: dubbo 源码解析: 1.服务导出 介绍: Dubbo 服务导出过程始于 Spring 容器发布刷新事件,Dubbo 在接收到事件后,会立即执行服务导出逻辑.整个逻辑大致可分为三 ...

最新文章

  1. 看网友如何定义C++
  2. 组合使用Laravel和vfsStream测试文件上传
  3. 如何制定好的方案之三:实施策略是关键
  4. 滴滴自研分布式 NoSQL 数据库 Fusion 的演进之路
  5. 计算机面试数据库基本知识,面试基础知识集合(python、计算机网络、操作系统、数据结构、数据库等杂记)...
  6. uwp选取文件夹并读取其中的图片
  7. 均线带角度的指标_指标:均线斜率角度计算
  8. Docker 图形界面管理工具 -- Portainer
  9. 用于混合Spock 1.x和JUnit 5测试的Maven项目设置
  10. 您是否应该信任JVM中的默认设置?
  11. C/C++之vector的内存管理和效率
  12. SQL --几张表公有字段的查询
  13. 【每日算法Day 100】字节跳动 AI Lab 面试编程题(三道)
  14. 用友v11服务器的共享文件,用友U8系列财务及供应链一体化操作手册u8V11.1(标准)版.docx...
  15. 大地坐标系是不是经纬度_批量导入经纬度点到奥维地图中
  16. 鸟哥的linux私房菜中推荐的linux学习网站
  17. 调查上网行为管理软件(或设备)
  18. 计算机专业的英语六级很难过,英语六级多少分算过 通过率高吗
  19. 贝塞尔曲线(Bezier)之 QQ 消息拖拽动画效果
  20. Python爬虫|豆瓣图书Top250

热门文章

  1. 软件项目技术点(21)——自动保存和恢复
  2. Oracle——20数据库恢复与备份
  3. CRUD之delete操作
  4. android binder
  5. linux下字符编码转换
  6. C# 使用正则表达式去掉字符串中的数字
  7. Log4net中的RollingFileAppender解析
  8. 如何测试组件的性能?
  9. layui与eazyui的区别_jquery easyui和layui的区别是什么?
  10. 4G EPS 的架构模型