Add some code about error code 1-1, 4-1 with code optimization. (#10500)
* Add code of showing error code 4-1.
* Add some comments about error code 1-1 with code optimization.
diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/RouterChain.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/RouterChain.java
index f3b4f5d..9c283ff 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/RouterChain.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/RouterChain.java
@@ -241,6 +241,7 @@
RouterSnapshotNode<T> commonRouterNode = new RouterSnapshotNode<T>("CommonRouter", resultInvokers.clone());
parentNode.appendNode(commonRouterNode);
List<Invoker<T>> commonRouterResult = resultInvokers;
+
// 2. route common router
for (Router router : routers) {
// Copy resultInvokers to a arrayList. BitList not support
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java b/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java
index 29d9df9..cb98b66 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java
@@ -146,7 +146,12 @@
public URL(URLAddress urlAddress, URLParam urlParam, Map<String, Object> attributes) {
this.urlAddress = urlAddress;
this.urlParam = null == urlParam ? URLParam.parse(new HashMap<>()) : urlParam;
- this.attributes = (attributes != null ? attributes.isEmpty() ? null : attributes : null);
+
+ if (attributes != null && !attributes.isEmpty()) {
+ this.attributes = attributes;
+ } else {
+ this.attributes = null;
+ }
}
public URL(String protocol, String host, int port) {
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java
index 2d84934..474305c 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java
@@ -524,8 +524,9 @@
}
/**
- * Find the extension with the given name. If the specified name is not found, then {@link IllegalStateException}
- * will be thrown.
+ * Find the extension with the given name.
+ *
+ * @throws IllegalStateException If the specified extension is not found.
*/
public T getExtension(String name) {
T extension = getExtension(name, true);
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/URLParam.java b/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/URLParam.java
index 05deabe..243e1d4 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/URLParam.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/URLParam.java
@@ -978,7 +978,7 @@
*
* @param params params map added into URLParam
* @param rawParam original rawParam string, directly add to rawParam field,
- * will not effect real key-pairs store in URLParam.
+ * will not affect real key-pairs store in URLParam.
* Please make sure it can correspond with params or will
* cause unexpected result when calling {@link URLParam#getRawParam()}
* and {@link URLParam#toString()} ()}. If you not sure, you can call
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/UrlUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/UrlUtils.java
index 11b1e3f..0167438 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/UrlUtils.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/UrlUtils.java
@@ -412,7 +412,7 @@
// If the category of provider URL does not match the category of consumer URL.
// Usually, the provider URL's category is empty, and the default category ('providers') is present.
// Hence, the category of the provider URL is 'providers'.
- // Through observing of the Zookeeper registry, I found that the category of the consumer URL is 'consumers'.
+ // Through observing of debugging process, I found that the category of the consumer URL is 'providers,configurators,routers'.
if (!isMatchCategory(providerUrl.getCategory(DEFAULT_CATEGORY), consumerUrl.getCategory(DEFAULT_CATEGORY))) {
return false;
}
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistryDirectory.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistryDirectory.java
index 30daeb7..bdcf62d 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistryDirectory.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistryDirectory.java
@@ -294,10 +294,15 @@
continue;
}
if (!getUrl().getOrDefaultFrameworkModel().getExtensionLoader(Protocol.class).hasExtension(instanceAddressURL.getProtocol())) {
- logger.error(new IllegalStateException("Unsupported protocol " + instanceAddressURL.getProtocol() +
+
+ // 4-1 - Unsupported protocol
+
+ logger.error("4-1", "protocol extension does not installed", "", "Unsupported protocol.",
+ new IllegalStateException("Unsupported protocol " + instanceAddressURL.getProtocol() +
" in notified url: " + instanceAddressURL + " from registry " + getUrl().getAddress() +
" to consumer " + NetUtils.getLocalHost() + ", supported protocol: " +
getUrl().getOrDefaultFrameworkModel().getExtensionLoader(Protocol.class).getSupportedExtensions()));
+
continue;
}
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java
index e3573de..afe1948 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java
@@ -361,37 +361,10 @@
}
String queryProtocols = this.queryMap.get(PROTOCOL_KEY);
for (URL providerUrl : urls) {
- // 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(",");
- for (String acceptProtocol : acceptProtocols) {
- if (providerUrl.getProtocol().equals(acceptProtocol)) {
- accept = true;
- break;
- }
- }
- if (!accept) {
- continue;
- }
- }
-
- if (EMPTY_PROTOCOL.equals(providerUrl.getProtocol())) {
+ if (!checkProtocolValid(queryProtocols, providerUrl)) {
continue;
}
- if (!getUrl().getOrDefaultFrameworkModel().getExtensionLoader(Protocol.class).hasExtension(providerUrl.getProtocol())) {
-
- // 4-1 - Unsupported protocol
-
- logger.error("4-1", "typo in URL", "", "Unsupported protocol.",
- new IllegalStateException("Unsupported protocol " + providerUrl.getProtocol() +
- " in notified url: " + providerUrl + " from registry " + getUrl().getAddress() +
- " to consumer " + NetUtils.getLocalHost() + ", supported protocol: " +
- getUrl().getOrDefaultFrameworkModel().getExtensionLoader(Protocol.class).getSupportedExtensions()));
-
- continue;
- }
URL url = mergeUrl(providerUrl);
// Cache key is url that does not merge with consumer side parameters,
@@ -433,6 +406,44 @@
return newUrlInvokerMap;
}
+ private boolean checkProtocolValid(String queryProtocols, URL providerUrl) {
+ // 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(",");
+ for (String acceptProtocol : acceptProtocols) {
+ if (providerUrl.getProtocol().equals(acceptProtocol)) {
+ accept = true;
+ break;
+ }
+ }
+
+ if (!accept) {
+ return false;
+ }
+ }
+
+ if (EMPTY_PROTOCOL.equals(providerUrl.getProtocol())) {
+ return false;
+ }
+
+ if (!getUrl().getOrDefaultFrameworkModel().getExtensionLoader(Protocol.class).hasExtension(providerUrl.getProtocol())) {
+
+ // 4-1 - Unsupported protocol
+
+ logger.error("4-1", "protocol extension does not installed", "", "Unsupported protocol.",
+ new IllegalStateException("Unsupported protocol " + providerUrl.getProtocol() +
+ " in notified url: " + providerUrl + " from registry " + getUrl().getAddress() +
+ " to consumer " + NetUtils.getLocalHost() + ", supported protocol: " +
+ getUrl().getOrDefaultFrameworkModel().getExtensionLoader(Protocol.class).getSupportedExtensions()));
+
+ return false;
+ }
+
+ return true;
+ }
+
/**
* Merge url parameters. the order is: override > -D >Consumer > Provider
*
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/support/CacheableFailbackRegistry.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/support/CacheableFailbackRegistry.java
index b1cccf2..f747a30 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/support/CacheableFailbackRegistry.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/support/CacheableFailbackRegistry.java
@@ -158,15 +158,21 @@
// create new urls
Map<String, ServiceAddressURL> newURLs = new HashMap<>((int) (providers.size() / 0.75f + 1));
+
+ // remove 'release', 'dubbo', 'methods', timestamp, 'dubbo.tag' parameter
+ // in consumer URL.
URL copyOfConsumer = removeParamsFromConsumer(consumer);
if (oldURLs == null) {
for (String rawProvider : providers) {
+ // remove timestamp in provider url.
rawProvider = stripOffVariableKeys(rawProvider);
+
+ // create DubboServiceAddress object using provider url, consumer url, and extra parameters.
ServiceAddressURL cachedURL = createURL(rawProvider, copyOfConsumer, getExtraParameters());
if (cachedURL == null) {
// 1-1: Address invalid.
- logger.warn("1-1", "", "",
+ logger.warn("1-1", "mismatch of service group and version settings", "",
"Invalid address, failed to parse into URL " + rawProvider);
continue;
@@ -174,14 +180,14 @@
newURLs.put(rawProvider, cachedURL);
}
} else {
- // maybe only default , or "env" + default
+ // maybe only default, or "env" + default
for (String rawProvider : providers) {
rawProvider = stripOffVariableKeys(rawProvider);
ServiceAddressURL cachedURL = oldURLs.remove(rawProvider);
if (cachedURL == null) {
cachedURL = createURL(rawProvider, copyOfConsumer, getExtraParameters());
if (cachedURL == null) {
- logger.warn("1-1", "", "",
+ logger.warn("1-1", "mismatch of service group and version settings", "",
"Invalid address, failed to parse into URL " + rawProvider);
continue;
@@ -233,16 +239,31 @@
return urls;
}
+ /**
+ * Create DubboServiceAddress object using provider url, consumer url, and extra parameters.
+ *
+ * @param rawProvider provider url string
+ * @param consumerURL URL object of consumer
+ * @param extraParameters extra parameters
+ * @return created DubboServiceAddressURL object
+ */
protected ServiceAddressURL createURL(String rawProvider, URL consumerURL, Map<String, String> extraParameters) {
+
boolean encoded = true;
// use encoded value directly to avoid URLDecoder.decode allocation.
int paramStartIdx = rawProvider.indexOf(ENCODED_QUESTION_MARK);
- if (paramStartIdx == -1) {// if ENCODED_QUESTION_MARK does not show, mark as not encoded.
+
+ if (paramStartIdx == -1) {
+ // if ENCODED_QUESTION_MARK does not show, mark as not encoded.
encoded = false;
}
+ // split by (encoded) question mark.
+ // part[0] => protocol + ip address + interface.
+ // part[1] => parameters (metadata).
String[] parts = URLStrParser.parseRawURLToArrays(rawProvider, paramStartIdx);
+
if (parts.length <= 1) {
// 1-5 Received URL without any parameters.
logger.warn("1-5", "", "",
@@ -257,16 +278,18 @@
// Workaround for 'effectively final': duplicate the encoded variable.
boolean isEncoded = encoded;
+ // PathURLAddress if it's using dubbo protocol.
URLAddress address = stringAddress.computeIfAbsent(rawAddress, k -> URLAddress.parse(k, getDefaultURLProtocol(), isEncoded));
address.setTimestamp(System.currentTimeMillis());
URLParam param = stringParam.computeIfAbsent(rawParams, k -> URLParam.parse(k, isEncoded, extraParameters));
param.setTimestamp(System.currentTimeMillis());
- ServiceAddressURL cachedURL = createServiceURL(address, param, consumerURL);
+ // create service URL using cached address, param, and consumer URL.
+ ServiceAddressURL cachedServiceAddressURL = createServiceURL(address, param, consumerURL);
- if (isMatch(consumerURL, cachedURL)) {
- return cachedURL;
+ if (isMatch(consumerURL, cachedServiceAddressURL)) {
+ return cachedServiceAddressURL;
}
return null;
diff --git a/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/ZookeeperRegistry.java b/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/ZookeeperRegistry.java
index e4af8f8..48b3005 100644
--- a/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/ZookeeperRegistry.java
+++ b/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/ZookeeperRegistry.java
@@ -185,6 +185,14 @@
try {
List<URL> urls = new ArrayList<>();
+ /*
+ Iterate over the category value in URL.
+ With default settings, the path variable can be when url is a consumer URL:
+
+ /dubbo/[service name]/providers,
+ /dubbo/[service name]/configurators
+ /dubbo/[service name]/routers
+ */
for (String path : toCategoriesPath(url)) {
ConcurrentMap<NotifyListener, ChildListener> listeners = zkListeners.computeIfAbsent(url, k -> new ConcurrentHashMap<>());
ChildListener zkListener = listeners.computeIfAbsent(listener, k -> new RegistryChildListenerImpl(url, k, latch));
@@ -193,9 +201,13 @@
((RegistryChildListenerImpl) zkListener).setLatch(latch);
}
+ // create "directories".
zkClient.create(path, false);
+
+ // Add children (i.e. service items).
List<String> children = zkClient.addChildListener(path, zkListener);
if (children != null) {
+ // The invocation point that may cause 1-1.
urls.addAll(toUrlsWithEmpty(url, path, children));
}
}
@@ -321,6 +333,11 @@
return UrlUtils.isMatch(subscribeUrl, providerUrl);
}
+ /**
+ * Triggered when children get changed. It will be invoked by implementation of CuratorWatcher.
+ *
+ * 'org.apache.dubbo.remoting.zookeeper.curator5.Curator5ZookeeperClient.CuratorWatcherImpl' (Curator 5)
+ */
private class RegistryChildListenerImpl implements ChildListener {
private final ZookeeperRegistryNotifier notifier;
private volatile CountDownLatch latch;
@@ -336,11 +353,13 @@
@Override
public void childChanged(String path, List<String> children) {
+ // Notify 'notifiers' one by one.
try {
latch.await();
} catch (InterruptedException e) {
logger.warn("Zookeeper children listener thread was interrupted unexpectedly, may cause race condition with the main thread.");
}
+
notifier.notify(path, children);
}
}