Skip to content

Commit 2133634

Browse files
authored
Add mapping retry (#11265)
1 parent 3d64f11 commit 2133634

File tree

4 files changed

+158
-34
lines changed

4 files changed

+158
-34
lines changed

dubbo-common/src/main/java/org/apache/dubbo/config/ApplicationConfig.java

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@
1616
*/
1717
package org.apache.dubbo.config;
1818

19+
import java.net.InetAddress;
20+
import java.net.UnknownHostException;
21+
import java.util.ArrayList;
22+
import java.util.HashMap;
23+
import java.util.List;
24+
import java.util.Map;
25+
import java.util.Set;
26+
1927
import org.apache.dubbo.common.compiler.support.AdaptiveCompiler;
2028
import org.apache.dubbo.common.infra.InfraAdapter;
2129
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
@@ -25,14 +33,6 @@
2533
import org.apache.dubbo.config.support.Parameter;
2634
import org.apache.dubbo.rpc.model.ApplicationModel;
2735

28-
import java.net.InetAddress;
29-
import java.net.UnknownHostException;
30-
import java.util.ArrayList;
31-
import java.util.HashMap;
32-
import java.util.List;
33-
import java.util.Map;
34-
import java.util.Set;
35-
3636
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
3737
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_PROTOCOL_KEY;
3838
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_VERSION_KEY;
@@ -198,6 +198,11 @@ public class ApplicationConfig extends AbstractConfig {
198198
*/
199199
private Integer metadataServicePort;
200200

201+
/**
202+
* The retry interval of service name mapping
203+
*/
204+
private Integer mappingRetryInterval;
205+
201206
/**
202207
* used to set extensions of probe in qos
203208
*/
@@ -564,6 +569,14 @@ public void setMetadataServicePort(Integer metadataServicePort) {
564569
this.metadataServicePort = metadataServicePort;
565570
}
566571

572+
public Integer getMappingRetryInterval() {
573+
return mappingRetryInterval;
574+
}
575+
576+
public void setMappingRetryInterval(Integer mappingRetryInterval) {
577+
this.mappingRetryInterval = mappingRetryInterval;
578+
}
579+
567580
@Parameter(key = METADATA_SERVICE_PROTOCOL_KEY)
568581
public String getMetadataServiceProtocol() {
569582
return metadataServiceProtocol;

dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,18 @@
1616
*/
1717
package org.apache.dubbo.config;
1818

19+
import java.lang.reflect.Method;
20+
import java.util.ArrayList;
21+
import java.util.Arrays;
22+
import java.util.Comparator;
23+
import java.util.HashMap;
24+
import java.util.List;
25+
import java.util.Map;
26+
import java.util.UUID;
27+
import java.util.concurrent.ScheduledExecutorService;
28+
import java.util.concurrent.TimeUnit;
29+
import java.util.concurrent.atomic.AtomicBoolean;
30+
1931
import org.apache.dubbo.common.URL;
2032
import org.apache.dubbo.common.URLBuilder;
2133
import org.apache.dubbo.common.Version;
@@ -24,6 +36,7 @@
2436
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
2537
import org.apache.dubbo.common.logger.LoggerFactory;
2638
import org.apache.dubbo.common.threadpool.manager.ExecutorRepository;
39+
import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository;
2740
import org.apache.dubbo.common.url.component.ServiceConfigURL;
2841
import org.apache.dubbo.common.utils.ClassUtils;
2942
import org.apache.dubbo.common.utils.CollectionUtils;
@@ -49,17 +62,6 @@
4962
import org.apache.dubbo.rpc.model.ServiceDescriptor;
5063
import org.apache.dubbo.rpc.service.GenericService;
5164

52-
import java.lang.reflect.Method;
53-
import java.util.ArrayList;
54-
import java.util.Arrays;
55-
import java.util.Comparator;
56-
import java.util.HashMap;
57-
import java.util.List;
58-
import java.util.Map;
59-
import java.util.UUID;
60-
import java.util.concurrent.TimeUnit;
61-
import java.util.concurrent.atomic.AtomicBoolean;
62-
6365
import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_KEY;
6466
import static org.apache.dubbo.common.constants.CommonConstants.ANY_VALUE;
6567
import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SEPARATOR;
@@ -261,21 +263,41 @@ protected void exported() {
261263
exportedURLs.forEach(url -> {
262264
if (url.getParameters().containsKey(SERVICE_NAME_MAPPING_KEY)) {
263265
ServiceNameMapping serviceNameMapping = ServiceNameMapping.getDefaultExtension(getScopeModel());
264-
try {
265-
boolean succeeded = serviceNameMapping.map(url);
266-
if (succeeded) {
267-
logger.info("Successfully registered interface application mapping for service " + url.getServiceKey());
268-
} else {
269-
logger.error(CONFIG_SERVER_DISCONNECTED, "configuration server disconnected", "", "Failed register interface application mapping for service " + url.getServiceKey());
270-
}
271-
} catch (Exception e) {
272-
logger.error(CONFIG_SERVER_DISCONNECTED, "configuration server disconnected", "", "Failed register interface application mapping for service " + url.getServiceKey(), e);
273-
}
266+
ScheduledExecutorService scheduledExecutor = getScopeModel().getBeanFactory()
267+
.getBean(FrameworkExecutorRepository.class).getSharedScheduledExecutor();
268+
mapServiceName(url, serviceNameMapping, scheduledExecutor);
274269
}
275270
});
276271
onExported();
277272
}
278273

274+
protected void mapServiceName(URL url, ServiceNameMapping serviceNameMapping, ScheduledExecutorService scheduledExecutor) {
275+
if (!exported) {
276+
return;
277+
}
278+
logger.info("Try to register interface application mapping for service " + url.getServiceKey());
279+
boolean succeeded = false;
280+
try {
281+
succeeded = serviceNameMapping.map(url);
282+
if (succeeded) {
283+
logger.info("Successfully registered interface application mapping for service " + url.getServiceKey());
284+
} else {
285+
logger.error(CONFIG_SERVER_DISCONNECTED, "configuration server disconnected", "", "Failed register interface application mapping for service " + url.getServiceKey());
286+
}
287+
} catch (Exception e) {
288+
logger.error(CONFIG_SERVER_DISCONNECTED, "configuration server disconnected", "", "Failed register interface application mapping for service " + url.getServiceKey(), e);
289+
}
290+
if (!succeeded) {
291+
scheduleToMapping(scheduledExecutor, serviceNameMapping, url);
292+
}
293+
}
294+
295+
private void scheduleToMapping(ScheduledExecutorService scheduledExecutor, ServiceNameMapping serviceNameMapping, URL url) {
296+
Integer mappingRetryInterval = getApplication().getMappingRetryInterval();
297+
scheduledExecutor.schedule(() -> mapServiceName(url, serviceNameMapping, scheduledExecutor),
298+
mappingRetryInterval == null ? 5000 : mappingRetryInterval, TimeUnit.MILLISECONDS);
299+
}
300+
279301
private void checkAndUpdateSubConfigs() {
280302

281303
// Use default configs defined explicitly with global scope

dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ServiceConfigTest.java

Lines changed: 89 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@
1717

1818
package org.apache.dubbo.config;
1919

20+
import java.util.Collections;
21+
import java.util.Map;
22+
import java.util.Set;
23+
import java.util.concurrent.CountDownLatch;
24+
import java.util.concurrent.Executors;
25+
import java.util.concurrent.ScheduledExecutorService;
26+
import java.util.concurrent.atomic.AtomicInteger;
27+
2028
import org.apache.dubbo.common.URL;
2129
import org.apache.dubbo.common.extension.ExtensionLoader;
2230
import org.apache.dubbo.config.api.DemoService;
@@ -27,22 +35,22 @@
2735
import org.apache.dubbo.config.mock.MockServiceListener;
2836
import org.apache.dubbo.config.mock.TestProxyFactory;
2937
import org.apache.dubbo.config.provider.impl.DemoServiceImpl;
38+
import org.apache.dubbo.metadata.MappingListener;
39+
import org.apache.dubbo.metadata.ServiceNameMapping;
3040
import org.apache.dubbo.registry.Registry;
3141
import org.apache.dubbo.rpc.Exporter;
3242
import org.apache.dubbo.rpc.Invoker;
3343
import org.apache.dubbo.rpc.Protocol;
44+
import org.apache.dubbo.rpc.model.ApplicationModel;
45+
import org.apache.dubbo.rpc.model.FrameworkModel;
3446
import org.apache.dubbo.rpc.service.GenericService;
35-
36-
import com.google.common.collect.Lists;
3747
import org.junit.jupiter.api.AfterEach;
3848
import org.junit.jupiter.api.Assertions;
3949
import org.junit.jupiter.api.BeforeEach;
4050
import org.junit.jupiter.api.Test;
4151
import org.mockito.Mockito;
4252

43-
import java.util.Collections;
44-
import java.util.Map;
45-
import java.util.concurrent.CountDownLatch;
53+
import com.google.common.collect.Lists;
4654

4755
import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_KEY;
4856
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
@@ -59,6 +67,7 @@
5967
import static org.apache.dubbo.remoting.Constants.BIND_PORT_KEY;
6068
import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
6169
import static org.apache.dubbo.rpc.cluster.Constants.EXPORT_KEY;
70+
import static org.awaitility.Awaitility.await;
6271
import static org.hamcrest.CoreMatchers.containsString;
6372
import static org.hamcrest.CoreMatchers.equalTo;
6473
import static org.hamcrest.CoreMatchers.is;
@@ -529,4 +538,79 @@ void testMethodConfigWithInvalidArgumentIndex() {
529538
service.export();
530539
});
531540
}
541+
542+
@Test
543+
void testMappingRetry() {
544+
FrameworkModel frameworkModel = new FrameworkModel();
545+
ApplicationModel applicationModel = frameworkModel.newApplication();
546+
ServiceConfig<DemoService> serviceConfig = new ServiceConfig<>(applicationModel.newModule());
547+
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
548+
AtomicInteger count = new AtomicInteger(0);
549+
ServiceNameMapping serviceNameMapping = new ServiceNameMapping() {
550+
@Override
551+
public boolean map(URL url) {
552+
if (count.incrementAndGet() < 5) {
553+
throw new RuntimeException();
554+
}
555+
return count.get() > 10;
556+
}
557+
558+
@Override
559+
public void initInterfaceAppMapping(URL subscribedURL) {
560+
561+
}
562+
563+
@Override
564+
public Set<String> getAndListen(URL registryURL, URL subscribedURL, MappingListener listener) {
565+
return null;
566+
}
567+
568+
@Override
569+
public MappingListener stopListen(URL subscribeURL, MappingListener listener) {
570+
return null;
571+
}
572+
573+
@Override
574+
public void putCachedMapping(String serviceKey, Set<String> apps) {
575+
576+
}
577+
578+
@Override
579+
public Set<String> getCachedMapping(String mappingKey) {
580+
return null;
581+
}
582+
583+
@Override
584+
public Set<String> getCachedMapping(URL consumerURL) {
585+
return null;
586+
}
587+
588+
@Override
589+
public Set<String> getRemoteMapping(URL consumerURL) {
590+
return null;
591+
}
592+
593+
@Override
594+
public Map<String, Set<String>> getCachedMapping() {
595+
return null;
596+
}
597+
598+
@Override
599+
public Set<String> removeCachedMapping(String serviceKey) {
600+
return null;
601+
}
602+
603+
@Override
604+
public void $destroy() {
605+
606+
}
607+
};
608+
ApplicationConfig applicationConfig = new ApplicationConfig("app");
609+
applicationConfig.setMappingRetryInterval(10);
610+
serviceConfig.setApplication(applicationConfig);
611+
serviceConfig.mapServiceName(URL.valueOf(""), serviceNameMapping, scheduledExecutorService);
612+
613+
await().until(() -> count.get() > 10);
614+
scheduledExecutorService.shutdown();
615+
}
532616
}

dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,11 @@
456456
<xsd:documentation><![CDATA[ The preferred protocol to use, set protocol name. ]]></xsd:documentation>
457457
</xsd:annotation>
458458
</xsd:attribute>
459+
<xsd:attribute name="mapping-retry-interval" type="xsd:integer">
460+
<xsd:annotation>
461+
<xsd:documentation><![CDATA[ The retry interval of service name mapping. ]]></xsd:documentation>
462+
</xsd:annotation>
463+
</xsd:attribute>
459464
</xsd:complexType>
460465

461466
<xsd:complexType name="moduleType">

0 commit comments

Comments
 (0)