一、创建代理
1.1、registry、consumer等配置信息通过spring初始化,比如DubboNamespaceHandler
1.2、创建代理对象的时候,通过registry配置连接zookeeper注册并获取provider信息
ReferenceBean.getObject()
->return get(); --ReferenceBean
->init();
->map存放了registry、application等
->ref = createProxy(map);
->List<URL> us = loadRegistries(false);
->List<URL> registryList = new ArrayList<URL>();
->for (RegistryConfig config : registries)
->url = url.setProtocol(Constants.REGISTRY_PROTOCOL); //protocol是registry
->registryList.add(url);
->return registryList;
->for (URL u : us)
->urls.add(u.addParameterAndEncoded(Constants.REFER_KEY, StringUtils.toQueryString(map)));
->URL u = registryURL.addParameter(Constants.CLUSTER_KEY, AvailableCluster.NAME);
->List<Invoker<?>> invokers = new ArrayList<Invoker<?>>();
->for (URL url : urls) --ReferenceConfig
->invokers.add(refprotocol.refer(interfaceClass, url)); --url来自上面的loadRegistries(false)【ReferenceConfig.java】
->RegistryProtocol.refer(Class<T> type, URL url)
->Registry registry = registryFactory.getRegistry(url);
->return doRefer(cluster, registry, type, url);
->RegistryDirectory<T> directory = new RegistryDirectory<T>(type, url);
->directory.setRegistry(registry);
->directory.subscribe(subscribeUrl.addParameter(Constants.CATEGORY_KEY, ...
->registry.subscribe(url, this); --registry是ZookeeperRegistry
->return cluster.join(directory); --cluster是FailoverCluster
->return new FailoverClusterInvoker<T>(directory);
->URL u = registryURL.addParameter(Constants.CLUSTER_KEY, AvailableCluster.NAME);
->invoker = cluster.join(new StaticDirectory(u, invokers)); //将多个注册中心的invokers合并成一个invoker
->return (T) proxyFactory.getProxy(invoker);
->return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker));
->ref;
二、通过zookeeper订阅并获取服务
2.1、registry.subscribe(url, this)订阅zookeeper后,notify返回服务提供者的具体信息
2.2、为每个服务提供者创建DubboInvoker,如果connections=0,共享NettyClient
public synchronized void notify(List<URL> urls) --RegistryDirectory.java,继承NotifyListener
->for (URL url : urls)
->invokerUrls.add(url);
->refreshInvoker(invokerUrls);
->Map<String, Invoker<T>> newUrlInvokerMap = toInvokers(invokerUrls) ;// 将URL列表转成Invoker列表
/* ====================================注册DubboInvoker_S ===========================================*/
->invoker = new InvokerDelegete<T>(protocol.refer(serviceType, url), url, providerUrl); --protocol是DubboProtocol
->DubboInvoker<T> invoker = new DubboInvoker<T>(serviceType, url, getClients(url), invokers);
->private ExchangeClient[] getClients(URL url)
->ExchangeClient[] clients = new ExchangeClient[connections];
->clients[i] = initClient(url);
->return Exchangers.connect(url ,requestHandler);
->return invoker;
->newUrlInvokerMap.put(key, invoker);
/* ====================================注册DubboInvoker_E ===========================================*/
->Map<String, List<Invoker<T>>> newMethodInvokerMap = toMethodInvokers(newUrlInvokerMap); // 换方法名映射Invoker列表
->for (Invoker<T> invoker : invokersMap.values())
->List<Invoker<T>> methodInvokers = newMethodInvokerMap.get(method);
->methodInvokers.add(invoker);
->this.methodInvokerMap = multiGroup ? toMergeMethodInvokerMap(newMethodInvokerMap) : newMethodInvokerMap;
->this.urlInvokerMap = newUrlInvokerMap;
三、通过Netty调用服务
3.1、调用DubboInvoker远程访问,request和response的body中会有一个id,网络请求本身是共享并非阻塞的,采用Future默认控制同步还是异步返回结果
InvokerInvocationHandler.invoke(Object proxy, Method method, Object[] args)
->return invoker.invoke(new RpcInvocation(method, args)).recreate(); --invoker假设是FailoverClusterInvoker
/* ====================================Directory_获取有效的invokers_S ===========================================*/
->List<Invoker<T>> invokers = list(invocation);
->return directory.list(invocation); //directory是RegistryDirectory【AbstractClusterInvoker】
->List<Invoker<T>> invokers = doList(invocation); --AbstractDirectory
->invokers = localMethodInvokerMap.get(methodName); --RegistryDirectory
->invokers = router.route(invokers, getConsumerUrl(), invocation);
->return getNormalInvokers(invokers); --MockInvokersSelector
/* ====================================Directory_获取有效的invokers_E ===========================================*/
/* ====================================LoadBalance_通过算法取其中一个invoker _S ===========================================*/
->loadbalance = ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(invokers.get(0).getUrl().getMethodParameter(invocation.getMethodName(),Constants.LOADBALANCE_KEY, Constants.DEFAULT_LOADBALANCE));
->return doInvoke(invocation, invokers, loadbalance); --doInvoke在FailoverClusterInvoker
->for (int i = 0; i < len; i++)
->Invoker<T> invoker = select(loadbalance, invocation, copyinvokers, invoked);
/* ====================================LoadBalance_通过算法取其中一个invoker _E ===========================================*/
/* ====================================DubboInvoker调用_S ===========================================*/
->Result result = invoker.invoke(invocation); --假设invoker是DubboInvoker
->return doInvoke(invocation); --【AbstractInvoker.java】
->currentClient = clients[index.getAndIncrement() % clients.length];
====采用异步方式,调用远程服务
->if (isAsync)
->ResponseFuture future = currentClient.request(inv, timeout) ;
->RpcContext.getContext().setFuture(new FutureAdapter<Object>(future));
->return new RpcResult();
====采用同步方式,调用远程服务
->else
->return (Result) currentClient.request(inv, timeout).get();
->.request(inv, timeout)
->Request req = new Request();
->req.setData(request);
->DefaultFuture future = new DefaultFuture(channel, req, timeout);
->channel.send(req);
->return future;
->.get()
->return get(timeout); --DefaultFuture
->done.await(timeout, TimeUnit.MILLISECONDS); --DefaultFuture
->return returnFromResponse(); --DefaultFuture
->return res.getResult(); --DefaultFuture
->return result;
/* ====================================DubboInvoker调用_E ===========================================*/