dubbo源码分析3-consumer订阅创建代理

本文详细分析了Dubbo消费者订阅创建代理的过程,包括RegistryDirectory的创建、消费者订阅信息的注册、服务端列表的订阅、容错层的创建等关键步骤。在创建RegistryDirectory时,保存并解析了订阅信息,通过Cluster.join()方法创建容错层,同时订阅服务提供者信息,以获取服务端列表、配置和路由信息。整个过程涉及到URL参数的合并、订阅信息的处理以及Invoker的创建与缓存。
摘要由CSDN通过智能技术生成

订阅创建代理的第一部分

红框之前的部分已经分析过,本文分析红框内的部分。

 

 

private <T> Invoker<T> doRefer(Cluster cluster, Registry registry, Class<T> type, URL url) {

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)) {

//注册consumer订阅信息

registry.register(subscribeUrl.addParameters(Constants.CATEGORY_KEY, Constants.CONSUMERS_CATEGORY,

Constants.CHECK_KEY, String.valueOf(false)));

}

//订阅并获取 服务端列表,配置,路由信息。然后连接服务端,并创建执行代理的invoker

directory.subscribe(subscribeUrl.addParameter(Constants.CATEGORY_KEY,

 

Constants.PROVIDERS_CATEGORY

+ "," + Constants.CONFIGURATORS_CATEGORY

+ "," + Constants.ROUTERS_CATEGORY));

//创建容错层

Invoker invoker = cluster.join(directory);

ProviderConsumerRegTable.registerConsumer(invoker, url, subscribeUrl, directory);

return invoker;

}

注意方法中黑体的部分,本文将围绕 这几个部分逐个分析

  1. 保存并解析了订阅信息。
  2. 注册consumer订阅信息
  3. 订阅并获取 服务端列表,配置,路由信息。然后连接服务端,并创建执行代理的invoker
  4. 创建容错层

 

RegistryDirectory创建分析

执行 RegistryProtocol.doRefer(Cluster, Registry, Class<T>, URL) 时创建,代码如下

RegistryDirectory<T> directory = new RegistryDirectory<T>(type, url);

directory.setRegistry(registry);

directory.setProtocol(protocol);

 

public RegistryDirectory(Class<T> serviceType, URL url) {

super(url);//保存url

if (serviceType == null)

throw new IllegalArgumentException("service type is null.");

if (url.getServiceKey() == null || url.getServiceKey().length() == 0)

throw new IllegalArgumentException("registry serviceKey is null.")

this.serviceType = serviceType;

this.serviceKey = url.getServiceKey();

//解析引用参数为map, 解析前的引用参数 url.getParameterAndDecoded(Constants.REFER_KEY): application=young-app&default.timeout=30000000&dubbo=2.6.2&interface=tuling.dubbo.server.UserService&loadbalance=consistenthash&methods=getUser&pid=25060&qos.enable=false&register.ip=169.254.23.140&side=consumer&timeout=30000000&timestamp=1573355812993

this.queryMap = StringUtils.parseQueryString(url.getParameterAndDecoded(Constants.REFER_KEY));

//url.setPath(url.getServiceInterface()).clearParameters()结果: zookeeper://127.0.0.1:2181/com.alibaba.dubbo.registry.RegistryService

//addParameters 将引用参数拼接在zookeeper://127.0.0.1:2181/com.alibaba.dubbo.registry.RegistryService后面

this.overrideDirectoryUrl = this.directoryUrl = url.setPath(url.getServiceInterface()).clearParameters().addParameters(queryMap).removeParameter(Constants.MONITOR_KEY);

String group = directoryUrl.getParameter(Constants.GROUP_KEY, "");

this.multiGroup = group != null && ("*".equals(group) || group.contains(","));//获取是否 配置多组

String methods = queryMap.get(Constants.METHODS_KEY);

this.serviceMethods = methods == null ? null : Constants.COMMA_SPLIT_PATTERN.split(methods);//解析方法名数组

}

创建 RegistryDirectory的过程就是保存并解析了订阅信息。

 

RegistryDirectory<T>.mergeUrl(URL) 分析

private URL mergeUrl(URL providerUrl) {

providerUrl = ClusterUtils.mergeUrl(providerUrl, queryMap); // Merge the consumer side parameters 合并 consumer端的参数

 

List<Configurator> localConfigurators = this.configurators; // local reference

if (localConfigurators != null && !localConfigurators.isEmpty()) {// 通过配置 更改providerUrl,需要详细分析。

for (Configurator configurator : localConfigurators) {

providerUrl = configurator.configure(providerUrl);

}

}

//不检查连接是否成功,总是创建invoker

providerUrl = providerUrl.addParameter(Constants.CHECK_KEY, String.valueOf(false));

 

// The combination of directoryUrl and override is at the end of notify, which can't be handled here

this.overrideDirectoryUrl = this.overrideDirectoryUrl.addParametersIfAbsent(providerUrl.getParameters()); //合并provider 的参数到overrideDirectoryUrl

 

if ((providerUrl.getPath() == null || providerUrl.getPath().length() == 0)// version 1.0 可能出现providerUrl path 为空的情况

&& "dubbo".equals(providerUrl.getProtocol())) { // Compatible version 1.0

//fix by tony.chenl DUBBO-44

String path = directoryUrl.getParameter(Constants.INTERFACE_KEY);

if (path != null) {

int i = path.indexOf('/');

if (i >= 0) {

path = path.substring(i + 1);

}

i = path.lastIndexOf(':');

if (i >= 0) {

path = path.substring(0, i);

}

providerUrl = providerUrl.setPath(path);

}

}

return providerUrl;

}

方法逻辑:合并consumer参数到 provoider 代表的providerUrl

ClusterUtils

将localMap的参数合并到remoteUrl中,将remoteUrl中的 filters and listeners合并到localMap中

public static URL mergeUrl(URL remoteUrl, Map<String, String> localMap) {

Map<String, String> map = new HashMap<String, String>();

Map<String, String> remoteMap = remoteUrl.getParameters();

 

if (remoteMap != null && remoteMap.size() > 0) {

map.putAll(remoteMap);

//一些参数 必须以localMap为准,移除被provider影响的参数

// Remove configurations from provider, some items should be affected by provider.

map.remove(Constants.THREAD_NAME_KEY);

map.remove(Constants.DEFAULT_KEY_PREFIX + Constants.THREAD_NAME_K

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值