This is an automated email from the ASF dual-hosted git repository.
albumenj pushed a commit to branch 3.1
in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/3.1 by this push:
new 673375b9bf Add nacos create client retry (#11304)
673375b9bf is described below
commit 673375b9bf3200b23b52aaa84eab61ee148d6f6e
Author: Albumen Kevin <[email protected]>
AuthorDate: Sat Jan 14 21:41:07 2023 +0800
Add nacos create client retry (#11304)
---
.../support/nacos/NacosDynamicConfiguration.java | 59 +++++++++++----
.../support/nacos/MockConfigService.java | 78 ++++++++++++++++++++
.../configcenter/support/nacos/RetryTest.java | 86 ++++++++++++++++++++++
.../metadata/store/nacos/NacosMetadataReport.java | 73 +++++++++++++-----
.../metadata/store/nacos/MockConfigService.java | 78 ++++++++++++++++++++
.../dubbo/metadata/store/nacos/RetryTest.java | 85 +++++++++++++++++++++
.../registry/nacos/NacosNamingServiceWrapper.java | 4 +-
.../nacos/util/NacosNamingServiceUtils.java | 41 +++++++++--
.../registry/nacos/NacosRegistryFactoryTest.java | 5 +-
.../dubbo/registry/nacos/NacosRegistryTest.java | 2 +-
.../nacos/NacosServiceDiscoveryFactoryTest.java | 3 +-
.../registry/nacos/NacosServiceDiscoveryTest.java | 26 +++----
.../nacos/util/NacosNamingServiceUtilsTest.java | 47 ++++++++++--
13 files changed, 523 insertions(+), 64 deletions(-)
diff --git
a/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java
b/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java
index 2f43c85f27..beb2400860 100644
---
a/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java
+++
b/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java
@@ -17,12 +17,20 @@
package org.apache.dubbo.configcenter.support.nacos;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.Executor;
+
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.config.configcenter.ConfigChangeType;
import org.apache.dubbo.common.config.configcenter.ConfigChangedEvent;
import org.apache.dubbo.common.config.configcenter.ConfigItem;
import org.apache.dubbo.common.config.configcenter.ConfigurationListener;
import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
+import org.apache.dubbo.common.constants.LoggerCodeConstants;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.MD5Utils;
@@ -34,17 +42,12 @@ import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.AbstractSharedListener;
import com.alibaba.nacos.api.exception.NacosException;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.concurrent.Executor;
-
import static com.alibaba.nacos.api.PropertyKeyConst.PASSWORD;
import static com.alibaba.nacos.api.PropertyKeyConst.SERVER_ADDR;
import static com.alibaba.nacos.api.PropertyKeyConst.USERNAME;
+import static com.alibaba.nacos.client.constant.Constants.HealthCheck.UP;
import static
org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_ERROR_NACOS;
+import static
org.apache.dubbo.common.constants.LoggerCodeConstants.INTERNAL_INTERRUPTED;
import static org.apache.dubbo.common.constants.RemotingConstants.BACKUP_KEY;
import static
org.apache.dubbo.common.utils.StringConstantFieldValuePredicate.of;
import static org.apache.dubbo.common.utils.StringUtils.HYPHEN_CHAR;
@@ -64,6 +67,12 @@ public class NacosDynamicConfiguration implements
DynamicConfiguration {
private Properties nacosProperties;
+ private static final String NACOS_RETRY_KEY = "nacos.retry";
+
+ private static final String NACOS_RETRY_WAIT_KEY = "nacos.retry-wait";
+
+ private static final String NACOS_CHECK_KEY = "nacos.check";
+
/**
* The nacos configService
*/
@@ -83,16 +92,40 @@ public class NacosDynamicConfiguration implements
DynamicConfiguration {
}
private NacosConfigServiceWrapper buildConfigService(URL url) {
- ConfigService configService = null;
+ int retryTimes = url.getPositiveParameter(NACOS_RETRY_KEY, 10);
+ int sleepMsBetweenRetries =
url.getPositiveParameter(NACOS_RETRY_WAIT_KEY, 1000);
+ boolean check = url.getParameter(NACOS_CHECK_KEY, true);
+ ConfigService tmpConfigServices = null;
try {
- configService = NacosFactory.createConfigService(nacosProperties);
- } catch (NacosException e) {
- if (logger.isErrorEnabled()) {
- logger.error(CONFIG_ERROR_NACOS, "", "", e.getMessage(), e);
+ for (int i = 0; i < retryTimes + 1; i++) {
+ tmpConfigServices =
NacosFactory.createConfigService(nacosProperties);
+ if (!check || UP.equals(tmpConfigServices.getServerStatus())) {
+ break;
+ } else {
+ logger.warn(LoggerCodeConstants.CONFIG_ERROR_NACOS, "", "",
+ "Failed to connect to nacos config server. " +
+ (i < retryTimes ? "Dubbo will try to retry in " +
sleepMsBetweenRetries + ". " : "Exceed retry max times.") +
+ "Try times: " + (i + 1));
+ }
+ tmpConfigServices.shutDown();
+ tmpConfigServices = null;
+ Thread.sleep(sleepMsBetweenRetries);
}
+ } catch (NacosException e) {
+ logger.error(CONFIG_ERROR_NACOS, "", "", e.getErrMsg(), e);
+ throw new IllegalStateException(e);
+ } catch (InterruptedException e) {
+ logger.error(INTERNAL_INTERRUPTED, "", "", "Interrupted when
creating nacos config service client.", e);
+ Thread.currentThread().interrupt();
throw new IllegalStateException(e);
}
- return new NacosConfigServiceWrapper(configService);
+
+ if (tmpConfigServices == null) {
+ logger.error(CONFIG_ERROR_NACOS, "", "", "Failed to create nacos
config service client. Reason: server status check failed.");
+ throw new IllegalStateException("Failed to create nacos config
service client. Reason: server status check failed.");
+ }
+
+ return new NacosConfigServiceWrapper(tmpConfigServices);
}
private Properties buildNacosProperties(URL url) {
diff --git
a/dubbo-configcenter/dubbo-configcenter-nacos/src/test/java/org/apache/dubbo/configcenter/support/nacos/MockConfigService.java
b/dubbo-configcenter/dubbo-configcenter-nacos/src/test/java/org/apache/dubbo/configcenter/support/nacos/MockConfigService.java
new file mode 100644
index 0000000000..bba7741e64
--- /dev/null
+++
b/dubbo-configcenter/dubbo-configcenter-nacos/src/test/java/org/apache/dubbo/configcenter/support/nacos/MockConfigService.java
@@ -0,0 +1,78 @@
+/*
+ * 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 org.apache.dubbo.configcenter.support.nacos;
+
+import com.alibaba.nacos.api.config.ConfigService;
+import com.alibaba.nacos.api.config.listener.Listener;
+import com.alibaba.nacos.api.exception.NacosException;
+
+public class MockConfigService implements ConfigService {
+ @Override
+ public String getConfig(String dataId, String group, long timeoutMs)
throws NacosException {
+ return null;
+ }
+
+ @Override
+ public String getConfigAndSignListener(String dataId, String group, long
timeoutMs, Listener listener) throws NacosException {
+ return null;
+ }
+
+ @Override
+ public void addListener(String dataId, String group, Listener listener)
throws NacosException {
+
+ }
+
+ @Override
+ public boolean publishConfig(String dataId, String group, String content)
throws NacosException {
+ return false;
+ }
+
+ @Override
+ public boolean publishConfig(String dataId, String group, String content,
String type) throws NacosException {
+ return false;
+ }
+
+ @Override
+ public boolean publishConfigCas(String dataId, String group, String
content, String casMd5) throws NacosException {
+ return false;
+ }
+
+ @Override
+ public boolean publishConfigCas(String dataId, String group, String
content, String casMd5, String type) throws NacosException {
+ return false;
+ }
+
+ @Override
+ public boolean removeConfig(String dataId, String group) throws
NacosException {
+ return false;
+ }
+
+ @Override
+ public void removeListener(String dataId, String group, Listener listener)
{
+
+ }
+
+ @Override
+ public String getServerStatus() {
+ return null;
+ }
+
+ @Override
+ public void shutDown() throws NacosException {
+
+ }
+}
diff --git
a/dubbo-configcenter/dubbo-configcenter-nacos/src/test/java/org/apache/dubbo/configcenter/support/nacos/RetryTest.java
b/dubbo-configcenter/dubbo-configcenter-nacos/src/test/java/org/apache/dubbo/configcenter/support/nacos/RetryTest.java
new file mode 100644
index 0000000000..e90a5cb016
--- /dev/null
+++
b/dubbo-configcenter/dubbo-configcenter-nacos/src/test/java/org/apache/dubbo/configcenter/support/nacos/RetryTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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 org.apache.dubbo.configcenter.support.nacos;
+
+import java.util.Properties;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.dubbo.common.URL;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+
+import com.alibaba.nacos.api.NacosFactory;
+import com.alibaba.nacos.api.config.ConfigService;
+
+import static com.alibaba.nacos.client.constant.Constants.HealthCheck.DOWN;
+import static com.alibaba.nacos.client.constant.Constants.HealthCheck.UP;
+import static org.mockito.ArgumentMatchers.any;
+
+class RetryTest {
+
+ @Test
+ void testRetryCreate() {
+ try (MockedStatic<NacosFactory> nacosFactoryMockedStatic =
Mockito.mockStatic(NacosFactory.class)) {
+ AtomicInteger atomicInteger = new AtomicInteger(0);
+ ConfigService mock = new MockConfigService() {
+ @Override
+ public String getServerStatus() {
+ return atomicInteger.incrementAndGet() > 10 ? UP : DOWN;
+ }
+ };
+ nacosFactoryMockedStatic.when(() ->
NacosFactory.createConfigService((Properties) any())).thenReturn(mock);
+
+
+ URL url = URL.valueOf("nacos://127.0.0.1:8848")
+ .addParameter("nacos.retry", 5)
+ .addParameter("nacos.retry-wait", 10);
+ Assertions.assertThrows(IllegalStateException.class, () -> new
NacosDynamicConfiguration(url));
+
+ try {
+ new NacosDynamicConfiguration(url);
+ } catch (Throwable t) {
+ Assertions.fail(t);
+ }
+ }
+ }
+
+ @Test
+ void testDisable() {
+ try (MockedStatic<NacosFactory> nacosFactoryMockedStatic =
Mockito.mockStatic(NacosFactory.class)) {
+ ConfigService mock = new MockConfigService() {
+ @Override
+ public String getServerStatus() {
+ return DOWN;
+ }
+ };
+ nacosFactoryMockedStatic.when(() ->
NacosFactory.createConfigService((Properties) any())).thenReturn(mock);
+
+
+ URL url = URL.valueOf("nacos://127.0.0.1:8848")
+ .addParameter("nacos.retry", 5)
+ .addParameter("nacos.retry-wait", 10)
+ .addParameter("nacos.check", "false");
+ try {
+ new NacosDynamicConfiguration(url);
+ } catch (Throwable t) {
+ Assertions.fail(t);
+ }
+ }
+ }
+}
diff --git
a/dubbo-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReport.java
b/dubbo-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReport.java
index 88f65ba642..9d2a93c24a 100644
---
a/dubbo-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReport.java
+++
b/dubbo-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReport.java
@@ -17,11 +17,24 @@
package org.apache.dubbo.metadata.store.nacos;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.Executor;
+
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.config.configcenter.ConfigChangeType;
import org.apache.dubbo.common.config.configcenter.ConfigChangedEvent;
import org.apache.dubbo.common.config.configcenter.ConfigItem;
import org.apache.dubbo.common.config.configcenter.ConfigurationListener;
+import org.apache.dubbo.common.constants.LoggerCodeConstants;
import org.apache.dubbo.common.utils.JsonUtils;
import org.apache.dubbo.common.utils.MD5Utils;
import org.apache.dubbo.common.utils.StringUtils;
@@ -38,23 +51,15 @@ import
org.apache.dubbo.metadata.report.support.AbstractMetadataReport;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.PropertyKeyConst;
+import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.AbstractSharedListener;
import com.alibaba.nacos.api.exception.NacosException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.concurrent.Executor;
-
import static com.alibaba.nacos.api.PropertyKeyConst.SERVER_ADDR;
+import static com.alibaba.nacos.client.constant.Constants.HealthCheck.UP;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
+import static
org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_ERROR_NACOS;
+import static
org.apache.dubbo.common.constants.LoggerCodeConstants.INTERNAL_INTERRUPTED;
import static
org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_NACOS_EXCEPTION;
import static org.apache.dubbo.common.constants.RemotingConstants.BACKUP_KEY;
import static
org.apache.dubbo.common.utils.StringConstantFieldValuePredicate.of;
@@ -81,25 +86,57 @@ public class NacosMetadataReport extends
AbstractMetadataReport {
private MD5Utils md5Utils = new MD5Utils();
+ private static final String NACOS_RETRY_KEY = "nacos.retry";
+
+ private static final String NACOS_RETRY_WAIT_KEY = "nacos.retry-wait";
+
+ private static final String NACOS_CHECK_KEY = "nacos.check";
+
public NacosMetadataReport(URL url) {
super(url);
this.configService = buildConfigService(url);
group = url.getParameter(GROUP_KEY, DEFAULT_ROOT);
}
- public NacosConfigServiceWrapper buildConfigService(URL url) {
+ private NacosConfigServiceWrapper buildConfigService(URL url) {
Properties nacosProperties = buildNacosProperties(url);
+ int retryTimes = url.getPositiveParameter(NACOS_RETRY_KEY, 10);
+ int sleepMsBetweenRetries =
url.getPositiveParameter(NACOS_RETRY_WAIT_KEY, 1000);
+ boolean check = url.getParameter(NACOS_CHECK_KEY, true);
+ ConfigService tmpConfigServices = null;
try {
- configService = new
NacosConfigServiceWrapper(NacosFactory.createConfigService(nacosProperties));
- } catch (NacosException e) {
- if (logger.isErrorEnabled()) {
- logger.error(REGISTRY_NACOS_EXCEPTION, "", "", e.getErrMsg(),
e);
+ for (int i = 0; i < retryTimes + 1; i++) {
+ tmpConfigServices =
NacosFactory.createConfigService(nacosProperties);
+ if (!check || UP.equals(tmpConfigServices.getServerStatus())) {
+ break;
+ } else {
+ logger.warn(LoggerCodeConstants.CONFIG_ERROR_NACOS, "", "",
+ "Failed to connect to nacos config server. " +
+ (i < retryTimes ? "Dubbo will try to retry in " +
sleepMsBetweenRetries + ". " : "Exceed retry max times.") +
+ "Try times: " + (i + 1));
+ }
+ tmpConfigServices.shutDown();
+ tmpConfigServices = null;
+ Thread.sleep(sleepMsBetweenRetries);
}
+ } catch (NacosException e) {
+ logger.error(CONFIG_ERROR_NACOS, "", "", e.getErrMsg(), e);
+ throw new IllegalStateException(e);
+ } catch (InterruptedException e) {
+ logger.error(INTERNAL_INTERRUPTED, "", "", "Interrupted when
creating nacos config service client.", e);
+ Thread.currentThread().interrupt();
throw new IllegalStateException(e);
}
- return configService;
+
+ if (tmpConfigServices == null) {
+ logger.error(CONFIG_ERROR_NACOS, "", "", "Failed to create nacos
config service client. Reason: server status check failed.");
+ throw new IllegalStateException("Failed to create nacos config
service client. Reason: server status check failed.");
+ }
+
+ return new NacosConfigServiceWrapper(tmpConfigServices);
}
+
private Properties buildNacosProperties(URL url) {
Properties properties = new Properties();
setServerAddr(url, properties);
diff --git
a/dubbo-metadata/dubbo-metadata-report-nacos/src/test/java/org/apache/dubbo/metadata/store/nacos/MockConfigService.java
b/dubbo-metadata/dubbo-metadata-report-nacos/src/test/java/org/apache/dubbo/metadata/store/nacos/MockConfigService.java
new file mode 100644
index 0000000000..86b5b879f7
--- /dev/null
+++
b/dubbo-metadata/dubbo-metadata-report-nacos/src/test/java/org/apache/dubbo/metadata/store/nacos/MockConfigService.java
@@ -0,0 +1,78 @@
+/*
+ * 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 org.apache.dubbo.metadata.store.nacos;
+
+import com.alibaba.nacos.api.config.ConfigService;
+import com.alibaba.nacos.api.config.listener.Listener;
+import com.alibaba.nacos.api.exception.NacosException;
+
+public class MockConfigService implements ConfigService {
+ @Override
+ public String getConfig(String dataId, String group, long timeoutMs)
throws NacosException {
+ return null;
+ }
+
+ @Override
+ public String getConfigAndSignListener(String dataId, String group, long
timeoutMs, Listener listener) throws NacosException {
+ return null;
+ }
+
+ @Override
+ public void addListener(String dataId, String group, Listener listener)
throws NacosException {
+
+ }
+
+ @Override
+ public boolean publishConfig(String dataId, String group, String content)
throws NacosException {
+ return false;
+ }
+
+ @Override
+ public boolean publishConfig(String dataId, String group, String content,
String type) throws NacosException {
+ return false;
+ }
+
+ @Override
+ public boolean publishConfigCas(String dataId, String group, String
content, String casMd5) throws NacosException {
+ return false;
+ }
+
+ @Override
+ public boolean publishConfigCas(String dataId, String group, String
content, String casMd5, String type) throws NacosException {
+ return false;
+ }
+
+ @Override
+ public boolean removeConfig(String dataId, String group) throws
NacosException {
+ return false;
+ }
+
+ @Override
+ public void removeListener(String dataId, String group, Listener listener)
{
+
+ }
+
+ @Override
+ public String getServerStatus() {
+ return null;
+ }
+
+ @Override
+ public void shutDown() throws NacosException {
+
+ }
+}
diff --git
a/dubbo-metadata/dubbo-metadata-report-nacos/src/test/java/org/apache/dubbo/metadata/store/nacos/RetryTest.java
b/dubbo-metadata/dubbo-metadata-report-nacos/src/test/java/org/apache/dubbo/metadata/store/nacos/RetryTest.java
new file mode 100644
index 0000000000..9159e076fc
--- /dev/null
+++
b/dubbo-metadata/dubbo-metadata-report-nacos/src/test/java/org/apache/dubbo/metadata/store/nacos/RetryTest.java
@@ -0,0 +1,85 @@
+/*
+ * 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 org.apache.dubbo.metadata.store.nacos;
+
+import java.util.Properties;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.dubbo.common.URL;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+
+import com.alibaba.nacos.api.NacosFactory;
+import com.alibaba.nacos.api.config.ConfigService;
+
+import static com.alibaba.nacos.client.constant.Constants.HealthCheck.DOWN;
+import static com.alibaba.nacos.client.constant.Constants.HealthCheck.UP;
+import static org.mockito.ArgumentMatchers.any;
+
+class RetryTest {
+
+ @Test
+ void testRetryCreate() {
+ try (MockedStatic<NacosFactory> nacosFactoryMockedStatic =
Mockito.mockStatic(NacosFactory.class)) {
+ AtomicInteger atomicInteger = new AtomicInteger(0);
+ ConfigService mock = new MockConfigService() {
+ @Override
+ public String getServerStatus() {
+ return atomicInteger.incrementAndGet() > 10 ? UP : DOWN;
+ }
+ };
+ nacosFactoryMockedStatic.when(() ->
NacosFactory.createConfigService((Properties) any())).thenReturn(mock);
+
+
+ URL url = URL.valueOf("nacos://127.0.0.1:8848")
+ .addParameter("nacos.retry", 5)
+ .addParameter("nacos.retry-wait", 10);
+ Assertions.assertThrows(IllegalStateException.class, () -> new
NacosMetadataReport(url));
+
+ try {
+ new NacosMetadataReport(url);
+ } catch (Throwable t) {
+ Assertions.fail(t);
+ }
+ }
+ }
+ @Test
+ void testDisable() {
+ try (MockedStatic<NacosFactory> nacosFactoryMockedStatic =
Mockito.mockStatic(NacosFactory.class)) {
+ ConfigService mock = new MockConfigService() {
+ @Override
+ public String getServerStatus() {
+ return DOWN;
+ }
+ };
+ nacosFactoryMockedStatic.when(() ->
NacosFactory.createConfigService((Properties) any())).thenReturn(mock);
+
+
+ URL url = URL.valueOf("nacos://127.0.0.1:8848")
+ .addParameter("nacos.retry", 5)
+ .addParameter("nacos.retry-wait", 10)
+ .addParameter("nacos.check", "false");
+ try {
+ new NacosMetadataReport(url);
+ } catch (Throwable t) {
+ Assertions.fail(t);
+ }
+ }
+ }
+}
diff --git
a/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosNamingServiceWrapper.java
b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosNamingServiceWrapper.java
index e1185aa15b..6bc12e17b6 100644
---
a/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosNamingServiceWrapper.java
+++
b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosNamingServiceWrapper.java
@@ -117,7 +117,7 @@ public class NacosNamingServiceWrapper {
logger.warn(LoggerCodeConstants.REGISTRY_NACOS_EXCEPTION, "",
"",
"Failed to request nacos naming server. " +
(times < retryTimes ? "Dubbo will try to retry in " +
sleepMsBetweenRetries + ". " : "Exceed retry max times.") +
- "Try times: " + times + 1, e);
+ "Try times: " + (times + 1), e);
if (times < retryTimes) {
try {
Thread.sleep(sleepMsBetweenRetries);
@@ -151,7 +151,7 @@ public class NacosNamingServiceWrapper {
logger.warn(LoggerCodeConstants.REGISTRY_NACOS_EXCEPTION, "",
"",
"Failed to request nacos naming server. " +
(times < retryTimes ? "Dubbo will try to retry in " +
sleepMsBetweenRetries + ". " : "Exceed retry max times.") +
- "Try times: " + times + 1, e);
+ "Try times: " + (times + 1), e);
if (times < retryTimes) {
try {
Thread.sleep(sleepMsBetweenRetries);
diff --git
a/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/util/NacosNamingServiceUtils.java
b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/util/NacosNamingServiceUtils.java
index c085701d86..b7809911a2 100644
---
a/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/util/NacosNamingServiceUtils.java
+++
b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/util/NacosNamingServiceUtils.java
@@ -20,6 +20,7 @@ import java.util.Map;
import java.util.Properties;
import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.constants.LoggerCodeConstants;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.StringUtils;
@@ -39,8 +40,10 @@ import static
com.alibaba.nacos.api.PropertyKeyConst.PASSWORD;
import static com.alibaba.nacos.api.PropertyKeyConst.SERVER_ADDR;
import static com.alibaba.nacos.api.PropertyKeyConst.USERNAME;
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
+import static com.alibaba.nacos.client.constant.Constants.HealthCheck.UP;
import static
com.alibaba.nacos.client.naming.utils.UtilAndComs.NACOS_NAMING_LOG_NAME;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
+import static
org.apache.dubbo.common.constants.LoggerCodeConstants.INTERNAL_INTERRUPTED;
import static
org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_NACOS_EXCEPTION;
import static org.apache.dubbo.common.constants.RemotingConstants.BACKUP_KEY;
import static
org.apache.dubbo.common.utils.StringConstantFieldValuePredicate.of;
@@ -57,6 +60,8 @@ public class NacosNamingServiceUtils {
private static final String NACOS_RETRY_KEY = "nacos.retry";
+ private static final String NACOS_CHECK_KEY = "nacos.check";
+
private static final String NACOS_RETRY_WAIT_KEY = "nacos.retry-wait";
@@ -119,17 +124,39 @@ public class NacosNamingServiceUtils {
*/
public static NacosNamingServiceWrapper createNamingService(URL
connectionURL) {
Properties nacosProperties = buildNacosProperties(connectionURL);
- NamingService namingService;
+ int retryTimes = connectionURL.getPositiveParameter(NACOS_RETRY_KEY,
10);
+ int sleepMsBetweenRetries =
connectionURL.getPositiveParameter(NACOS_RETRY_WAIT_KEY, 1000);
+ boolean check = connectionURL.getParameter(NACOS_CHECK_KEY, true);
+ NamingService namingService = null;
try {
- namingService = NacosFactory.createNamingService(nacosProperties);
- } catch (NacosException e) {
- if (logger.isErrorEnabled()) {
- logger.error(REGISTRY_NACOS_EXCEPTION, "", "", e.getErrMsg(),
e);
+ for (int i = 0; i < retryTimes + 1; i++) {
+ namingService =
NacosFactory.createNamingService(nacosProperties);
+ if (!check || UP.equals(namingService.getServerStatus())) {
+ break;
+ } else {
+ logger.warn(LoggerCodeConstants.REGISTRY_NACOS_EXCEPTION,
"", "",
+ "Failed to connect to nacos naming server. " +
+ (i < retryTimes ? "Dubbo will try to retry in " +
sleepMsBetweenRetries + ". " : "Exceed retry max times.") +
+ "Try times: " + (i + 1));
+ }
+ namingService.shutDown();
+ namingService = null;
+ Thread.sleep(sleepMsBetweenRetries);
}
+ } catch (NacosException e) {
+ logger.error(REGISTRY_NACOS_EXCEPTION, "", "", e.getErrMsg(), e);
+ throw new IllegalStateException(e);
+ } catch (InterruptedException e) {
+ logger.error(INTERNAL_INTERRUPTED, "", "", "Interrupted when
creating nacos naming service client.", e);
+ Thread.currentThread().interrupt();
throw new IllegalStateException(e);
}
- int retryTimes = connectionURL.getParameter(NACOS_RETRY_KEY, 10);
- int sleepMsBetweenRetries =
connectionURL.getParameter(NACOS_RETRY_WAIT_KEY, 10);
+
+ if (namingService == null) {
+ logger.error(REGISTRY_NACOS_EXCEPTION, "", "", "Failed to create
nacos naming service client. Reason: server status check failed.");
+ throw new IllegalStateException("Failed to create nacos naming
service client. Reason: server status check failed.");
+ }
+
return new NacosNamingServiceWrapper(namingService, retryTimes,
sleepMsBetweenRetries);
}
diff --git
a/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosRegistryFactoryTest.java
b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosRegistryFactoryTest.java
index 1df7d4d760..2af57626a4 100644
---
a/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosRegistryFactoryTest.java
+++
b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosRegistryFactoryTest.java
@@ -18,7 +18,6 @@ package org.apache.dubbo.registry.nacos;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.utils.NetUtils;
-
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
@@ -42,7 +41,7 @@ class NacosRegistryFactoryTest {
@Test
void testCreateRegistryCacheKey() {
- URL url = URL.valueOf("dubbo://" +
NetUtils.getLocalAddress().getHostAddress() + ":8080");
+ URL url = URL.valueOf("dubbo://" +
NetUtils.getLocalAddress().getHostAddress() + ":8080?nacos.check=false");
String registryCacheKey1 =
nacosRegistryFactory.createRegistryCacheKey(url);
String registryCacheKey2 =
nacosRegistryFactory.createRegistryCacheKey(url);
Assertions.assertEquals(registryCacheKey1, registryCacheKey2);
@@ -50,7 +49,7 @@ class NacosRegistryFactoryTest {
@Test
void testCreateRegistryCacheKeyWithNamespace() {
- URL url = URL.valueOf("dubbo://" +
NetUtils.getLocalAddress().getHostAddress() + ":8080?namespace=test");
+ URL url = URL.valueOf("dubbo://" +
NetUtils.getLocalAddress().getHostAddress() +
":8080?namespace=test&nacos.check=false");
String registryCacheKey1 =
nacosRegistryFactory.createRegistryCacheKey(url);
String registryCacheKey2 =
nacosRegistryFactory.createRegistryCacheKey(url);
Assertions.assertEquals(registryCacheKey1, registryCacheKey2);
diff --git
a/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosRegistryTest.java
b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosRegistryTest.java
index c0568d3c52..82efa81bd9 100644
---
a/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosRegistryTest.java
+++
b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosRegistryTest.java
@@ -69,7 +69,7 @@ class NacosRegistryTest {
int nacosServerPort = NetUtils.getAvailablePort();
- this.registryUrl = URL.valueOf("nacos://localhost:" + nacosServerPort);
+ this.registryUrl = URL.valueOf("nacos://localhost:" + nacosServerPort
+ "?nacos.check=false");
this.nacosRegistryFactory = new NacosRegistryFactory();
diff --git
a/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosServiceDiscoveryFactoryTest.java
b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosServiceDiscoveryFactoryTest.java
index c52466d9a6..6f9003490c 100644
---
a/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosServiceDiscoveryFactoryTest.java
+++
b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosServiceDiscoveryFactoryTest.java
@@ -20,7 +20,6 @@ import org.apache.dubbo.common.URL;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.registry.client.ServiceDiscovery;
import org.apache.dubbo.rpc.model.ApplicationModel;
-
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -42,7 +41,7 @@ class NacosServiceDiscoveryFactoryTest {
@Test
void testGetServiceDiscoveryWithCache() {
- URL url = URL.valueOf("dubbo://test:8080");
+ URL url = URL.valueOf("dubbo://test:8080?nacos.check=false");
ServiceDiscovery discovery =
nacosServiceDiscoveryFactory.createDiscovery(url);
Assertions.assertTrue(discovery instanceof NacosServiceDiscovery);
diff --git
a/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosServiceDiscoveryTest.java
b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosServiceDiscoveryTest.java
index 962acca8af..d994a08f59 100644
---
a/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosServiceDiscoveryTest.java
+++
b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosServiceDiscoveryTest.java
@@ -16,6 +16,12 @@
*/
package org.apache.dubbo.registry.nacos;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.config.ApplicationConfig;
@@ -25,10 +31,6 @@ import
org.apache.dubbo.registry.client.event.ServiceInstancesChangedEvent;
import
org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListener;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.ScopeModelUtil;
-
-import com.alibaba.nacos.api.exception.NacosException;
-import com.alibaba.nacos.api.naming.pojo.Instance;
-import com.alibaba.nacos.api.naming.pojo.ListView;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
@@ -37,11 +39,9 @@ import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.internal.util.collections.Sets;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
+import com.alibaba.nacos.api.exception.NacosException;
+import com.alibaba.nacos.api.naming.pojo.Instance;
+import com.alibaba.nacos.api.naming.pojo.ListView;
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -63,7 +63,7 @@ class NacosServiceDiscoveryTest {
private static final String LOCALHOST = "127.0.0.1";
- protected URL registryUrl = URL.valueOf("nacos://127.0.0.1:" +
NetUtils.getAvailablePort());
+ protected URL registryUrl = URL.valueOf("nacos://127.0.0.1:" +
NetUtils.getAvailablePort() + "?nacos.check=false");
private NacosServiceDiscovery nacosServiceDiscovery;
@@ -79,7 +79,7 @@ class NacosServiceDiscoveryTest {
public NacosServiceDiscoveryGroupTest1() {
super();
group = "test-group1";
- registryUrl = URL.valueOf("nacos://127.0.0.1:" +
NetUtils.getAvailablePort()).addParameter("group", group);
+ registryUrl = URL.valueOf("nacos://127.0.0.1:" +
NetUtils.getAvailablePort() + "?nacos.check=false").addParameter("group",
group);
}
}
@@ -87,7 +87,7 @@ class NacosServiceDiscoveryTest {
public NacosServiceDiscoveryGroupTest2() {
super();
group = "test-group2";
- registryUrl = URL.valueOf("nacos://127.0.0.1:" +
NetUtils.getAvailablePort()).addParameter("group", group);
+ registryUrl = URL.valueOf("nacos://127.0.0.1:" +
NetUtils.getAvailablePort() + "?nacos.check=false").addParameter("group",
group);
}
}
@@ -97,7 +97,7 @@ class NacosServiceDiscoveryTest {
public NacosServiceDiscoveryGroupTest3() {
super();
group = DEFAULT_GROUP;
- registryUrl = URL.valueOf("nacos://127.0.0.1:" +
NetUtils.getAvailablePort()).addParameter("group", "test-group3");
+ registryUrl = URL.valueOf("nacos://127.0.0.1:" +
NetUtils.getAvailablePort() + "?nacos.check=false").addParameter("group",
"test-group3");
}
@BeforeAll
diff --git
a/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/util/NacosNamingServiceUtilsTest.java
b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/util/NacosNamingServiceUtilsTest.java
index 701d97cffa..35c13d6a41 100644
---
a/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/util/NacosNamingServiceUtilsTest.java
+++
b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/util/NacosNamingServiceUtilsTest.java
@@ -16,19 +16,29 @@
*/
package org.apache.dubbo.registry.nacos.util;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.atomic.AtomicInteger;
+
import org.apache.dubbo.common.URL;
import org.apache.dubbo.metadata.report.MetadataReport;
import org.apache.dubbo.registry.client.ServiceInstance;
+import org.apache.dubbo.registry.nacos.MockNamingService;
import org.apache.dubbo.registry.nacos.NacosNamingServiceWrapper;
-
-import com.alibaba.nacos.api.naming.pojo.Instance;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
import org.mockito.Mockito;
-import java.util.HashMap;
-import java.util.Map;
+import com.alibaba.nacos.api.NacosFactory;
+import com.alibaba.nacos.api.exception.NacosException;
+import com.alibaba.nacos.api.naming.NamingService;
+import com.alibaba.nacos.api.naming.pojo.Instance;
+import static com.alibaba.nacos.client.constant.Constants.HealthCheck.DOWN;
+import static com.alibaba.nacos.client.constant.Constants.HealthCheck.UP;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
/**
@@ -67,8 +77,35 @@ class NacosNamingServiceUtilsTest {
@Test
void testCreateNamingService() {
- URL url = URL.valueOf("test://test:8080/test?backup=backup");
+ URL url =
URL.valueOf("test://test:8080/test?backup=backup&nacos.check=false");
NacosNamingServiceWrapper namingService =
NacosNamingServiceUtils.createNamingService(url);
Assertions.assertNotNull(namingService);
}
+
+
+ @Test
+ void testRetryCreate() throws NacosException {
+ try (MockedStatic<NacosFactory> nacosFactoryMockedStatic =
Mockito.mockStatic(NacosFactory.class)) {
+ AtomicInteger atomicInteger = new AtomicInteger(0);
+ NamingService mock = new MockNamingService() {
+ @Override
+ public String getServerStatus() {
+ return atomicInteger.incrementAndGet() > 10 ? UP : DOWN;
+ }
+ };
+ nacosFactoryMockedStatic.when(() ->
NacosFactory.createNamingService((Properties) any())).thenReturn(mock);
+
+
+ URL url = URL.valueOf("nacos://127.0.0.1:8848")
+ .addParameter("nacos.retry", 5)
+ .addParameter("nacos.retry-wait", 10);
+ Assertions.assertThrows(IllegalStateException.class, () ->
NacosNamingServiceUtils.createNamingService(url));
+
+ try {
+ NacosNamingServiceUtils.createNamingService(url);
+ } catch (Throwable t) {
+ Assertions.fail(t);
+ }
+ }
+ }
}