======= RegistryDirectory =======
RegistryDirectoryextends AbstractDirectoryimplements NotifyListener
Directory代表多个Invoker,可以把它看成List,但与List不同的是,它的值可能是动态变化的,比如注册中心推送变更。RegistryDirectory 注册目录,目录服务;同时也是一个通知监听每一个接口会生成一个目录服务,同一个接口下的不同方法公用同一个目录服务。因为服务暴露和引用的URL都是以接口为维度的。客户端订阅的一个服务,可能有多个服务端提供,所以需要一个目录服务。1:当有新的服务端提供服务时,则通知当前目录服务,将Provider的url转成invoker,放入缓存 而在将url转成invoker的过程,又会做很多准备:如建立服务端端通信组件客户端,调用时通过其进行通信。 在一个框架中我们通常把负责数据交换和网络通信的组件叫做Exchanger。每个Invoker都维护了一个ExchangeClient的引用,并通过它和远程的Server进行通信。2:当客户端调用服务端服务时,根据客户端参数invocation,查找所有提供改服务的invoker列表,以供负载均衡作进一步选择
======= 主要成员变量 ======
private final URL directoryUrl;// Mapcache service url to invoker mapping.private volatile Map> urlInvokerMap;// Mapcache service method to invokers mapping.private volatile Map>> methodInvokerMap;// Setcache invokeUrls to invokers mapping. private volatile SetcachedInvokerUrls;//缓存的服务端url
==== 示例 ===
directoryUrl => consumer urlmulticast://224.5.6.7:1234/com.alibaba.dubbo.registry.RegistryService?application=consumer-of-helloworld-app&dubbo=2.5.3&interface=cn.tw.dubbo.intf.DemoService&methods=sayHello&pid=4604&side=consumer×tamp=1498724632185urlInvokerMap => url - invoker其中url是个合并过的,前半部分是provider的地址,后半部分是consumer的信息,invoker是为每个provider生成一个invoker形如,{ provider1+consumer = invoker1,provider2+consumer = invoker2 }{dubbo://130.130.10.146:20880/cn.tw.dubbo.intf.DemoService?anyhost=true&application=consumer-of-helloworld-app&check=false&dubbo=2.5.3&interface=cn.tw.dubbo.intf.DemoService&methods=sayHello&pid=4604&side=consumer×tamp=1498724632185=com.alibaba.dubbo.registry.integration.RegistryDirectory$InvokerDelegete@25d25f8d}methodInvokerMap => 方法 - invokers{*=[com.alibaba.dubbo.registry.integration.RegistryDirectory$InvokerDelegete@25d25f8d], sayHello=[com.alibaba.dubbo.registry.integration.RegistryDirectory$InvokerDelegete@25d25f8d]}cachedInvokerUrls => 服务端url[dubbo://130.130.10.146:20880/cn.tw.dubbo.intf.DemoService?anyhost=true&application=hello-world-app&dubbo=2.5.3&interface=cn.tw.dubbo.intf.DemoService&methods=sayHello&pid=11812&side=provider×tamp=1498463368943]
======== 主要方法 ======
//列出可以执行的Invoker//当客户端远程调用时触发//主要目的:通过invocation解析调用的方法,从缓存的methodInvokerMap中匹配Invokerpublic List> doList(Invocation invocation) { List> invokers = null; Map>> localMethodInvokerMap = this.methodInvokerMap; // local reference if (localMethodInvokerMap != null && localMethodInvokerMap.size() > 0) { String methodName = RpcUtils.getMethodName(invocation); Object[] args = RpcUtils.getArguments(invocation); if(args != null && args.length > 0 && args[0] != null && (args[0] instanceof String || args[0].getClass().isEnum())) { invokers = localMethodInvokerMap.get(methodName + "." + args[0]); // 可根据第一个参数枚举路由 } if(invokers == null) { invokers = localMethodInvokerMap.get(methodName); } if(invokers == null) { invokers = localMethodInvokerMap.get(Constants.ANY_VALUE); } if(invokers == null) { Iterator>> iterator = localMethodInvokerMap.values().iterator(); if (iterator.hasNext()) { invokers = iterator.next(); } } } return invokers == null ? new ArrayList>(0) : invokers;
}
网友评论