Add nacos create client retry (#11304)
This commit is contained in:
parent
f9b27eddef
commit
673375b9bf
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue