#1046 The comments translation of registry-registry module (#1051)

This commit is contained in:
WangXin 2017-12-18 00:05:41 -06:00 committed by Ian Luo
parent c8093cf6cc
commit c774436e60
50 changed files with 776 additions and 925 deletions

View File

@ -1,12 +1,13 @@
<!--
- Copyright 1999-2011 Alibaba Group.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -22,22 +23,21 @@ import java.util.List;
/**
* NotifyListener. (API, Prototype, ThreadSafe)
*
* @author william.liangf
* @see com.alibaba.dubbo.registry.RegistryService#subscribe(URL, NotifyListener)
*/
public interface NotifyListener {
/**
* 当收到服务变更通知时触发
* Triggered when a service change notification is received.
* <p>
* 通知需处理契约<br>
* 1. 总是以服务接口和数据类型为维度全量通知即不会通知一个服务的同类型的部分数据用户不需要对比上一次通知结果<br>
* 2. 订阅时的第一次通知必须是一个服务的所有类型数据的全量通知<br>
* 3. 中途变更时允许不同类型的数据分开通知比如providers, consumers, routers, overrides允许只通知其中一种类型但该类型的数据必须是全量的不是增量的<br>
* 4. 如果一种类型的数据为空需通知一个empty协议并带category参数的标识性URL数据<br>
* 5. 通知者(即注册中心实现)需保证通知的顺序比如单线程推送队列串行化带版本对比<br>
* Notify needs to support the contract: <br>
* 1. Always notifications on the service interface and the dimension of the data type. that is, won't notify part of the same type data belonging to one service. Users do not need to compare the results of the previous notification.<br>
* 2. The first notification at a subscription must be a full notification of all types of data of a service.<br>
* 3. At the time of change, different types of data are allowed to be notified separately, e.g.: providers, consumers, routers, overrides. It allows only one of these types to be notified, but the data of this type must be full, not incremental.<br>
* 4. If a data type is empty, need to notify a empty protocol with category parameter identification of url data.<br>
* 5. The order of notifications to be guaranteed by the notifications(That is, the implementation of the registry). Such as: single thread push, queue serialization, and version comparison.<br>
*
* @param urls 已注册信息列表总不为空含义同{@link com.alibaba.dubbo.registry.RegistryService#lookup(URL)}的返回值
* @param urls The list of registered information , is always not empty. The meaning is the same as the return value of {@link com.alibaba.dubbo.registry.RegistryService#lookup(URL)}.
*/
void notify(List<URL> urls);

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -21,7 +22,6 @@ import com.alibaba.dubbo.common.URL;
/**
* Registry. (SPI, Prototype, ThreadSafe)
*
* @author william.liangf
* @see com.alibaba.dubbo.registry.RegistryFactory#getRegistry(URL)
* @see com.alibaba.dubbo.registry.support.AbstractRegistry
*/

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -22,25 +23,24 @@ import com.alibaba.dubbo.common.extension.SPI;
/**
* RegistryFactory. (SPI, Singleton, ThreadSafe)
*
* @author william.liangf
* @see com.alibaba.dubbo.registry.support.AbstractRegistryFactory
*/
@SPI("dubbo")
public interface RegistryFactory {
/**
* 连接注册中心.
* Connect to the registry
* <p>
* 连接注册中心需处理契约<br>
* 1. 当设置check=false时表示不检查连接否则在连接不上时抛出异常<br>
* 2. 支持URL上的username:password权限认证<br>
* 3. 支持backup=10.20.153.10备选注册中心集群地址<br>
* 4. 支持file=registry.cache本地磁盘文件缓存<br>
* 5. 支持timeout=1000请求超时设置<br>
* 6. 支持session=60000会话超时或过期设置<br>
* Connecting the registry needs to support the contract: <br>
* 1. When the check=false is set, the connection is not checked, otherwise the exception is thrown when disconnection <br>
* 2. Support username:password authority authentication on URL.<br>
* 3. Support the backup=10.20.153.10 candidate registry cluster address.<br>
* 4. Support file=registry.cache local disk file cache.<br>
* 5. Support the timeout=1000 request timeout setting.<br>
* 6. Support session=60000 session timeout or expiration settings.<br>
*
* @param url 注册中心地址不允许为空
* @return 注册中心引用总不返回空
* @param url Registry address, is not allowed to be empty
* @return Registry reference, never return empty value
*/
@Adaptive({"protocol"})
Registry getRegistry(URL url);

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -22,71 +23,70 @@ import java.util.List;
/**
* RegistryService. (SPI, Prototype, ThreadSafe)
*
* @author william.liangf
* @see com.alibaba.dubbo.registry.Registry
* @see com.alibaba.dubbo.registry.RegistryFactory#getRegistry(URL)
*/
public interface RegistryService {
/**
* 注册数据比如提供者地址消费者地址路由规则覆盖规则等数据
* Register data, such as : provider service, consumer address, route rule, override rule and other data.
* <p>
* 注册需处理契约<br>
* 1. 当URL设置了check=false时注册失败后不报错在后台定时重试否则抛出异常<br>
* 2. 当URL设置了dynamic=false参数则需持久存储否则当注册者出现断电等情况异常退出时需自动删除<br>
* 3. 当URL设置了category=routers时表示分类存储缺省类别为providers可按分类部分通知数据<br>
* 4. 当注册中心重启网络抖动不能丢失数据包括断线自动删除数据<br>
* 5. 允许URI相同但参数不同的URL并存不能覆盖<br>
* Registering is required to support the contract:<br>
* 1. When the URL sets the check=false parameter. When the registration fails, the exception is not thrown and retried in the background. Otherwise, the exception will be thrown.<br>
* 2. When URL sets the dynamic=false parameter, it needs to be stored persistently, otherwise, it should be deleted automatically when the registrant has an abnormal exit.<br>
* 3. When the URL sets category=routers, it means classified storage, the default category is providers, and the data can be notified by the classified section. <br>
* 4. When the registry is restarted, network jitter, data can not be lost, including automatically deleting data from the broken line.<br>
* 5. Allow URLs which have the same URL but different parameters to coexist,they can't cover each other.<br>
*
* @param url 注册信息不允许为空dubbo://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin
* @param url Registration information , is not allowed to be empty, e.g: dubbo://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin
*/
void register(URL url);
/**
* 取消注册.
* Unregister
* <p>
* 取消注册需处理契约<br>
* 1. 如果是dynamic=false的持久存储数据找不到注册数据则抛IllegalStateException否则忽略<br>
* 2. 按全URL匹配取消注册<br>
* Unregistering is required to support the contract:<br>
* 1. If it is the persistent stored data of dynamic=false, the registration data can not be found, then the IllegalStateException is thrown, otherwise it is ignored.<br>
* 2. Unregister according to the full url match.<br>
*
* @param url 注册信息不允许为空dubbo://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin
* @param url Registration information , is not allowed to be empty, e.g: dubbo://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin
*/
void unregister(URL url);
/**
* 订阅符合条件的已注册数据当有注册数据变更时自动推送.
* Subscrib to eligible registered data and automatically push when the registered data is changed.
* <p>
* 订阅需处理契约<br>
* 1. 当URL设置了check=false时订阅失败后不报错在后台定时重试<br>
* 2. 当URL设置了category=routers只通知指定分类的数据多个分类用逗号分隔并允许星号通配表示订阅所有分类数据<br>
* 3. 允许以interface,group,version,classifier作为条件查询interface=com.alibaba.foo.BarService&version=1.0.0<br>
* 4. 并且查询条件允许星号通配订阅所有接口的所有分组的所有版本interface=*&group=*&version=*&classifier=*<br>
* 5. 当注册中心重启网络抖动需自动恢复订阅请求<br>
* 6. 允许URI相同但参数不同的URL并存不能覆盖<br>
* 7. 必须阻塞订阅过程等第一次通知完后再返回<br>
* Subscribing need to support contracts:<br>
* 1. When the URL sets the check=false parameter. When the registration fails, the exception is not thrown and retried in the background. <br>
* 2. When URL sets category=routers, it only notifies the specified classification data. Multiple classifications are separated by commas, and allows asterisk to match, which indicates that all categorical data are subscribed.<br>
* 3. Allow interface, group, version, and classifier as a conditional query, e.g.: interface=com.alibaba.foo.BarService&version=1.0.0<br>
* 4. And the query conditions allow the asterisk to be matched, subscribe to all versions of all the packets of all interfaces, e.g. :interface=*&group=*&version=*&classifier=*<br>
* 5. When the registry is restarted and network jitter, it is necessary to automatically restore the subscription request.<br>
* 6. Allow URLs which have the same URL but different parameters to coexist,they can't cover each other.<br>
* 7. The subscription process must be blocked, when the first notice is finished and then returned.<br>
*
* @param url 订阅条件不允许为空consumer://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin
* @param listener 变更事件监听器不允许为空
* @param url Subscription condition, not allowed to be empty, e.g. consumer://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin
* @param listener A listener of the change event, not allowed to be empty
*/
void subscribe(URL url, NotifyListener listener);
/**
* 取消订阅.
* Unsubscribe
* <p>
* 取消订阅需处理契约<br>
* 1. 如果没有订阅直接忽略<br>
* 2. 按全URL匹配取消订阅<br>
* Unsubscribing is required to support the contract:<br>
* 1. If don't subscribe, ignore it directly.<br>
* 2. Unsubscribe by full URL match.<br>
*
* @param url 订阅条件不允许为空consumer://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin
* @param listener 变更事件监听器不允许为空
* @param url Subscription condition, not allowed to be empty, e.g. consumer://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin
* @param listener A listener of the change event, not allowed to be empty
*/
void unsubscribe(URL url, NotifyListener listener);
/**
* 查询符合条件的已注册数据与订阅的推模式相对应这里为拉模式只返回一次结果
* Query the registered data that matches the conditions. Corresponding to the push mode of the subscription, this is the pull mode and returns only one result.
*
* @param url 查询条件不允许为空consumer://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin
* @return 已注册信息列表可能为空含义同{@link com.alibaba.dubbo.registry.NotifyListener#notify(List<URL>)}的参数
* @param url Query condition, is not allowed to be empty, e.g. consumer://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin
* @return The registered information list, which may be empty, the meaning is the same as the parameters of {@link com.alibaba.dubbo.registry.NotifyListener#notify(List<URL>)}.
* @see com.alibaba.dubbo.registry.NotifyListener#notify(List)
*/
List<URL> lookup(URL url);

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -55,8 +56,6 @@ import java.util.Set;
/**
* RegistryDirectory
*
* @author william.liangf
* @author chao.liuc
*/
public class RegistryDirectory<T> extends AbstractDirectory<T> implements NotifyListener {
@ -67,33 +66,34 @@ public class RegistryDirectory<T> extends AbstractDirectory<T> implements Notify
private static final RouterFactory routerFactory = ExtensionLoader.getExtensionLoader(RouterFactory.class).getAdaptiveExtension();
private static final ConfiguratorFactory configuratorFactory = ExtensionLoader.getExtensionLoader(ConfiguratorFactory.class).getAdaptiveExtension();
private final String serviceKey; // 构造时初始化断言不为null
private final Class<T> serviceType; // 构造时初始化断言不为null
private final Map<String, String> queryMap; // 构造时初始化断言不为null
private final URL directoryUrl; // 构造时初始化断言不为null并且总是赋非null值
private final String serviceKey; // Initialization at construction time, assertion not null
private final Class<T> serviceType; // Initialization at construction time, assertion not null
private final Map<String, String> queryMap; // Initialization at construction time, assertion not null
private final URL directoryUrl; // Initialization at construction time, assertion not null, and always assign non null value
private final String[] serviceMethods;
private final boolean multiGroup;
private Protocol protocol; // 注入时初始化断言不为null
private Registry registry; // 注入时初始化断言不为null
private Protocol protocol; // Initialization at the time of injection, the assertion is not null
private Registry registry; // Initialization at the time of injection, the assertion is not null
private volatile boolean forbidden = false;
private volatile URL overrideDirectoryUrl; // 构造时初始化断言不为null并且总是赋非null值
private volatile URL overrideDirectoryUrl; // Initialization at construction time, assertion not null, and always assign non null value
/*override规则
* 优先级override>-D>consumer>provider
* 第一种规则针对某个provider <ip:port,timeout=100>
* 第二种规则针对所有provider <* ,timeout=5000>
/**
* override rules
* Priority: override>-D>consumer>provider
* Rule one: for a certain provider <ip:port,timeout=100>
* Rule two: for all providers <* ,timeout=5000>
*/
private volatile List<Configurator> configurators; // 初始为null以及中途可能被赋为null请使用局部变量引用
private volatile List<Configurator> configurators; // The initial value is null and the midway may be assigned to null, please use the local variable reference
// Map<url, Invoker> cache service url to invoker mapping.
private volatile Map<String, Invoker<T>> urlInvokerMap; // 初始为null以及中途可能被赋为null请使用局部变量引用
private volatile Map<String, Invoker<T>> urlInvokerMap; // The initial value is null and the midway may be assigned to null, please use the local variable reference
// Map<methodName, Invoker> cache service method to invokers mapping.
private volatile Map<String, List<Invoker<T>>> methodInvokerMap; // 初始为null以及中途可能被赋为null请使用局部变量引用
private volatile Map<String, List<Invoker<T>>> methodInvokerMap; // The initial value is null and the midway may be assigned to null, please use the local variable reference
// Set<invokerUrls> cache invokeUrls to invokers mapping.
private volatile Set<URL> cachedInvokerUrls; // 初始为null以及中途可能被赋为null请使用局部变量引用
private volatile Set<URL> cachedInvokerUrls; // The initial value is null and the midway may be assigned to null, please use the local variable reference
public RegistryDirectory(Class<T> serviceType, URL url) {
super(url);
@ -112,14 +112,14 @@ public class RegistryDirectory<T> extends AbstractDirectory<T> implements Notify
}
/**
* 将overrideURL转换为map供重新refer时使用.
* 每次下发全部规则全部重新组装计算
* Convert override urls to map for use when re-refer.
* Send all rules every time, the urls will be reassembled and calculated
*
* @param urls 契约
* </br>1.override://0.0.0.0/...(override://ip:port...?anyhost=true)&para1=value1...表示全局规则(对所有的提供者全部生效)
* </br>2.override://ip:port...?anyhost=false 特例规则只针对某个提供者生效
* </br>3.不支持override://规则... 需要注册中心自行计算.
* </br>4.不带参数的override://0.0.0.0/ 表示清除override
* @param urls Contract:
* </br>1.override://0.0.0.0/...( or override://ip:port...?anyhost=true)&para1=value1... means global rules (all of the providers take effect)
* </br>2.override://ip:port...?anyhost=false Special rules (only for a certain provider)
* </br>3.override:// rule is not supported... ,needs to be calculated by registry itself.
* </br>4.override://0.0.0.0/ without parameters means clearing the override
* @return
*/
public static List<Configurator> toConfigurators(List<URL> urls) {
@ -134,7 +134,7 @@ public class RegistryDirectory<T> extends AbstractDirectory<T> implements Notify
break;
}
Map<String, String> override = new HashMap<String, String>(url.getParameters());
//override 上的anyhost可能是自动添加的不能影响改变url判断
//The anyhost parameter of override may be added automatically, it can't change the judgement of changing url
override.remove(Constants.ANYHOST_KEY);
if (override.size() == 0) {
configurators.clear();
@ -171,7 +171,7 @@ public class RegistryDirectory<T> extends AbstractDirectory<T> implements Notify
} catch (Throwable t) {
logger.warn("unexpeced error when unsubscribe service " + serviceKey + "from registry" + registry.getUrl(), t);
}
super.destroy(); // 必须在unsubscribe之后执行
super.destroy(); // must be executed after unsubscribing
try {
destroyAllInvokers();
} catch (Throwable t) {
@ -210,7 +210,7 @@ public class RegistryDirectory<T> extends AbstractDirectory<T> implements Notify
}
}
List<Configurator> localConfigurators = this.configurators; // local reference
// 合并override参数
// merge override parameters
this.overrideDirectoryUrl = directoryUrl;
if (localConfigurators != null && localConfigurators.size() > 0) {
for (Configurator configurator : localConfigurators) {
@ -222,36 +222,36 @@ public class RegistryDirectory<T> extends AbstractDirectory<T> implements Notify
}
/**
* 根据invokerURL列表转换为invoker列表转换规则如下
* 1.如果url已经被转换为invoker则不在重新引用直接从缓存中获取注意如果url中任何一个参数变更也会重新引用
* 2.如果传入的invoker列表不为空则表示最新的invoker列表
* 3.如果传入的invokerUrl列表是空则表示只是下发的override规则或route规则需要重新交叉对比决定是否需要重新引用
* Convert the invokerURL list to the Invoker Map. The rules of the conversion are as follows:
* 1.If URL has been converted to invoker, it is no longer re-referenced and obtained directly from the cache, and notice that any parameter changes in the URL will be re-referenced.
* 2.If the incoming invoker list is not empty, it means that it is the latest invoker list
* 3.If the list of incoming invokerUrl is empty, It means that the rule is only a override rule or a route rule, which needs to be re-contrasted to decide whether to re-reference.
*
* @param invokerUrls 传入的参数不能为null
* @param invokerUrls this parameter can't be null
*/
// TODO: 2017/8/31 FIXME 使用线程池去刷新地址否则可能会导致任务堆积
// TODO: 2017/8/31 FIXME The thread pool should be used to refresh the address, otherwise the task may be accumulated.
private void refreshInvoker(List<URL> invokerUrls) {
if (invokerUrls != null && invokerUrls.size() == 1 && invokerUrls.get(0) != null
&& Constants.EMPTY_PROTOCOL.equals(invokerUrls.get(0).getProtocol())) {
this.forbidden = true; // 禁止访问
this.methodInvokerMap = null; // 置空列表
destroyAllInvokers(); // 关闭所有Invoker
this.forbidden = true; // Forbid to access
this.methodInvokerMap = null; // Set the method invoker map to null
destroyAllInvokers(); // Close all invokers
} else {
this.forbidden = false; // 允许访问
this.forbidden = false; // Allow to access
Map<String, Invoker<T>> oldUrlInvokerMap = this.urlInvokerMap; // local reference
if (invokerUrls.size() == 0 && this.cachedInvokerUrls != null) {
invokerUrls.addAll(this.cachedInvokerUrls);
} else {
this.cachedInvokerUrls = new HashSet<URL>();
this.cachedInvokerUrls.addAll(invokerUrls);//缓存invokerUrls列表便于交叉对比
this.cachedInvokerUrls.addAll(invokerUrls);//Cached invoker urls, convenient for comparison
}
if (invokerUrls.size() == 0) {
return;
}
Map<String, Invoker<T>> newUrlInvokerMap = toInvokers(invokerUrls);// 将URL列表转成Invoker列表
Map<String, List<Invoker<T>>> newMethodInvokerMap = toMethodInvokers(newUrlInvokerMap); // 换方法名映射Invoker列表
Map<String, Invoker<T>> newUrlInvokerMap = toInvokers(invokerUrls);// Translate url list to Invoker map
Map<String, List<Invoker<T>>> newMethodInvokerMap = toMethodInvokers(newUrlInvokerMap); // Change method name to map Invoker Map
// state change
//如果计算错误则不进行处理.
// If the calculation is wrong, it is not processed.
if (newUrlInvokerMap == null || newUrlInvokerMap.size() == 0) {
logger.error(new IllegalStateException("urls to invokers error .invokerUrls.size :" + invokerUrls.size() + ", invoker.size :0. urls :" + invokerUrls.toString()));
return;
@ -259,7 +259,7 @@ public class RegistryDirectory<T> extends AbstractDirectory<T> implements Notify
this.methodInvokerMap = multiGroup ? toMergeMethodInvokerMap(newMethodInvokerMap) : newMethodInvokerMap;
this.urlInvokerMap = newUrlInvokerMap;
try {
destroyUnusedInvokers(oldUrlInvokerMap, newUrlInvokerMap); // 关闭未使用的Invoker
destroyUnusedInvokers(oldUrlInvokerMap, newUrlInvokerMap); // Close the unused Invoker
} catch (Exception e) {
logger.warn("destroyUnusedInvokers error. ", e);
}
@ -328,11 +328,9 @@ public class RegistryDirectory<T> extends AbstractDirectory<T> implements Notify
}
/**
* 将urls转成invokers,如果url已经被refer过不再重新引用
* Turn urls into invokers, and if url has been refer, will not re-reference.
*
* @param urls
* @param overrides
* @param query
* @return invokers
*/
private Map<String, Invoker<T>> toInvokers(List<URL> urls) {
@ -343,7 +341,7 @@ public class RegistryDirectory<T> extends AbstractDirectory<T> implements Notify
Set<String> keys = new HashSet<String>();
String queryProtocols = this.queryMap.get(Constants.PROTOCOL_KEY);
for (URL providerUrl : urls) {
//如果reference端配置了protocol则只选择匹配的protocol
// If protocol is configured at the reference side, only the matching protocol is selected
if (queryProtocols != null && queryProtocols.length() > 0) {
boolean accept = false;
String[] acceptProtocols = queryProtocols.split(",");
@ -367,15 +365,15 @@ public class RegistryDirectory<T> extends AbstractDirectory<T> implements Notify
}
URL url = mergeUrl(providerUrl);
String key = url.toFullString(); // URL参数是排序的
if (keys.contains(key)) { // 重复URL
String key = url.toFullString(); // The parameter urls are sorted
if (keys.contains(key)) { // Repeated url
continue;
}
keys.add(key);
// 缓存key为没有合并消费端参数的URL不管消费端如何合并参数如果服务端URL发生变化则重新refer
// Cache key is url that does not merge with consumer side parameters, regardless of how the consumer combines parameters, if the server url changes, then refer again
Map<String, Invoker<T>> localUrlInvokerMap = this.urlInvokerMap; // local reference
Invoker<T> invoker = localUrlInvokerMap == null ? null : localUrlInvokerMap.get(key);
if (invoker == null) { // 缓存中没有重新refer
if (invoker == null) { // Not in the cache, refer again
try {
boolean enabled = true;
if (url.hasParameter(Constants.DISABLED_KEY)) {
@ -384,12 +382,12 @@ public class RegistryDirectory<T> extends AbstractDirectory<T> implements Notify
enabled = url.getParameter(Constants.ENABLED_KEY, true);
}
if (enabled) {
invoker = new InvokerDelegete<T>(protocol.refer(serviceType, url), url, providerUrl);
invoker = new InvokerDelegate<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) { // 将新的引用放入缓存
if (invoker != null) { // Put new invoker in cache
newUrlInvokerMap.put(key, invoker);
}
} else {
@ -401,14 +399,13 @@ public class RegistryDirectory<T> extends AbstractDirectory<T> implements Notify
}
/**
* 合并url参数 顺序为override > -D >Consumer > Provider
* Merge url parameters. the order is: override > -D >Consumer > Provider
*
* @param providerUrl
* @param overrides
* @return
*/
private URL mergeUrl(URL providerUrl) {
providerUrl = ClusterUtils.mergeUrl(providerUrl, queryMap); // 合并消费端参数
providerUrl = ClusterUtils.mergeUrl(providerUrl, queryMap); // Merge the consumer side parameters
List<Configurator> localConfigurators = this.configurators; // local reference
if (localConfigurators != null && localConfigurators.size() > 0) {
@ -417,13 +414,13 @@ public class RegistryDirectory<T> extends AbstractDirectory<T> implements Notify
}
}
providerUrl = providerUrl.addParameter(Constants.CHECK_KEY, String.valueOf(false)); // 不检查连接是否成功总是创建Invoker
providerUrl = providerUrl.addParameter(Constants.CHECK_KEY, String.valueOf(false)); // Do not check whether the connection is successful or not, always create Invoker!
//directoryUrl override 合并是在notify的最后这里不能够处理
this.overrideDirectoryUrl = this.overrideDirectoryUrl.addParametersIfAbsent(providerUrl.getParameters()); // 合并提供者参数
// 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()); // Merge the provider side parameters
if ((providerUrl.getPath() == null || providerUrl.getPath().length() == 0)
&& "dubbo".equals(providerUrl.getProtocol())) { // 兼容1.0
&& "dubbo".equals(providerUrl.getProtocol())) { // Compatible version 1.0
//fix by tony.chenl DUBBO-44
String path = directoryUrl.getParameter(Constants.INTERFACE_KEY);
if (path != null) {
@ -455,14 +452,14 @@ public class RegistryDirectory<T> extends AbstractDirectory<T> implements Notify
}
/**
* 将invokers列表转成与方法的映射关系
* Transform the invokers list into a mapping relationship with a method
*
* @param invokersMap Invoker列表
* @return Invoker与方法的映射关系
* @param invokersMap Invoker Map
* @return Mapping relation between Invoker and method
*/
private Map<String, List<Invoker<T>>> toMethodInvokers(Map<String, Invoker<T>> invokersMap) {
Map<String, List<Invoker<T>>> newMethodInvokerMap = new HashMap<String, List<Invoker<T>>>();
// 按提供者URL所声明的methods分类兼容注册中心执行路由过滤掉的methods
// According to the methods classification declared by the provider URL, the methods is compatible with the registry to execute the filtered methods
List<Invoker<T>> invokersList = new ArrayList<Invoker<T>>();
if (invokersMap != null && invokersMap.size() > 0) {
for (Invoker<T> invoker : invokersMap.values()) {
@ -507,7 +504,7 @@ public class RegistryDirectory<T> extends AbstractDirectory<T> implements Notify
}
/**
* 关闭所有Invoker
* Close all invokers
*/
private void destroyAllInvokers() {
Map<String, Invoker<T>> localUrlInvokerMap = this.urlInvokerMap; // local reference
@ -525,10 +522,11 @@ public class RegistryDirectory<T> extends AbstractDirectory<T> implements Notify
}
/**
* 检查缓存中的invoker是否需要被destroy
* 如果url中指定refer.autodestroy=false则只增加不减少可能会有refer泄漏
* Check whether the invoker in the cache needs to be destroyed
* If set attribute of url: refer.autodestroy=false, the invokers will only increase without decreasing,there may be a refer leak
*
* @param invokers
* @param oldUrlInvokerMap
* @param newUrlInvokerMap
*/
private void destroyUnusedInvokers(Map<String, Invoker<T>> oldUrlInvokerMap, Map<String, Invoker<T>> newUrlInvokerMap) {
if (newUrlInvokerMap == null || newUrlInvokerMap.size() == 0) {
@ -570,7 +568,7 @@ public class RegistryDirectory<T> extends AbstractDirectory<T> implements Notify
public List<Invoker<T>> doList(Invocation invocation) {
if (forbidden) {
// 1. 没有服务提供者 2. 服务提供者被禁用
// 1. No service provider 2. Service providers are disabled
throw new RpcException(RpcException.FORBIDDEN_EXCEPTION,
"No provider available from registry " + getUrl().getAddress() + " for service " + getConsumerUrl().getServiceKey() + " on consumer " + NetUtils.getLocalHost()
+ " use dubbo version " + Version.getVersion() + ", may be providers disabled or not registered ?");
@ -582,7 +580,7 @@ public class RegistryDirectory<T> extends AbstractDirectory<T> implements Notify
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]); // 可根据第一个参数枚举路由
invokers = localMethodInvokerMap.get(methodName + "." + args[0]); // The routing can be enumerated according to the first parameter
}
if (invokers == null) {
invokers = localMethodInvokerMap.get(methodName);
@ -655,15 +653,14 @@ public class RegistryDirectory<T> extends AbstractDirectory<T> implements Notify
}
/**
* 代理类主要用于存储注册中心下发的url地址用于重新重新refer时能够根据providerURL queryMap overrideMap重新组装
* The delegate class, which is mainly used to store the URL address sent by the registry,and can be reassembled on the basis of providerURL queryMap overrideMap for re-refer.
*
* @param <T>
* @author chao.liuc
*/
private static class InvokerDelegete<T> extends InvokerWrapper<T> {
private static class InvokerDelegate<T> extends InvokerWrapper<T> {
private URL providerUrl;
public InvokerDelegete(Invoker<T> invoker, URL url, URL providerUrl) {
public InvokerDelegate(Invoker<T> invoker, URL url, URL providerUrl) {
super(invoker, url);
this.providerUrl = providerUrl;
}

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -45,15 +46,13 @@ import java.util.concurrent.ConcurrentHashMap;
/**
* RegistryProtocol
*
* @author william.liangf
* @author chao.liuc
*/
public class RegistryProtocol implements Protocol {
private final static Logger logger = LoggerFactory.getLogger(RegistryProtocol.class);
private static RegistryProtocol INSTANCE;
private final Map<URL, NotifyListener> overrideListeners = new ConcurrentHashMap<URL, NotifyListener>();
//用于解决rmi重复暴露端口冲突的问题已经暴露过的服务不再重新暴露
//To solve the problem of RMI repeated exposure port conflicts, the services that have been exposed are no longer exposed.
//providerurl <--> exporter
private final Map<String, ExporterChangeableWrapper<?>> bounds = new ConcurrentHashMap<String, ExporterChangeableWrapper<?>>();
private Cluster cluster;
@ -72,7 +71,7 @@ public class RegistryProtocol implements Protocol {
return INSTANCE;
}
//过滤URL中不需要输出的参数(以点号开头的)
//Filter the parameters that do not need to be output in url(Starting with .)
private static String[] getFilteredKeys(URL url) {
Map<String, String> params = url.getParameters();
if (params != null && !params.isEmpty()) {
@ -137,13 +136,13 @@ public class RegistryProtocol implements Protocol {
ProviderConsumerRegTable.getProviderWrapper(originInvoker).setReg(true);
}
// 订阅override数据
// FIXME 提供者订阅时会影响同一JVM即暴露服务又引用同一服务的的场景因为subscribed以服务名为缓存的key导致订阅信息覆盖
// Subscribe the override data
// FIXME When the provider subscribes, it will affect the scene : a certain JVM exposes the service and call the same service. Because the subscribed is cached key with the name of the service, it causes the subscription information to cover.
final URL overrideSubscribeUrl = getSubscribedOverrideUrl(registedProviderUrl);
final OverrideListener overrideSubscribeListener = new OverrideListener(overrideSubscribeUrl, originInvoker);
overrideListeners.put(overrideSubscribeUrl, overrideSubscribeListener);
registry.subscribe(overrideSubscribeUrl, overrideSubscribeListener);
//保证每次export都返回一个新的exporter实例
//Ensure that a new exporter instance is returned every time export
return new Exporter<T>() {
public Invoker<T> getInvoker() {
return exporter.getInvoker();
@ -188,7 +187,7 @@ public class RegistryProtocol implements Protocol {
}
/**
* 对修改了url的invoker重新export
* Reexport the invoker of the modified url
*
* @param originInvoker
* @param newInvokerUrl
@ -206,7 +205,7 @@ public class RegistryProtocol implements Protocol {
}
/**
* 根据invoker的地址获取registry实例
* Get an instance of registry based on the address of invoker
*
* @param originInvoker
* @return
@ -227,14 +226,14 @@ public class RegistryProtocol implements Protocol {
/**
* 返回注册到注册中心的URL对URL参数进行一次过滤
* Return the url that is registered to the registry and filter the url parameter once
*
* @param originInvoker
* @return
*/
private URL getRegistedProviderUrl(final Invoker<?> originInvoker) {
URL providerUrl = getProviderUrl(originInvoker);
//注册中心看到的地址
//The address you see at the registry
final URL registedProviderUrl = providerUrl.removeParameters(getFilteredKeys(providerUrl))
.removeParameter(Constants.MONITOR_KEY)
.removeParameter(Constants.BIND_IP_KEY)
@ -249,7 +248,7 @@ public class RegistryProtocol implements Protocol {
}
/**
* 通过invoker的url 获取 providerUrl的地址
* Get the address of the providerUrl through the url of the invoker
*
* @param origininvoker
* @return
@ -265,7 +264,7 @@ public class RegistryProtocol implements Protocol {
}
/**
* 获取invoker在bounds中缓存的key
* Get the key cached in bounds by invoker
*
* @param originInvoker
* @return
@ -304,7 +303,7 @@ public class RegistryProtocol implements Protocol {
RegistryDirectory<T> directory = new RegistryDirectory<T>(type, url);
directory.setRegistry(registry);
directory.setProtocol(protocol);
// REFER_KEY的所有属性
// 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())
@ -335,7 +334,7 @@ public class RegistryProtocol implements Protocol {
/**
* @param invoker
* @param url invoker.getUrl返回此值
* @param url invoker.getUrl return this value
*/
public InvokerDelegete(Invoker<T> invoker, URL url) {
super(invoker, url);
@ -351,10 +350,11 @@ public class RegistryProtocol implements Protocol {
}
}
/*重新export 1.protocol中的exporter destory问题
*1.要求registryprotocol返回的exporter可以正常destroy
*2.notify后不需要重新向注册中心注册
*3.export 方法传入的invoker最好能一直作为exporter的invoker.
/**
* Reexport: the exporter destroy problem in protocol
* 1.Ensure that the exporter returned by registryprotocol can be normal destroyed
* 2.No need to re-register to the registry after notify
* 3.The invoker passed by the export method , would better to be the invoker of exporter
*/
private class OverrideListener implements NotifyListener {
@ -367,13 +367,13 @@ public class RegistryProtocol implements Protocol {
}
/**
* @param urls 已注册信息列表总不为空含义同{@link com.alibaba.dubbo.registry.RegistryService#lookup(URL)}的返回值
* @param urls The list of registered information , is always not empty, The meaning is the same as the return value of {@link com.alibaba.dubbo.registry.RegistryService#lookup(URL)}.
*/
public synchronized void notify(List<URL> urls) {
logger.debug("original override urls: " + urls);
List<URL> matchedUrls = getMatchedUrls(urls, subscribeUrl);
logger.debug("subscribe url: " + subscribeUrl + ", override urls: " + matchedUrls);
//没有匹配的
// No matching results
if (matchedUrls.isEmpty()) {
return;
}
@ -386,7 +386,7 @@ public class RegistryProtocol implements Protocol {
} else {
invoker = originInvoker;
}
//最原始的invoker
//The origin invoker
URL originUrl = RegistryProtocol.this.getProviderUrl(invoker);
String key = getCacheKey(originInvoker);
ExporterChangeableWrapper<?> exporter = bounds.get(key);
@ -394,9 +394,9 @@ public class RegistryProtocol implements Protocol {
logger.warn(new IllegalStateException("error state, exporter should not be null"));
return;
}
//当前的可能经过了多次merge
//The current, may have been merged many times
URL currentUrl = exporter.getInvoker().getUrl();
//与本次配置merge的
//Merged with this configuration
URL newUrl = getConfigedInvokerUrl(configurators, originUrl);
if (!currentUrl.equals(newUrl)) {
RegistryProtocol.this.doChangeLocalExport(originInvoker, newUrl);
@ -408,13 +408,13 @@ public class RegistryProtocol implements Protocol {
List<URL> result = new ArrayList<URL>();
for (URL url : configuratorUrls) {
URL overrideUrl = url;
// 兼容旧版本
// Compatible with the old version
if (url.getParameter(Constants.CATEGORY_KEY) == null
&& Constants.OVERRIDE_PROTOCOL.equals(url.getProtocol())) {
overrideUrl = url.addParameter(Constants.CATEGORY_KEY, Constants.CONFIGURATORS_CATEGORY);
}
//检查是不是要应用到当前服务上
// Check whether url is to be applied to the current service
if (UrlUtils.isMatch(currentSubscribe, overrideUrl)) {
result.add(url);
}
@ -422,7 +422,7 @@ public class RegistryProtocol implements Protocol {
return result;
}
//合并配置的url
//Merge the urls of configurators
private URL getConfigedInvokerUrl(List<Configurator> configurators, URL url) {
for (Configurator configurator : configurators) {
url = configurator.configure(url);
@ -432,10 +432,9 @@ public class RegistryProtocol implements Protocol {
}
/**
* exporter代理,建立返回的exporter与protocol export出的exporter的对应关系在override时可以进行关系修改.
* exporter proxy, establish the corresponding relationship between the returned exporter and the exporter exported by the protocol, and can modify the relationship at the time of override.
*
* @param <T>
* @author chao.liuc
*/
private class ExporterChangeableWrapper<T> implements Exporter<T> {

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -30,7 +31,6 @@ import java.util.Set;
/**
* RegisteredPageHandler
*
* @author william.liangf
*/
public class RegisteredPageHandler implements PageHandler {

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -31,7 +32,6 @@ import java.util.List;
/**
* RegistriesPageHandler
*
* @author william.liangf
*/
@Menu(name = "Registries", desc = "Show connected registries.", order = 10000)
public class RegistriesPageHandler implements PageHandler {

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -30,7 +31,6 @@ import java.util.Set;
/**
* SubscribedPageHandler
*
* @author william.liangf
*/
public class SubscribedPageHandler implements PageHandler {

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -26,7 +27,6 @@ import java.util.Collection;
/**
* RegistryStatusChecker
*
* @author william.liangf
*/
@Activate
public class RegistryStatusChecker implements StatusChecker {

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -52,36 +53,34 @@ import java.util.concurrent.atomic.AtomicReference;
/**
* AbstractRegistry. (SPI, Prototype, ThreadSafe)
*
* @author chao.liuc
* @author william.liangf
*/
public abstract class AbstractRegistry implements Registry {
// URL地址分隔符用于文件缓存中服务提供者URL分隔
// URL address separator, used in file cache, service provider URL separation
private static final char URL_SEPARATOR = ' ';
// URL地址分隔正则表达式用于解析文件缓存中服务提供者URL列表
// URL address separated regular expression for parsing the service provider URL list in the file cache
private static final String URL_SPLIT = "\\s+";
// 日志输出
// Log output
protected final Logger logger = LoggerFactory.getLogger(getClass());
// 本地磁盘缓存其中特殊的key值.registies记录注册中心列表其它均为notified服务提供者列表
// Local disk cache, where the special key value.registies records the list of registry centers, and the others are the list of notified service providers
private final Properties properties = new Properties();
// 文件缓存定时写入
// File cache timing writing
private final ExecutorService registryCacheExecutor = Executors.newFixedThreadPool(1, new NamedThreadFactory("DubboSaveRegistryCache", true));
//是否是同步保存文件
// Is it synchronized to save the file
private final boolean syncSaveFile;
private final AtomicLong lastCacheChanged = new AtomicLong();
private final Set<URL> registered = new ConcurrentHashSet<URL>();
private final ConcurrentMap<URL, Set<NotifyListener>> subscribed = new ConcurrentHashMap<URL, Set<NotifyListener>>();
private final ConcurrentMap<URL, Map<String, List<URL>>> notified = new ConcurrentHashMap<URL, Map<String, List<URL>>>();
private URL registryUrl;
// 本地磁盘缓存文件
// Local disk cache file
private File file;
private AtomicBoolean destroyed = new AtomicBoolean(false);
public AbstractRegistry(URL url) {
setUrl(url);
// 启动文件保存定时器
// Start file save timer
syncSaveFile = url.getParameter(Constants.REGISTRY_FILESAVE_SYNC_KEY, false);
String filename = url.getParameter(Constants.FILE_KEY, System.getProperty("user.home") + "/.dubbo/dubbo-registry-" + url.getParameter(Constants.APPLICATION_KEY) + "-" + url.getAddress() + ".cache");
File file = null;
@ -149,7 +148,7 @@ public abstract class AbstractRegistry implements Registry {
if (file == null) {
return;
}
// 保存
// Save
try {
File lockfile = new File(file.getAbsolutePath() + ".lock");
if (!lockfile.exists()) {
@ -163,7 +162,7 @@ public abstract class AbstractRegistry implements Registry {
if (lock == null) {
throw new IOException("Can not lock the registry cache file " + file.getAbsolutePath() + ", ignore and retry later, maybe multi java process use the file, please config: dubbo.registry.file=xxx.properties");
}
// 保存
// Save
try {
if (!file.exists()) {
file.createNewFile();
@ -252,7 +251,7 @@ public abstract class AbstractRegistry implements Registry {
reference.set(urls);
}
};
subscribe(url, listener); // 订阅逻辑保证第一次notify后再返回
subscribe(url, listener); // Subscribe logic guarantees the first notify to return
List<URL> urls = reference.get();
if (urls != null && urls.size() > 0) {
for (URL u : urls) {

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -32,38 +33,37 @@ import java.util.concurrent.locks.ReentrantLock;
/**
* AbstractRegistryFactory. (SPI, Singleton, ThreadSafe)
*
* @author william.liangf
* @see com.alibaba.dubbo.registry.RegistryFactory
*/
public abstract class AbstractRegistryFactory implements RegistryFactory {
// 日志输出
// Log output
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractRegistryFactory.class);
// 注册中心获取过程锁
// The lock for the acquisition process of the registry
private static final ReentrantLock LOCK = new ReentrantLock();
// 注册中心集合 Map<RegistryAddress, Registry>
// Registry Collection Map<RegistryAddress, Registry>
private static final Map<String, Registry> REGISTRIES = new ConcurrentHashMap<String, Registry>();
/**
* 获取所有注册中心
* Get all registries
*
* @return 所有注册中心
* @return all registries
*/
public static Collection<Registry> getRegistries() {
return Collections.unmodifiableCollection(REGISTRIES.values());
}
/**
* 关闭所有已创建注册中心
* Close all created registries
*/
// TODO: 2017/8/30 to move somewhere else better
public static void destroyAll() {
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Close all registries " + getRegistries());
}
// 锁定注册中心关闭过程
// Lock up the registry shutdown process
LOCK.lock();
try {
for (Registry registry : getRegistries()) {
@ -75,7 +75,7 @@ public abstract class AbstractRegistryFactory implements RegistryFactory {
}
REGISTRIES.clear();
} finally {
// 释放锁
// Release the lock
LOCK.unlock();
}
}
@ -85,7 +85,7 @@ public abstract class AbstractRegistryFactory implements RegistryFactory {
.addParameter(Constants.INTERFACE_KEY, RegistryService.class.getName())
.removeParameters(Constants.EXPORT_KEY, Constants.REFER_KEY);
String key = url.toServiceString();
// 锁定注册中心获取过程保证注册中心单一实例
// Lock the registry access process to ensure a single instance of the registry
LOCK.lock();
try {
Registry registry = REGISTRIES.get(key);
@ -99,7 +99,7 @@ public abstract class AbstractRegistryFactory implements RegistryFactory {
REGISTRIES.put(key, registry);
return registry;
} finally {
// 释放锁
// Release the lock
LOCK.unlock();
}
}

View File

@ -1,3 +1,19 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.dubbo.registry.support;
import com.alibaba.dubbo.common.URL;
@ -8,7 +24,6 @@ import com.alibaba.dubbo.rpc.Result;
import com.alibaba.dubbo.rpc.RpcException;
/**
* @author qinliujie
* @date 2017/11/23
*/
public class ConsumerInvokerWrapper<T> implements Invoker {

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -38,14 +39,13 @@ import java.util.concurrent.atomic.AtomicBoolean;
/**
* FailbackRegistry. (SPI, Prototype, ThreadSafe)
*
* @author william.liangf
*/
public abstract class FailbackRegistry extends AbstractRegistry {
// 定时任务执行器
// Scheduled executor service
private final ScheduledExecutorService retryExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("DubboRegistryFailedRetryTimer", true));
// 失败重试定时器定时检查是否有请求失败如有无限次重试
// Timer for failure retry, regular check if there is a request for failure, and if there is, an unlimited retry
private final ScheduledFuture<?> retryFuture;
private final Set<URL> failedRegistered = new ConcurrentHashSet<URL>();
@ -65,10 +65,10 @@ public abstract class FailbackRegistry extends AbstractRegistry {
int retryPeriod = url.getParameter(Constants.REGISTRY_RETRY_PERIOD_KEY, Constants.DEFAULT_REGISTRY_RETRY_PERIOD);
this.retryFuture = retryExecutor.scheduleWithFixedDelay(new Runnable() {
public void run() {
// 检测并连接注册中心
// Check and connect to the registry
try {
retry();
} catch (Throwable t) { // 防御性容错
} catch (Throwable t) { // Defensive fault tolerance
logger.error("Unexpected error occur at failed retry, cause: " + t.getMessage(), t);
}
}
@ -132,12 +132,12 @@ public abstract class FailbackRegistry extends AbstractRegistry {
failedRegistered.remove(url);
failedUnregistered.remove(url);
try {
// 向服务器端发送注册请求
// Sending a registration request to the server side
doRegister(url);
} catch (Exception e) {
Throwable t = e;
// 如果开启了启动时检测则直接抛出异常
// If the startup detection is opened, the Exception is thrown directly.
boolean check = getUrl().getParameter(Constants.CHECK_KEY, true)
&& url.getParameter(Constants.CHECK_KEY, true)
&& !Constants.CONSUMER_PROTOCOL.equals(url.getProtocol());
@ -151,7 +151,7 @@ public abstract class FailbackRegistry extends AbstractRegistry {
logger.error("Failed to register " + url + ", waiting for retry, cause: " + t.getMessage(), t);
}
// 将失败的注册请求记录到失败列表定时重试
// Record a failed registration request to a failed list, retry regularly
failedRegistered.add(url);
}
}
@ -165,12 +165,12 @@ public abstract class FailbackRegistry extends AbstractRegistry {
failedRegistered.remove(url);
failedUnregistered.remove(url);
try {
// 向服务器端发送取消注册请求
// Sending a cancellation request to the server side
doUnregister(url);
} catch (Exception e) {
Throwable t = e;
// 如果开启了启动时检测则直接抛出异常
// If the startup detection is opened, the Exception is thrown directly.
boolean check = getUrl().getParameter(Constants.CHECK_KEY, true)
&& url.getParameter(Constants.CHECK_KEY, true)
&& !Constants.CONSUMER_PROTOCOL.equals(url.getProtocol());
@ -184,7 +184,7 @@ public abstract class FailbackRegistry extends AbstractRegistry {
logger.error("Failed to uregister " + url + ", waiting for retry, cause: " + t.getMessage(), t);
}
// 将失败的取消注册请求记录到失败列表定时重试
// Record a failed registration request to a failed list, retry regularly
failedUnregistered.add(url);
}
}
@ -197,7 +197,7 @@ public abstract class FailbackRegistry extends AbstractRegistry {
super.subscribe(url, listener);
removeFailedSubscribed(url, listener);
try {
// 向服务器端发送订阅请求
// Sending a subscription request to the server side
doSubscribe(url, listener);
} catch (Exception e) {
Throwable t = e;
@ -207,7 +207,7 @@ public abstract class FailbackRegistry extends AbstractRegistry {
notify(url, listener, urls);
logger.error("Failed to subscribe " + url + ", Using cached list: " + urls + " from cache file: " + getUrl().getParameter(Constants.FILE_KEY, System.getProperty("user.home") + "/dubbo-registry-" + url.getHost() + ".cache") + ", cause: " + t.getMessage(), t);
} else {
// 如果开启了启动时检测则直接抛出异常
// If the startup detection is opened, the Exception is thrown directly.
boolean check = getUrl().getParameter(Constants.CHECK_KEY, true)
&& url.getParameter(Constants.CHECK_KEY, true);
boolean skipFailback = t instanceof SkipFailbackWrapperException;
@ -221,7 +221,7 @@ public abstract class FailbackRegistry extends AbstractRegistry {
}
}
// 将失败的订阅请求记录到失败列表定时重试
// Record a failed registration request to a failed list, retry regularly
addFailedSubscribed(url, listener);
}
}
@ -234,12 +234,12 @@ public abstract class FailbackRegistry extends AbstractRegistry {
super.unsubscribe(url, listener);
removeFailedSubscribed(url, listener);
try {
// 向服务器端发送取消订阅请求
// Sending a canceling subscription request to the server side
doUnsubscribe(url, listener);
} catch (Exception e) {
Throwable t = e;
// 如果开启了启动时检测则直接抛出异常
// If the startup detection is opened, the Exception is thrown directly.
boolean check = getUrl().getParameter(Constants.CHECK_KEY, true)
&& url.getParameter(Constants.CHECK_KEY, true);
boolean skipFailback = t instanceof SkipFailbackWrapperException;
@ -252,7 +252,7 @@ public abstract class FailbackRegistry extends AbstractRegistry {
logger.error("Failed to unsubscribe " + url + ", waiting for retry, cause: " + t.getMessage(), t);
}
// 将失败的取消订阅请求记录到失败列表定时重试
// Record a failed registration request to a failed list, retry regularly
Set<NotifyListener> listeners = failedUnsubscribed.get(url);
if (listeners == null) {
failedUnsubscribed.putIfAbsent(url, new ConcurrentHashSet<NotifyListener>());
@ -273,7 +273,7 @@ public abstract class FailbackRegistry extends AbstractRegistry {
try {
doNotify(url, listener, urls);
} catch (Exception t) {
// 将失败的通知请求记录到失败列表定时重试
// Record a failed registration request to a failed list, retry regularly
Map<NotifyListener, List<URL>> listeners = failedNotified.get(url);
if (listeners == null) {
failedNotified.putIfAbsent(url, new ConcurrentHashMap<NotifyListener, List<URL>>());
@ -315,7 +315,7 @@ public abstract class FailbackRegistry extends AbstractRegistry {
}
}
// 重试失败的动作
// Retry the failed actions
protected void retry() {
if (!failedRegistered.isEmpty()) {
Set<URL> failed = new HashSet<URL>(failedRegistered);
@ -328,11 +328,11 @@ public abstract class FailbackRegistry extends AbstractRegistry {
try {
doRegister(url);
failedRegistered.remove(url);
} catch (Throwable t) { // 忽略所有异常等待下次重试
} catch (Throwable t) { // Ignore all the exceptions and wait for the next retry
logger.warn("Failed to retry register " + failed + ", waiting for again, cause: " + t.getMessage(), t);
}
}
} catch (Throwable t) { // 忽略所有异常等待下次重试
} catch (Throwable t) { // Ignore all the exceptions and wait for the next retry
logger.warn("Failed to retry register " + failed + ", waiting for again, cause: " + t.getMessage(), t);
}
}
@ -348,11 +348,11 @@ public abstract class FailbackRegistry extends AbstractRegistry {
try {
doUnregister(url);
failedUnregistered.remove(url);
} catch (Throwable t) { // 忽略所有异常等待下次重试
} catch (Throwable t) { // Ignore all the exceptions and wait for the next retry
logger.warn("Failed to retry unregister " + failed + ", waiting for again, cause: " + t.getMessage(), t);
}
}
} catch (Throwable t) { // 忽略所有异常等待下次重试
} catch (Throwable t) { // Ignore all the exceptions and wait for the next retry
logger.warn("Failed to retry unregister " + failed + ", waiting for again, cause: " + t.getMessage(), t);
}
}
@ -376,12 +376,12 @@ public abstract class FailbackRegistry extends AbstractRegistry {
try {
doSubscribe(url, listener);
listeners.remove(listener);
} catch (Throwable t) { // 忽略所有异常等待下次重试
} catch (Throwable t) { // Ignore all the exceptions and wait for the next retry
logger.warn("Failed to retry subscribe " + failed + ", waiting for again, cause: " + t.getMessage(), t);
}
}
}
} catch (Throwable t) { // 忽略所有异常等待下次重试
} catch (Throwable t) { // Ignore all the exceptions and wait for the next retry
logger.warn("Failed to retry subscribe " + failed + ", waiting for again, cause: " + t.getMessage(), t);
}
}
@ -405,12 +405,12 @@ public abstract class FailbackRegistry extends AbstractRegistry {
try {
doUnsubscribe(url, listener);
listeners.remove(listener);
} catch (Throwable t) { // 忽略所有异常等待下次重试
} catch (Throwable t) { // Ignore all the exceptions and wait for the next retry
logger.warn("Failed to retry unsubscribe " + failed + ", waiting for again, cause: " + t.getMessage(), t);
}
}
}
} catch (Throwable t) { // 忽略所有异常等待下次重试
} catch (Throwable t) { // Ignore all the exceptions and wait for the next retry
logger.warn("Failed to retry unsubscribe " + failed + ", waiting for again, cause: " + t.getMessage(), t);
}
}
@ -434,12 +434,12 @@ public abstract class FailbackRegistry extends AbstractRegistry {
List<URL> urls = entry.getValue();
listener.notify(urls);
values.remove(listener);
} catch (Throwable t) { // 忽略所有异常等待下次重试
} catch (Throwable t) { // Ignore all the exceptions and wait for the next retry
logger.warn("Failed to retry notify " + failed + ", waiting for again, cause: " + t.getMessage(), t);
}
}
}
} catch (Throwable t) { // 忽略所有异常等待下次重试
} catch (Throwable t) { // Ignore all the exceptions and wait for the next retry
logger.warn("Failed to retry notify " + failed + ", waiting for again, cause: " + t.getMessage(), t);
}
}
@ -469,7 +469,7 @@ public abstract class FailbackRegistry extends AbstractRegistry {
}
// ==== 模板方法 ====
// ==== Template method ====
protected abstract void doRegister(URL url);

View File

@ -1,3 +1,19 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.dubbo.registry.support;
import com.alibaba.dubbo.common.Constants;
@ -11,7 +27,6 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author qinliujie
* @date 2017/11/23
*/
public class ProviderConsumerRegTable {

View File

@ -1,3 +1,19 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.dubbo.registry.support;
import com.alibaba.dubbo.common.URL;
@ -7,7 +23,6 @@ import com.alibaba.dubbo.rpc.Result;
import com.alibaba.dubbo.rpc.RpcException;
/**
* @author qinliujie
* @date 2017/11/23
*/
public class ProviderInvokerWrapper<T> implements Invoker {

View File

@ -1,11 +1,26 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.dubbo.registry.support;
/**
* Wrapper异常用于指示 {@link FailbackRegistry}跳过Failback
* Wrapper Exception, it is used to indicate that {@link FailbackRegistry} skips Failback.
* <p>
* NOTE: 期望找到其它更常规的指示方式
* NOTE: Expect to find other more conventional ways of instruction.
*
* @author ding.lid
* @see FailbackRegistry
*/
public class SkipFailbackWrapperException extends RuntimeException {

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -27,7 +28,6 @@ import org.junit.Test;
/**
* RegistryPerformanceTest
*
* @author william.liangf
*/
public class PerformanceRegistryTest extends TestCase {

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -25,7 +26,6 @@ import java.util.List;
/**
* PerformanceUtils
*
* @author william.liangf
*/
public class PerformanceUtils {

View File

@ -1,215 +0,0 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.dubbo.registry;
/**
* @author ding.lid
*/
public class RegistryTestSupport {
/*public static <T> void assertEqualsIgnoreOrde(Collection<T> expected, Collection<T> actual) {
Set<T> expectedSet;
if (expected instanceof Set) {
expectedSet = (Set<T>) expected;
} else {
expectedSet = new HashSet<T>(expected);
}
Set<T> actualSet;
if (actual instanceof Set) {
actualSet = (Set<T>) actual;
} else {
actualSet = new HashSet<T>(actual);
}
Assert.assertEquals(expectedSet, actualSet);
}
public static final String member_service_name = "com.alibaba.morgan.MemberService";
public static final Map<String, String> member_urls1;
static {
Map<String, String> m = new HashMap<String, String>();
m.put("remote://10.20.130.230:9090/memberService", "version=1.0.0");
member_urls1 = Collections.unmodifiableMap(m);
}
public static final Map<String, String> member_urls2;
static {
Map<String, String> m = new HashMap<String, String>();
m.put("remote://11.11.11.11:9090/memberService", "version=1.0.0");
m.put("remote://22.22.22.22:9090/memberService", "version=1.0.0");
m.put("remote://33.33.33.33:9090/memberService", "version=1.0.0");
member_urls2 = Collections.unmodifiableMap(m);
}
public static final Map<String, String> member_urls3;
static {
Map<String, String> m = new HashMap<String, String>();
m.put("remote://44.44.44.44:9090/memberService", "version=1.0.0");
member_urls3 = Collections.unmodifiableMap(m);
}
public static final String xxx_service_name = "com.alibaba.xxx.XxxService";
public static final Map<String, String> xxx_urls1;
static {
Map<String, String> m = new HashMap<String, String>();
m.put("remote://11.11.11.11:9090/xxxService", "version=1.0.0");
m.put("remote://22.22.22.22:9090/xxxService", "version=1.0.0");
xxx_urls1 = Collections.unmodifiableMap(m);
}
public static void registerCheck(AbstractRegistry registry) {
{
List<URL> registeredList = registry
.getRegistered("com.alibaba.morgan.MemberService");
assertEquals(0, registeredList.size());
Map<String, Map<String, String>> registeredMap = registry.getRegistered();
assertEquals(0, registeredMap.size());
}
{
for (Map.Entry<String, String> entry : member_urls1.entrySet()) {
registry.register(member_service_name, entry.getKey(), entry.getValue());
}
Map<String, String> registered = registry.getRegistered(member_service_name);
assertEquals(1, registered.size());
assertNotSame(member_urls1, registered);
assertEquals(member_urls1, registered);
Map<String, Map<String, String>> registeredMap = registry.getRegistered();
assertEquals(1, registeredMap.size());
assertTrue(registeredMap.containsKey(member_service_name));
registered = registeredMap.get(member_service_name);
assertEquals(1, registered.size());
assertNotSame(member_urls1, registered);
assertEquals(member_urls1, registered);
}
{
registry.register(member_service_name, member_urls2);
Map<String, String> registered = registry.getRegistered(member_service_name);
final Map<String, String> urls = new HashMap<String, String>();
urls.putAll(member_urls1);
urls.putAll(member_urls2);
assertEquals(urls, registered);
Map<String, Map<String, String>> registeredMap = registry.getRegistered();
assertEquals(1, registeredMap.size());
assertTrue(registeredMap.containsKey(member_service_name));
registered = registeredMap.get(member_service_name);
assertEquals(urls, registered);
}
{
Map<String, Map<String, String>> services = new HashMap<String, Map<String, String>>();
services.put(member_service_name, member_urls3);
services.put(xxx_service_name, xxx_urls1);
registry.register(services);
final Map<String, String> urls = new HashMap<String, String>();
urls.putAll(member_urls1);
urls.putAll(member_urls2);
urls.putAll(member_urls3);
{
Map<String, String> registered = registry.getRegistered(member_service_name);
assertEquals(urls, registered);
registered = registry.getRegistered(xxx_service_name);
assertEquals(xxx_urls1, registered);
}
{
Map<String, Map<String, String>> registeredMap = registry.getRegistered();
assertEquals(2, registeredMap.size());
assertTrue(registeredMap.containsKey(member_service_name));
assertTrue(registeredMap.containsKey(xxx_service_name));
Map<String, String> registered = registeredMap.get(member_service_name);
assertEquals(urls, registered);
registered = registeredMap.get(xxx_service_name);
assertEquals(xxx_urls1, registered);
}
}
}
public static void subscribeCheck(AbstractRegistry registry, NotificationListener mockNotifyListener) {
String subscribed = registry.getSubscribed("com.alibaba.morgan.MemberService");
assertNull(subscribed);
Map<String, String> subscribedMap = registry.getSubscribed();
assertEquals(0, subscribedMap.size());
// query允许为null
registry.subscribe("com.alibaba.xxx.XxxService", (String) null, mockNotifyListener);
subscribed = registry.getSubscribed("com.alibaba.xxx.XxxService");
assertEquals("", subscribed);
subscribedMap = registry.getSubscribed();
assertEquals(1, subscribedMap.size());
assertTrue(subscribedMap.containsKey("com.alibaba.xxx.XxxService"));
assertEquals("", subscribedMap.get("com.alibaba.xxx.XxxService"));
registry.subscribe("com.alibaba.empty.EmptyService", "", mockNotifyListener);
// query允许为空
subscribed = registry.getSubscribed("com.alibaba.empty.EmptyService");
assertEquals("", subscribed);
subscribedMap = registry.getSubscribed();
assertEquals(2, subscribedMap.size());
assertTrue(subscribedMap.containsKey("com.alibaba.empty.EmptyService"));
assertEquals("", subscribedMap.get("com.alibaba.empty.EmptyService"));
// 多项值的Query
registry.subscribe("com.alibaba.morgan.MemberService", "dog=bad,cat=god",
mockNotifyListener);
subscribed = registry.getSubscribed("com.alibaba.morgan.MemberService");
assertEquals("dog=bad,cat=god", subscribed);
subscribedMap = registry.getSubscribed();
assertEquals(3, subscribedMap.size());
String s = subscribedMap.get("com.alibaba.morgan.MemberService");
assertEquals("dog=bad,cat=god", s);
registry.subscribe("com.alibaba.complex.ComplexService",
"version=1.0.0&application=kylin&methods=findPerson,findVAccount",
mockNotifyListener);
subscribedMap = registry.getSubscribed();
assertEquals(4, subscribedMap.size());
String q = subscribedMap.get("com.alibaba.complex.ComplexService");
assertEquals("version=1.0.0&application=kylin&methods=findPerson,findVAccount", q);
}*/
public void testDummy() {
}
}

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -29,7 +30,6 @@ import java.util.List;
/**
* AbstractRegistryFactoryTest
*
* @author william.liangf
*/
public class AbstractRegistryFactoryTest {

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2101 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -32,7 +33,7 @@ import java.util.concurrent.atomic.AtomicReference;
import static org.junit.Assert.assertEquals;
/**
* @author liuchao
*
*/
public class FailbackRegistryTest {
static String service;
@ -55,7 +56,7 @@ public class FailbackRegistryTest {
/**
* Test method for
* {@link com.alibaba.dubbo.registry.internal.FailbackRegistry#doRetry()}.
* {@link com.alibaba.dubbo.registry.support.FailbackRegistry#retry()}.
*
* @throws Exception
*/
@ -63,7 +64,7 @@ public class FailbackRegistryTest {
public void testDoRetry() throws Exception {
final AtomicReference<Boolean> notified = new AtomicReference<Boolean>(false);
final CountDownLatch latch = new CountDownLatch(3);//全部共调用3次成功才会减1. subscribe register的失败尝试不会在做了
final CountDownLatch latch = new CountDownLatch(3);//All of them are called 3 times. Successful attempts to reduce the failure of 1. subscribe register will not be done again
NotifyListener listner = new NotifyListener() {
public void notify(List<URL> urls) {
@ -77,7 +78,7 @@ public class FailbackRegistryTest {
registry.subscribe(serviceUrl.setProtocol(Constants.CONSUMER_PROTOCOL).addParameters(CollectionUtils.toStringMap("check", "false")), listner);
registry.unsubscribe(serviceUrl.setProtocol(Constants.CONSUMER_PROTOCOL).addParameters(CollectionUtils.toStringMap("check", "false")), listner);
//失败的情况不能调用到listener.
//Failure can not be called to listener.
assertEquals(false, notified.get());
assertEquals(3, latch.getCount());
@ -92,14 +93,14 @@ public class FailbackRegistryTest {
}
// Thread.sleep(100000);//for debug
assertEquals(0, latch.getCount());
//unsubscribe时会清除failedsubcribe对应key
//The failedsubcribe corresponding key will be cleared when unsubscribing
assertEquals(false, notified.get());
}
@Test
public void testDoRetry_subscribe() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);//全部共调用4次成功才会减1. subscribe的失败尝试不会在做了
final CountDownLatch latch = new CountDownLatch(1);//All of them are called 4 times. A successful attempt to lose 1. subscribe will not be done
registry = new MockRegistry(registryUrl, latch);
registry.setBad(true);
@ -120,7 +121,7 @@ public class FailbackRegistryTest {
public void testDoRetry_register() throws Exception {
final AtomicReference<Boolean> notified = new AtomicReference<Boolean>(false);
final CountDownLatch latch = new CountDownLatch(1);//全部共调用4次成功才会减1. subscribe的失败尝试不会在做了
final CountDownLatch latch = new CountDownLatch(1);//All of them are called 4 times. A successful attempt to lose 1. subscribe will not be done
NotifyListener listner = new NotifyListener() {
public void notify(List<URL> urls) {
@ -131,7 +132,7 @@ public class FailbackRegistryTest {
registry.setBad(true);
registry.subscribe(serviceUrl.setProtocol(Constants.CONSUMER_PROTOCOL).addParameters(CollectionUtils.toStringMap("check", "false")), listner);
//失败的情况不能调用到listener.
//Failure can not be called to listener.
assertEquals(false, notified.get());
assertEquals(1, latch.getCount());
@ -146,20 +147,20 @@ public class FailbackRegistryTest {
}
// Thread.sleep(100000);
assertEquals(0, latch.getCount());
//unsubscribe时会清除failedsubcribe对应key
//The failedsubcribe corresponding key will be cleared when unsubscribing
assertEquals(true, notified.get());
}
@Test
public void testDoRetry_nofify() throws Exception {
//初始值0
//Initial value 0
final AtomicInteger count = new AtomicInteger(0);
NotifyListener listner = new NotifyListener() {
public void notify(List<URL> urls) {
count.incrementAndGet();
//第一次抛出异常看后面是否会再次调用到incrementAndGet
//The exception is thrown for the first time to see if the back will be called again to incrementAndGet
if (count.get() == 1l) {
throw new RuntimeException("test exception please ignore");
}
@ -168,8 +169,8 @@ public class FailbackRegistryTest {
registry = new MockRegistry(registryUrl, new CountDownLatch(0));
registry.subscribe(serviceUrl.setProtocol(Constants.CONSUMER_PROTOCOL).addParameters(CollectionUtils.toStringMap("check", "false")), listner);
assertEquals(1, count.get()); //确保subscribe调用完成后刚调用过一次count.incrementAndGet
//等定时器.
assertEquals(1, count.get()); //Make sure that the subscribe call has just been called once count.incrementAndGet after the call is completed
//Wait for the timer.
for (int i = 0; i < trytimes; i++) {
System.out.println("failback notify retry ,times:" + i);
if (count.get() == 2)

View File

@ -1,13 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright 1999-2011 Alibaba Group.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

View File

@ -1,12 +1,13 @@
<!--
- Copyright 1999-2011 Alibaba Group.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -37,22 +38,21 @@ import java.util.concurrent.locks.ReentrantLock;
/**
* DubboRegistry
*
* @author william.liangf
*/
public class DubboRegistry extends FailbackRegistry {
private final static Logger logger = LoggerFactory.getLogger(DubboRegistry.class);
// 重连检测周期3秒(单位毫秒)
// Reconnecting detection cycle: 3 seconds (unit:millisecond)
private static final int RECONNECT_PERIOD_DEFAULT = 3 * 1000;
// 定时任务执行器
// Scheduled executor service
private final ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1, new NamedThreadFactory("DubboRegistryReconnectTimer", true));
// 重连定时器定时检查连接是否可用不可用时无限次重连
// Reconnection timer, regular check connection is available. If unavailable, unlimited reconnection.
private final ScheduledFuture<?> reconnectFuture;
// 客户端获取过程锁锁定客户端实例的创建过程防止重复的客户端
// The lock for client acquisition process, lock the creation process of the client instance to prevent repeated clients
private final ReentrantLock clientLock = new ReentrantLock();
private final Invoker<RegistryService> registryInvoker;
@ -63,14 +63,14 @@ public class DubboRegistry extends FailbackRegistry {
super(registryInvoker.getUrl());
this.registryInvoker = registryInvoker;
this.registryService = registryService;
// 启动重连定时器
// Start reconnection timer
int reconnectPeriod = registryInvoker.getUrl().getParameter(Constants.REGISTRY_RECONNECT_PERIOD_KEY, RECONNECT_PERIOD_DEFAULT);
reconnectFuture = scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
public void run() {
// 检测并连接注册中心
// Check and connect to the registry
try {
connect();
} catch (Throwable t) { // 防御性容错
} catch (Throwable t) { // Defensive fault tolerance
logger.error("Unexpected error occur at reconnect, cause: " + t.getMessage(), t);
}
}
@ -79,7 +79,7 @@ public class DubboRegistry extends FailbackRegistry {
protected final void connect() {
try {
// 检查是否已连接
// Check whether or not it is connected
if (isAvailable()) {
return;
}
@ -88,7 +88,7 @@ public class DubboRegistry extends FailbackRegistry {
}
clientLock.lock();
try {
// 双重检查是否已连接
// Double check whether or not it is connected
if (isAvailable()) {
return;
}
@ -96,7 +96,7 @@ public class DubboRegistry extends FailbackRegistry {
} finally {
clientLock.unlock();
}
} catch (Throwable t) { // 忽略所有异常等待下次重试
} catch (Throwable t) { // Ignore all the exceptions and wait for the next retry
if (getUrl().getParameter(Constants.CHECK_KEY, true)) {
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
@ -116,7 +116,7 @@ public class DubboRegistry extends FailbackRegistry {
public void destroy() {
super.destroy();
try {
// 取消重连定时器
// Cancel the reconnection timer
if (!reconnectFuture.isCancelled()) {
reconnectFuture.cancel(true);
}

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -37,7 +38,6 @@ import java.util.List;
/**
* DubboRegistryFactory
*
* @author william.liangf
*/
public class DubboRegistryFactory extends AbstractRegistryFactory {

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -32,26 +33,25 @@ import java.util.concurrent.CopyOnWriteArrayList;
/**
* AbstractRegistryService
*
* @author william.liangf
*/
public abstract class AbstractRegistryService implements RegistryService {
// 日志输出
// Log output
protected final Logger logger = LoggerFactory.getLogger(getClass());
// 已注册的服务
// Registered services
// Map<serviceName, Map<url, queryString>>
private final ConcurrentMap<String, List<URL>> registered = new ConcurrentHashMap<String, List<URL>>();
// 已订阅的服务
// Subscribed services
// Map<serviceName, queryString>
private final ConcurrentMap<String, Map<String, String>> subscribed = new ConcurrentHashMap<String, Map<String, String>>();
// 已通知的服务
// Notified services
// Map<serviceName, Map<url, queryString>>
private final ConcurrentMap<String, List<URL>> notified = new ConcurrentHashMap<String, List<URL>>();
// 已订阅服务的监听器列表
// Listeners list for subscribed services
// Map<serviceName, List<notificationListener>>
private final ConcurrentMap<String, List<NotifyListener>> notifyListeners = new ConcurrentHashMap<String, List<NotifyListener>>();
@ -154,7 +154,7 @@ public abstract class AbstractRegistryService implements RegistryService {
removeListener(service, listener);
}
//consumer provider的 listener可以一起存储,都是根据服务名称共享
//The listener of the consumer and the provider can be stored together, all based on the service name
private void addListener(final String service, final NotifyListener listener) {
if (listener == null) {
return;

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -32,7 +33,6 @@ import java.util.Map;
/**
* MockedClient
*
* @author william.liangf
*/
public class MockedClient implements ExchangeClient {

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -34,7 +35,7 @@ import com.alibaba.dubbo.rpc.cluster.loadbalance.RoundRobinLoadBalance;
import com.alibaba.dubbo.rpc.cluster.router.script.ScriptRouter;
import com.alibaba.dubbo.rpc.cluster.router.script.ScriptRouterFactory;
import junit.framework.Assert;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@ -125,7 +126,7 @@ public class RegistryDirectoryTest {
}
/**
* 测试推送只有router的情况
* Test push only router
*/
@Test
public void testNotified_Normal_withRouters() {
@ -184,7 +185,7 @@ public class RegistryDirectoryTest {
}
}
//测试调用和registry url的path无关
//The test call is independent of the path of the registry url
@Test
public void test_NotifiedDubbo1() {
URL errorPathUrl = URL.valueOf("notsupport:/" + "xxx" + "?refer=" + URL.encode("interface=" + service));
@ -267,7 +268,7 @@ public class RegistryDirectoryTest {
Assert.assertEquals(1, invokers.size());
}
// 通知成3个invoker===================================
// 3 invoker notifications===================================
private void test_Notified3invokers(RegistryDirectory registryDirectory) {
List<URL> serviceUrls = new ArrayList<URL>();
serviceUrls.add(SERVICEURL.addParameter("methods", "getXXX1"));
@ -313,7 +314,7 @@ public class RegistryDirectoryTest {
registryDirectory2.setProtocol(protocol);
List<URL> serviceUrls = new ArrayList<URL>();
// 检验注册中心的参数需要被清除
// The parameters of the inspection registry need to be cleared
{
serviceUrls.clear();
serviceUrls.add(SERVICEURL.addParameter("methods", "getXXX1"));
@ -326,7 +327,7 @@ public class RegistryDirectoryTest {
URL url = invoker.getUrl();
Assert.assertEquals(null, url.getParameter("key"));
}
// 检验服务提供方的参数需要merge
// The parameters of the provider for the inspection service need merge
{
serviceUrls.clear();
serviceUrls.add(SERVICEURL.addParameter("methods", "getXXX2").addParameter("key", "provider"));
@ -339,7 +340,7 @@ public class RegistryDirectoryTest {
URL url = invoker.getUrl();
Assert.assertEquals("provider", url.getParameter("key"));
}
// 检验服务query的参数需要与providermerge
// The parameters of the test service query need to be with the providermerge.
{
serviceUrls.clear();
serviceUrls.add(SERVICEURL.addParameter("methods", "getXXX3").addParameter("key", "provider"));
@ -560,8 +561,8 @@ public class RegistryDirectoryTest {
}
/**
* 测试override规则是否优先
* 场景先推送override后推送invoker
* Test whether the override rule have a high priority
* Scene: first push override , then push invoker
*/
@Test
public void testNotifyoverrideUrls_beforeInvoker() {
@ -569,10 +570,10 @@ public class RegistryDirectoryTest {
List<URL> overrideUrls = new ArrayList<URL>();
overrideUrls.add(URL.valueOf("override://0.0.0.0?timeout=1&connections=5"));
registryDirectory.notify(overrideUrls);
//注册中心初始只推送overridedirctory状态应该是false因为没有invoker存在
//The registry is initially pushed to override only, and the dirctory state should be false because there is no invoker.
Assert.assertEquals(false, registryDirectory.isAvailable());
//在推送两个provider,directory状态恢复为true
//After pushing two provider, the directory state is restored to true
List<URL> serviceUrls = new ArrayList<URL>();
serviceUrls.add(SERVICEURL.addParameter("timeout", "1000"));
serviceUrls.add(SERVICEURL2.addParameter("timeout", "1000").addParameter("connections", "10"));
@ -580,7 +581,7 @@ public class RegistryDirectoryTest {
registryDirectory.notify(serviceUrls);
Assert.assertEquals(true, registryDirectory.isAvailable());
//开始验证参数值
//Start validation of parameter values
invocation = new RpcInvocation();
@ -592,14 +593,14 @@ public class RegistryDirectoryTest {
}
/**
* 测试override规则是否优先
* 场景先推送override后推送invoker
* Test whether the override rule have a high priority
* Scene: first push override , then push invoker
*/
@Test
public void testNotifyoverrideUrls_afterInvoker() {
RegistryDirectory registryDirectory = getRegistryDirectory();
//在推送两个provider,directory状态恢复为true
//After pushing two provider, the directory state is restored to true
List<URL> serviceUrls = new ArrayList<URL>();
serviceUrls.add(SERVICEURL.addParameter("timeout", "1000"));
serviceUrls.add(SERVICEURL2.addParameter("timeout", "1000").addParameter("connections", "10"));
@ -611,7 +612,7 @@ public class RegistryDirectoryTest {
overrideUrls.add(URL.valueOf("override://0.0.0.0?timeout=1&connections=5"));
registryDirectory.notify(overrideUrls);
//开始验证参数值
//Start validation of parameter values
invocation = new RpcInvocation();
@ -623,8 +624,8 @@ public class RegistryDirectoryTest {
}
/**
* 测试override规则是否优先
* 场景与invoker 一起推override规则
* Test whether the override rule have a high priority
* Scene: push override rules with invoker
*/
@Test
public void testNotifyoverrideUrls_withInvoker() {
@ -638,7 +639,7 @@ public class RegistryDirectoryTest {
registryDirectory.notify(durls);
Assert.assertEquals(true, registryDirectory.isAvailable());
//开始验证参数值
//Start validation of parameter values
invocation = new RpcInvocation();
@ -650,9 +651,9 @@ public class RegistryDirectoryTest {
}
/**
* 测试override规则是否优先
* 场景推送的规则与provider的参数是一样的
* 期望不需要重新引用
* Test whether the override rule have a high priority
* Scene: the rules of the push are the same as the parameters of the provider
* Expectation: no need to be re-referenced
*/
@Test
public void testNotifyoverrideUrls_Nouse() {
@ -660,7 +661,7 @@ public class RegistryDirectoryTest {
invocation = new RpcInvocation();
List<URL> durls = new ArrayList<URL>();
durls.add(SERVICEURL.addParameter("timeout", "1"));//一个一样一个不一样
durls.add(SERVICEURL.addParameter("timeout", "1"));//One is the same, one is different
durls.add(SERVICEURL2.addParameter("timeout", "1").addParameter("connections", "5"));
registryDirectory.notify(durls);
List<Invoker<?>> invokers = registryDirectory.list(invocation);
@ -678,15 +679,15 @@ public class RegistryDirectoryTest {
Invoker<?> a2Invoker = invokers.get(0);
Invoker<?> b2Invoker = invokers.get(1);
//参数不一样必须重新引用
//The parameters are different and must be rereferenced.
Assert.assertFalse("object not same", a1Invoker == a2Invoker);
//参数一样不能重新引用
//The parameters can not be rereferenced
Assert.assertTrue("object same", b1Invoker == b2Invoker);
}
/**
* 测试针对某个provider的Override规则
* Test override rules for a certain provider
*/
@Test
public void testNofityOverrideUrls_Provider() {
@ -694,7 +695,7 @@ public class RegistryDirectoryTest {
invocation = new RpcInvocation();
List<URL> durls = new ArrayList<URL>();
durls.add(SERVICEURL.setHost("10.20.30.140").addParameter("timeout", "1").addParameter(Constants.SIDE_KEY, Constants.CONSUMER_SIDE));//一个一样一个不一样
durls.add(SERVICEURL.setHost("10.20.30.140").addParameter("timeout", "1").addParameter(Constants.SIDE_KEY, Constants.CONSUMER_SIDE));//One is the same, one is different
durls.add(SERVICEURL2.setHost("10.20.30.141").addParameter("timeout", "2").addParameter(Constants.SIDE_KEY, Constants.CONSUMER_SIDE));
registryDirectory.notify(durls);
@ -711,8 +712,8 @@ public class RegistryDirectoryTest {
}
/**
* 测试清除override规则同时下发清除规则和其他override规则
* 测试是否能够恢复到推送时的providerUrl
* Test cleanup override rules, and sent remove rules and other override rules
* Whether the test can be restored to the providerUrl when it is pushed
*/
@Test
public void testNofityOverrideUrls_Clean1() {
@ -734,13 +735,13 @@ public class RegistryDirectoryTest {
List<Invoker<?>> invokers = registryDirectory.list(invocation);
Invoker<?> aInvoker = invokers.get(0);
//需要恢复到最初的providerUrl
//Need to be restored to the original providerUrl
Assert.assertEquals("1", aInvoker.getUrl().getParameter("timeout"));
}
/**
* 测试清除override规则只下发override清除规则
* 测试是否能够恢复到推送时的providerUrl
* The test clears the override rule and only sends the override cleanup rules
* Whether the test can be restored to the providerUrl when it is pushed
*/
@Test
public void testNofityOverrideUrls_CleanOnly() {
@ -767,15 +768,15 @@ public class RegistryDirectoryTest {
registryDirectory.notify(durls);
invokers = registryDirectory.list(invocation);
aInvoker = invokers.get(0);
//需要恢复到最初的providerUrl
//Need to be restored to the original providerUrl
Assert.assertEquals("1", aInvoker.getUrl().getParameter("timeout"));
Assert.assertEquals(null, registryDirectory.getUrl().getParameter("mock"));
}
/**
* 测试同时推送清除override和针对某个provider的override
* 看override是否能够生效
* Test the simultaneous push to clear the override and the override for a certain provider
* See if override can take effect
*/
@Test
public void testNofityOverrideUrls_CleanNOverride() {
@ -798,8 +799,8 @@ public class RegistryDirectoryTest {
}
/**
* 测试override通过enable=false禁用所有服务提供者
* 预期:不能通过override禁用所有服务提供者.
* Test override disables all service providers through enable=false
* Expectation: all service providers can not be disabled through override.
*/
@Test
public void testNofityOverrideUrls_disabled_allProvider() {
@ -816,13 +817,13 @@ public class RegistryDirectoryTest {
registryDirectory.notify(durls);
List<Invoker<?>> invokers = registryDirectory.list(invocation);
//不能通过override禁用所有服务提供者.
//All service providers can not be disabled through override.
Assert.assertEquals(2, invokers.size());
}
/**
* 测试override通过enable=false禁用指定服务提供者
* 预期:可以禁用指定的服务提供者
* Test override disables a specified service provider through enable=false
* It is expected that a specified service provider can be disable.
*/
@Test
public void testNofityOverrideUrls_disabled_specifiedProvider() {
@ -850,8 +851,8 @@ public class RegistryDirectoryTest {
}
/**
* 测试override通过enable=false禁用指定服务提供者
* 预期:可以禁用指定的服务提供者
* Test override disables a specified service provider through enable=false
* It is expected that a specified service provider can be disable.
*/
@Test
public void testNofity_To_Decrease_provider() {
@ -881,15 +882,15 @@ public class RegistryDirectoryTest {
}
/**
* 测试override通过enable=false禁用指定服务提供者
* 预期:可以禁用指定的服务提供者
* Test override disables a specified service provider through enable=false
* It is expected that a specified service provider can be disable.
*/
@Test
public void testNofity_disabled_specifiedProvider() {
RegistryDirectory registryDirectory = getRegistryDirectory();
invocation = new RpcInvocation();
// 初始就禁用
// Initially disable
List<URL> durls = new ArrayList<URL>();
durls.add(SERVICEURL.setHost("10.20.30.140").addParameter(Constants.ENABLED_KEY, "false"));
durls.add(SERVICEURL.setHost("10.20.30.141"));
@ -899,7 +900,7 @@ public class RegistryDirectoryTest {
Assert.assertEquals(1, invokers.size());
Assert.assertEquals("10.20.30.141", invokers.get(0).getUrl().getHost());
// 通过覆盖规则启用
//Enabled by override rule
durls = new ArrayList<URL>();
durls.add(URL.valueOf("override://10.20.30.140:9091?" + Constants.DISABLED_KEY + "=false"));
registryDirectory.notify(durls);
@ -932,7 +933,7 @@ public class RegistryDirectoryTest {
}
/**
* 测试mock provider下发
* Test mock provider distribution
*/
@Test
public void testNotify_MockProviderOnly() {
@ -958,7 +959,7 @@ public class RegistryDirectoryTest {
// mock protocol
//测试protocol匹配只选择匹配的protocol进行refer
//Test the matching of protocol and select only the matched protocol for refer
@Test
public void test_Notified_acceptProtocol0() {
URL errorPathUrl = URL.valueOf("notsupport:/xxx?refer=" + URL.encode("interface=" + service));
@ -976,7 +977,7 @@ public class RegistryDirectoryTest {
Assert.assertEquals(2, invokers.size());
}
//测试protocol匹配只选择匹配的protocol进行refer
//Test the matching of protocol and select only the matched protocol for refer
@Test
public void test_Notified_acceptProtocol1() {
URL errorPathUrl = URL.valueOf("notsupport:/xxx");
@ -995,7 +996,7 @@ public class RegistryDirectoryTest {
Assert.assertEquals(1, invokers.size());
}
//测试protocol匹配只选择匹配的protocol进行refer
//Test the matching of protocol and select only the matched protocol for refer
@Test
public void test_Notified_acceptProtocol2() {
URL errorPathUrl = URL.valueOf("notsupport:/xxx");

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -44,7 +45,6 @@ import static org.junit.Assert.assertEquals;
/**
* RegistryProtocolTest
*
* @author tony.chenl
*/
public class RegistryProtocolTest {
@ -88,7 +88,7 @@ public class RegistryProtocolTest {
newRegistryUrl, new ExchangeClient[]{new MockedClient("10.20.20.20", 2222, true)});
Exporter<DemoService> exporter = registryProtocol.export(invoker);
Exporter<DemoService> exporter2 = registryProtocol.export(invoker);
//同一个invoker多次export的exporter不同
//The same invoker, exporter that multiple exported are different
Assert.assertNotSame(exporter, exporter2);
exporter.unexport();
exporter2.unexport();
@ -120,8 +120,8 @@ public class RegistryProtocolTest {
/**
* 服务名称不匹配不能override invoker
* 服务名称匹配服务版本号不匹配
* The name of the service does not match and can't override invoker
* Service name matching, service version number mismatch
*/
@Test
public void testNotifyOverride_notmatch() throws Exception {
@ -140,7 +140,7 @@ public class RegistryProtocolTest {
}
/**
* 测试destory registry exporter是否能够正常被destroy掉
* Test destory registry, exporter can be normal by destroyed
*/
@Test
public void testDestoryRegistry() {

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -31,7 +32,6 @@ import static org.junit.Assert.assertEquals;
/**
* StatusTest
*
* @author tony.chenl
*/
public class RegistryStatusCheckerTest {

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -30,7 +31,6 @@ import java.net.ServerSocket;
/**
* SimpleRegistryExporter
*
* @author william.liangf
*/
public class SimpleRegistryExporter {

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -32,7 +33,6 @@ import java.util.concurrent.ConcurrentMap;
/**
* SimpleRegistryService
*
* @author william.liangf
*/
public class SimpleRegistryService extends AbstractRegistryService {

View File

@ -1,13 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright 1999-2011 Alibaba Group.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -17,7 +18,7 @@
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- ===================================================================== -->
<!-- 以下是appender的定义 -->
<!-- The following is the definition of appender -->
<!-- ===================================================================== -->
<appender name="dubbo" class="com.alibaba.dubbo.common.utils.DubboAppender">
<param name="encoding" value="GBK"/>

View File

@ -1,12 +1,13 @@
<!--
- Copyright 1999-2011 Alibaba Group.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -49,11 +50,10 @@ import java.util.concurrent.TimeUnit;
/**
* MulticastRegistry
*
* @author william.liangf
*/
public class MulticastRegistry extends FailbackRegistry {
// 日志输出
// logging output
private static final Logger logger = LoggerFactory.getLogger(MulticastRegistry.class);
private static final int DEFAULT_MULTICAST_PORT = 1234;
@ -120,8 +120,8 @@ public class MulticastRegistry extends FailbackRegistry {
this.cleanFuture = cleanExecutor.scheduleWithFixedDelay(new Runnable() {
public void run() {
try {
clean(); // 清除过期者
} catch (Throwable t) { // 防御性容错
clean(); // Remove the expired
} catch (Throwable t) { // Defensive fault tolerance
logger.error("Unexpected exception occur at clean expired provider, cause: " + t.getMessage(), t);
}
}
@ -216,8 +216,8 @@ public class MulticastRegistry extends FailbackRegistry {
if (UrlUtils.isMatch(url, u)) {
String host = remoteAddress != null && remoteAddress.getAddress() != null
? remoteAddress.getAddress().getHostAddress() : url.getIp();
if (url.getParameter("unicast", true) // 消费者的机器是否只有一个进程
&& !NetUtils.getLocalHost().equals(host)) { // 同机器多进程不能用unicast单播信息否则只会有一个进程收到信息
if (url.getParameter("unicast", true) // Whether the consumer's machine has only one process
&& !NetUtils.getLocalHost().equals(host)) { // Multiple processes in the same machine cannot be unicast with unicast or there will be only one process receiving information
unicast(Constants.REGISTER + " " + u.toFullString(), host);
} else {
broadcast(Constants.REGISTER + " " + u.toFullString());

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -22,7 +23,6 @@ import com.alibaba.dubbo.registry.support.AbstractRegistryFactory;
/**
* MulticastRegistryLocator
*
* @author william.liangf
*/
public class MulticastRegistryFactory extends AbstractRegistryFactory {

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -36,7 +37,6 @@ import static org.junit.Assert.assertTrue;
/**
* MulticastRegistryTest
*
* @author tony.chenl
*/
public class MulticastRegistryTest {
@ -69,7 +69,7 @@ public class MulticastRegistryTest {
}
/**
* Test method for {@link com.alibaba.dubbo.registry.support.injvm.InjvmRegistry#register(java.util.Map)}.
* Test method for {@link com.alibaba.dubbo.registry.multicast.MulticastRegistry#getRegistered()}.
*/
@Test
public void testRegister() {
@ -89,7 +89,7 @@ public class MulticastRegistryTest {
/**
* Test method for
* {@link com.alibaba.dubbo.registry.support.injvm.InjvmRegistry#subscribe(java.util.Map, com.alibaba.dubbo.registry.support.NotifyListener)}
* {@link com.alibaba.dubbo.registry.multicast.MulticastRegistry#subscribe(URL url, com.alibaba.dubbo.registry.NotifyListener)}
* .
*/
@Test

View File

@ -1,12 +1,13 @@
<!--
- Copyright 1999-2011 Alibaba Group.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

View File

@ -1,12 +1,12 @@
/*
* Copyright 1999-2012 Alibaba Group.
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -52,7 +52,6 @@ import java.util.concurrent.atomic.AtomicInteger;
/**
* RedisRegistry
*
* @author william.liangf
*/
public class RedisRegistry extends FailbackRegistry {
@ -154,8 +153,8 @@ public class RedisRegistry extends FailbackRegistry {
this.expireFuture = expireExecutor.scheduleWithFixedDelay(new Runnable() {
public void run() {
try {
deferExpired(); // 延长过期时间
} catch (Throwable t) { // 防御性容错
deferExpired(); // Extend the expiration time
} catch (Throwable t) { // Defensive fault tolerance
logger.error("Unexpected exception occur at defer expire time, cause: " + t.getMessage(), t);
}
}
@ -180,7 +179,7 @@ public class RedisRegistry extends FailbackRegistry {
clean(jedis);
}
if (!replicate) {
break;//  如果服务器端已同步数据只需写入单台机器
break;//  If the server side has synchronized data, just write a single machine
}
} finally {
jedisPool.returnResource(jedis);
@ -191,7 +190,7 @@ public class RedisRegistry extends FailbackRegistry {
}
}
// 监控中心负责删除过期脏数据
// The monitoring center is responsible for deleting outdated dirty data
private void clean(Jedis jedis) {
Set<String> keys = jedis.keys(root + Constants.ANY_VALUE);
if (keys != null && keys.size() > 0) {
@ -227,7 +226,7 @@ public class RedisRegistry extends FailbackRegistry {
Jedis jedis = jedisPool.getResource();
try {
if (jedis.isConnected()) {
return true; // 至少需单台机器可用
return true; // At least one single machine is available.
}
} finally {
jedisPool.returnResource(jedis);
@ -279,7 +278,7 @@ public class RedisRegistry extends FailbackRegistry {
jedis.publish(key, Constants.REGISTER);
success = true;
if (!replicate) {
break; //  如果服务器端已同步数据只需写入单台机器
break; //  If the server side has synchronized data, just write a single machine
}
} finally {
jedisPool.returnResource(jedis);
@ -312,7 +311,7 @@ public class RedisRegistry extends FailbackRegistry {
jedis.publish(key, Constants.UNREGISTER);
success = true;
if (!replicate) {
break; //  如果服务器端已同步数据只需写入单台机器
break; //  If the server side has synchronized data, just write a single machine
}
} finally {
jedisPool.returnResource(jedis);
@ -371,11 +370,11 @@ public class RedisRegistry extends FailbackRegistry {
doNotify(jedis, jedis.keys(service + Constants.PATH_SEPARATOR + Constants.ANY_VALUE), url, Arrays.asList(listener));
}
success = true;
break; // 只需读一个服务器的数据
break; // Just read one server's data
} finally {
jedisPool.returnResource(jedis);
}
} catch (Throwable t) { // 尝试下一个服务器
} catch (Throwable t) { // Try the next server
exception = new RpcException("Failed to subscribe service from redis registry. registry: " + entry.getKey() + ", service: " + url + ", cause: " + t.getMessage(), t);
}
}
@ -500,7 +499,7 @@ public class RedisRegistry extends FailbackRegistry {
} finally {
jedisPool.returnResource(jedis);
}
} catch (Throwable t) { // TODO 通知失败没有恢复机制保障
} catch (Throwable t) { // TODO Notification failure does not restore mechanism guarantee
logger.error(t.getMessage(), t);
}
}
@ -553,14 +552,14 @@ public class RedisRegistry extends FailbackRegistry {
}
private boolean isSkip() {
int skip = connectSkip.get(); // 跳过次数增长
if (skip >= 10) { // 如果跳过次数增长超过10取随机数
int skip = connectSkip.get(); // Growth of skipping times
if (skip >= 10) { // If the number of skipping times increases by more than 10, take the random number
if (connectRandom == 0) {
connectRandom = random.nextInt(10);
}
skip = 10 + connectRandom;
}
if (connectSkiped.getAndIncrement() < skip) { // 检查跳过次数
if (connectSkiped.getAndIncrement() < skip) { // Check the number of skipping times
return true;
}
connectSkip.incrementAndGet();
@ -591,22 +590,22 @@ public class RedisRegistry extends FailbackRegistry {
}
resetSkip();
}
jedis.psubscribe(new NotifySub(jedisPool), service); // 阻塞
jedis.psubscribe(new NotifySub(jedisPool), service); // blocking
} else {
if (!first) {
first = false;
doNotify(jedis, service);
resetSkip();
}
jedis.psubscribe(new NotifySub(jedisPool), service + Constants.PATH_SEPARATOR + Constants.ANY_VALUE); // 阻塞
jedis.psubscribe(new NotifySub(jedisPool), service + Constants.PATH_SEPARATOR + Constants.ANY_VALUE); // blocking
}
break;
} finally {
jedisPool.returnBrokenResource(jedis);
}
} catch (Throwable t) { // 重试另一台
} catch (Throwable t) { // Retry another server
logger.warn("Failed to subscribe service from redis registry. registry: " + entry.getKey() + ", cause: " + t.getMessage(), t);
// 如果在单台redis的情况下需要休息一会避免空转占用过多cpu资源
// If you only have a single redis, you need to take a rest to avoid overtaking a lot of CPU resources
sleep(reconnectPeriod);
}
}

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2012 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -22,7 +23,6 @@ import com.alibaba.dubbo.registry.RegistryFactory;
/**
* RedisRegistryFactory
*
* @author william.liangf
*/
public class RedisRegistryFactory implements RegistryFactory {

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2012 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -24,7 +25,6 @@ import org.junit.Test;
/**
* RedisRegistryTest
*
* @author tony.chenl
*/
public class RedisRegistryTest {
@ -53,7 +53,7 @@ public class RedisRegistryTest {
}
/**
* Test method for {@link com.alibaba.dubbo.registry.support.injvm.InjvmRegistry#register(java.util.Map)}.
* Test method for {@link com.alibaba.dubbo.registry.redis.RedisRegistry#getRegistered()}.
*/
@Test
public void testRegister() {
@ -73,7 +73,7 @@ public class RedisRegistryTest {
/**
* Test method for
* {@link com.alibaba.dubbo.registry.support.injvm.InjvmRegistry#subscribe(java.util.Map, com.alibaba.dubbo.registry.support.NotifyListener)}
* {@link com.alibaba.dubbo.registry.redis.RedisRegistry#subscribe(URL, com.alibaba.dubbo.registry.NotifyListener)}
* .
*/
@Test

View File

@ -1,12 +1,13 @@
<!--
- Copyright 1999-2011 Alibaba Group.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -38,7 +39,6 @@ import java.util.concurrent.ConcurrentMap;
/**
* ZookeeperRegistry
*
* @author william.liangf
*/
public class ZookeeperRegistry extends FailbackRegistry {

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -23,7 +24,6 @@ import com.alibaba.dubbo.remoting.zookeeper.ZookeeperTransporter;
/**
* ZookeeperRegistryFactory.
*
* @author william.liangf
*/
public class ZookeeperRegistryFactory extends AbstractRegistryFactory {

View File

@ -1,12 +1,13 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -25,7 +26,6 @@ import org.junit.Test;
/**
* ZookeeperRegistryTest
*
* @author tony.chenl
*/
public class ZookeeperRegistryTest {
@ -64,7 +64,7 @@ public class ZookeeperRegistryTest {
}
/**
* Test method for {@link com.alibaba.dubbo.registry.support.injvm.InjvmRegistry#register(java.util.Map)}.
* Test method for {@link com.alibaba.dubbo.registry.zookeeper.ZookeeperRegistry#getRegistered()}.
*/
@Test
public void testRegister() {
@ -84,7 +84,7 @@ public class ZookeeperRegistryTest {
/**
* Test method for
* {@link com.alibaba.dubbo.registry.support.injvm.InjvmRegistry#subscribe(java.util.Map, com.alibaba.dubbo.registry.support.NotifyListener)}
* {@link com.alibaba.dubbo.registry.zookeeper.ZookeeperRegistry#subscribe(URL, com.alibaba.dubbo.registry.NotifyListener)}
* .
*/
@Test

View File

@ -1,12 +1,13 @@
<!--
- Copyright 1999-2011 Alibaba Group.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
<!--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.