Fix nacos create client retry conflicts
This commit is contained in:
parent
b38e23b5ce
commit
c519eb47a3
|
|
@ -16,7 +16,15 @@
|
|||
*/
|
||||
package org.apache.dubbo.registry.nacos;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
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;
|
||||
|
|
@ -27,18 +35,13 @@ import com.alibaba.nacos.api.PropertyKeyConst;
|
|||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.api.naming.NamingService;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import static com.alibaba.nacos.api.PropertyKeyConst.NAMING_LOAD_CACHE_AT_START;
|
||||
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 com.alibaba.nacos.client.naming.utils.UtilAndComs.NACOS_NAMING_LOG_NAME;
|
||||
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;
|
||||
|
|
@ -52,8 +55,17 @@ public class NacosConnectionManager {
|
|||
|
||||
private final List<NamingService> namingServiceList = new LinkedList<>();
|
||||
|
||||
public NacosConnectionManager(URL connectionURL) {
|
||||
private final int retryTimes;
|
||||
|
||||
private final int sleepMsBetweenRetries;
|
||||
|
||||
private final boolean check;
|
||||
|
||||
public NacosConnectionManager(URL connectionURL, boolean check, int retryTimes, int sleepMsBetweenRetries) {
|
||||
this.connectionURL = connectionURL;
|
||||
this.check = check;
|
||||
this.retryTimes = retryTimes;
|
||||
this.sleepMsBetweenRetries = sleepMsBetweenRetries;
|
||||
// create default one
|
||||
this.namingServiceList.add(createNamingService());
|
||||
}
|
||||
|
|
@ -64,6 +76,9 @@ public class NacosConnectionManager {
|
|||
@Deprecated
|
||||
protected NacosConnectionManager(NamingService namingService) {
|
||||
this.connectionURL = null;
|
||||
this.retryTimes = 0;
|
||||
this.sleepMsBetweenRetries = 0;
|
||||
this.check = false;
|
||||
// create default one
|
||||
this.namingServiceList.add(namingService);
|
||||
}
|
||||
|
|
@ -103,15 +118,37 @@ public class NacosConnectionManager {
|
|||
*/
|
||||
protected NamingService createNamingService() {
|
||||
Properties nacosProperties = buildNacosProperties(this.connectionURL);
|
||||
NamingService namingService;
|
||||
NamingService namingService = null;
|
||||
try {
|
||||
namingService = NacosFactory.createNamingService(nacosProperties);
|
||||
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) {
|
||||
if (logger.isErrorEnabled()) {
|
||||
logger.error(REGISTRY_NACOS_EXCEPTION, "", "", e.getErrMsg(), e);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
logger.error(INTERNAL_INTERRUPTED, "", "", "Interrupted when creating nacos naming service client.", e);
|
||||
Thread.currentThread().interrupt();
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
|
||||
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 namingService;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -416,7 +416,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);
|
||||
|
|
@ -450,7 +450,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);
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ public class NacosNamingServiceUtils {
|
|||
|
||||
private static final String NACOS_RETRY_WAIT_KEY = "nacos.retry-wait";
|
||||
|
||||
private static final String NACOS_CHECK_KEY = "nacos.check";
|
||||
|
||||
private NacosNamingServiceUtils() {
|
||||
throw new IllegalStateException("NacosNamingServiceUtils should not be instantiated");
|
||||
}
|
||||
|
|
@ -108,8 +110,10 @@ public class NacosNamingServiceUtils {
|
|||
* @since 2.7.5
|
||||
*/
|
||||
public static NacosNamingServiceWrapper createNamingService(URL connectionURL) {
|
||||
int retryTimes = connectionURL.getParameter(NACOS_RETRY_KEY, 10);
|
||||
int sleepMsBetweenRetries = connectionURL.getParameter(NACOS_RETRY_WAIT_KEY, 10);
|
||||
return new NacosNamingServiceWrapper(new NacosConnectionManager(connectionURL), retryTimes, sleepMsBetweenRetries);
|
||||
boolean check = connectionURL.getParameter(NACOS_CHECK_KEY, true);
|
||||
int retryTimes = connectionURL.getPositiveParameter(NACOS_RETRY_KEY, 10);
|
||||
int sleepMsBetweenRetries = connectionURL.getPositiveParameter(NACOS_RETRY_WAIT_KEY, 10);
|
||||
NacosConnectionManager nacosConnectionManager = new NacosConnectionManager(connectionURL, check, retryTimes, sleepMsBetweenRetries);
|
||||
return new NacosNamingServiceWrapper(nacosConnectionManager, retryTimes, sleepMsBetweenRetries);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,17 +16,26 @@
|
|||
*/
|
||||
package org.apache.dubbo.registry.nacos;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
|
||||
import com.alibaba.nacos.api.naming.NamingService;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
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.exception.NacosException;
|
||||
import com.alibaba.nacos.api.naming.NamingService;
|
||||
|
||||
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;
|
||||
|
||||
public class NacosConnectionsManagerTest {
|
||||
@Test
|
||||
|
|
@ -41,7 +50,7 @@ public class NacosConnectionsManagerTest {
|
|||
@Test
|
||||
public void testCreate() {
|
||||
List<NamingService> namingServiceList = new ArrayList<>();
|
||||
NacosConnectionManager nacosConnectionManager = new NacosConnectionManager(URL.valueOf("")) {
|
||||
NacosConnectionManager nacosConnectionManager = new NacosConnectionManager(URL.valueOf(""), false, 0, 0) {
|
||||
@Override
|
||||
protected NamingService createNamingService() {
|
||||
NamingService namingService = Mockito.mock(NamingService.class);
|
||||
|
|
@ -81,4 +90,47 @@ public class NacosConnectionsManagerTest {
|
|||
copy = new LinkedList<>(namingServiceList);
|
||||
Assertions.assertFalse(copy.contains(nacosConnectionManager.getNamingService()));
|
||||
}
|
||||
|
||||
@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");
|
||||
Assertions.assertThrows(IllegalStateException.class, () -> new NacosConnectionManager(url, true, 5, 10));
|
||||
|
||||
try {
|
||||
new NacosConnectionManager(url, true, 5, 10);
|
||||
} catch (Throwable t) {
|
||||
Assertions.fail(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
@Test
|
||||
void testNoCheck() throws NacosException {
|
||||
try (MockedStatic<NacosFactory> nacosFactoryMockedStatic = Mockito.mockStatic(NacosFactory.class)) {
|
||||
NamingService mock = new MockNamingService() {
|
||||
@Override
|
||||
public String getServerStatus() {
|
||||
return DOWN;
|
||||
}
|
||||
};
|
||||
nacosFactoryMockedStatic.when(() -> NacosFactory.createNamingService((Properties) any())).thenReturn(mock);
|
||||
|
||||
URL url = URL.valueOf("nacos://127.0.0.1:8848");
|
||||
|
||||
try {
|
||||
new NacosConnectionManager(url, false, 5, 10);
|
||||
} catch (Throwable t) {
|
||||
Assertions.fail(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ class NacosNamingServiceWrapperTest {
|
|||
@Test
|
||||
void testRegisterNacos2_0_x() throws NacosException {
|
||||
List<NamingService> namingServiceList = new LinkedList<>();
|
||||
NacosConnectionManager nacosConnectionManager = new NacosConnectionManager(URL.valueOf("")) {
|
||||
NacosConnectionManager nacosConnectionManager = new NacosConnectionManager(URL.valueOf(""), false, 0, 0) {
|
||||
@Override
|
||||
protected NamingService createNamingService() {
|
||||
NamingService namingService = Mockito.mock(NamingService.class);
|
||||
|
|
@ -140,7 +140,7 @@ class NacosNamingServiceWrapperTest {
|
|||
@Test
|
||||
void testRegisterNacos2_1_xClient2_0_xServer() throws NacosException {
|
||||
List<NamingService> namingServiceList = new LinkedList<>();
|
||||
NacosConnectionManager nacosConnectionManager = new NacosConnectionManager(URL.valueOf("")) {
|
||||
NacosConnectionManager nacosConnectionManager = new NacosConnectionManager(URL.valueOf(""), false, 0, 0) {
|
||||
@Override
|
||||
protected NamingService createNamingService() {
|
||||
NamingService namingService = Mockito.mock(NamingService.class);
|
||||
|
|
@ -204,7 +204,7 @@ class NacosNamingServiceWrapperTest {
|
|||
@Test
|
||||
void testRegisterNacos2_1_xClient2_1_xServer() throws NacosException {
|
||||
List<NamingService> namingServiceList = new LinkedList<>();
|
||||
NacosConnectionManager nacosConnectionManager = new NacosConnectionManager(URL.valueOf("")) {
|
||||
NacosConnectionManager nacosConnectionManager = new NacosConnectionManager(URL.valueOf(""), false, 0, 0) {
|
||||
@Override
|
||||
protected NamingService createNamingService() {
|
||||
NamingService namingService = Mockito.mock(NamingService.class);
|
||||
|
|
@ -307,7 +307,7 @@ class NacosNamingServiceWrapperTest {
|
|||
@Test
|
||||
void testUnregister() throws NacosException {
|
||||
List<NamingService> namingServiceList = new LinkedList<>();
|
||||
NacosConnectionManager nacosConnectionManager = new NacosConnectionManager(URL.valueOf("")) {
|
||||
NacosConnectionManager nacosConnectionManager = new NacosConnectionManager(URL.valueOf(""), false, 0, 0) {
|
||||
@Override
|
||||
protected NamingService createNamingService() {
|
||||
NamingService namingService = Mockito.mock(NamingService.class);
|
||||
|
|
|
|||
Loading…
Reference in New Issue