This is an automated email from the ASF dual-hosted git repository. mercyblitz pushed a commit to branch cloud-native in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/cloud-native by this push: new 79e69ad [Refactor] Dubbo cloud native (#4953) 79e69ad is described below commit 79e69ad35a1e05882ce18de69a434732b2469535 Author: Mercy Ma <mercybl...@gmail.com> AuthorDate: Tue Aug 27 17:56:42 2019 +0800 [Refactor] Dubbo cloud native (#4953) * Polish apache/dubbo#4542 : [Enhancement] Adapt the Java standard Event/Listener mechanism * Polish apache/dubbo#4541 : [Feature] Add local File System DynamicConfigurationFactory‘s extension * Polish apache#4541 : Bugfix * Polish apache/dubbo#4541 : Optimization * Polish apache/dubbo#4541 : Add the compatibility for PollingWatchService on the some platforms * Polish apache/dubbo#4541 : Add delay publish without ThreadPoolExecutor * Polish apache/dubbo#4541 : Refactor the extension name * Polish apache/dubbo#4541 : Add remove ops * Polish apache/dubbo#4541 : Add testable constructor * Polish apache/dubbo#4541 : Add getConfigGroups method * Polish apache/dubbo#4610 : [Refactor] Refactor the bootstrap module * Polish apache/dubbo#4541 : Fix the nulling URL issue * Polish apache/dubbo#4622 : [Refactor] Refactor ConfigManager * Polish apache/dubbo#4622 : [Refactor] Refactor ConfigManager * Polish apache/dubbo#4622 : Support multiple configcenters * Polish apache/dubbo#4671 : ServiceNameMapping will not map the group, version and protocol * update referenceCount log (#4683) Add comments to support multiple shared connections * Polish /apache/dubbo#4687 : Remove the duplicated test code in dubbo-config-spring (#4688) * #4685 修改代码if判断false问题 if (hasException == false)修改成if (!hasException) (#4695) * Fixed Service annotation method parameters are not in effect (#4598) * keep demo simple, and switch to use zookeeper as registry center (#4705) * keep demo simple, and switch to use zookeeper as registry center * remove comment * @Reference auto-wires the instance of generic interface #4594 (#4677) * try to shorten maven output to make travis build pass (#4710) * use CountDownLatch to check zk registry if establish connection (#4589) * Minor change * Rename the extension name of WritableMetadataService * Polish apache/dubbo#4759 : [Refactor] Change the signature of methods of MetadataService #4759 * Merge remote-tracking branch 'upstream/master' into dubbo-cloud-native # Conflicts: # dubbo-all/pom.xml # dubbo-bom/pom.xml # dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java # dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ApplicationConfig.java # dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ConfigCenterConfig.java # dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java # dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/RegistryConfig.java # dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java # dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java # dubbo-configcenter/dubbo-configcenter-api/src/main/java/org/apache/dubbo/configcenter/DynamicConfiguration.java # dubbo-configcenter/dubbo-configcenter-api/src/test/java/org/apache/dubbo/configcenter/mock/MockDynamicConfiguration.java # dubbo-configcenter/dubbo-configcenter-consul/src/main/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfiguration.java # dubbo-configcenter/dubbo-configcenter-etcd/src/test/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfigurationTest.java # dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java # dubbo-configcenter/dubbo-configcenter-nacos/src/test/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfigurationTest.java # dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfiguration.java # dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/MethodDefinition.java # dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/identifier/MetadataIdentifier.java # dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReport.java # dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/identifier/MetadataIdentifierTest.java # dubbo-metadata/dubbo-metadata-definition-protobuf/src/main/java/org/apache/dubbo/metadata/definition/protobuf/ProtobufTypeBuilder.java # dubbo-metadata/dubbo-metadata-definition-protobuf/src/test/java/org/apache/dubbo/metadata/definition/protobuf/ProtobufTypeBuilderTest.java # dubbo-metadata/pom.xml # dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/AbstractConfiguratorListener.java # dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosRegistry.java # dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosRegistryFactory.java # dubbo-rpc/dubbo-rpc-xml/src/main/java/org/apache/dubbo/xml/rpc/protocol/xmlrpc/XmlRpcProtocol.java * Polish apache/dubbo#3984 : Add the implementation of Page<ServiceInstance> getInstances(String serviceName, int offset, int pageSize, boolean healthyOnly) * Code merge * Fix the cases * Merge remote-tracking branch 'upstream/cloud-native' into dubbo-cloud-native # Conflicts: # dubbo-bootstrap/src/test/java/org/apache/dubbo/bootstrap/DubboServiceProviderBootstrap.java # dubbo-metadata/dubbo-metadata-definition-protobuf/pom.xml # dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/support/ServiceOrientedRegistryTest.java # dubbo-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/ConsulServiceDiscoveryFactory.java # dubbo-registry/dubbo-registry-etcd3/src/main/java/org/apache/dubbo/registry/etcd/EtcdServiceDiscovery.java * Refactor ConfigManager * Refactor ConfigManager * Resolve the issues on ConfigManager * Refactor and add test-cases for ConfigManager * Polish apache/dubbo#4774 : [Feature] Dubbo Cloud Native - To Support in Spring * Polish apache/dubbo#4808 : [Feature] Add the registered/unregistered event mechanism ShutdownHook * Polish apache/dubbo#4807 : [Feature] Add the callback mechanism ShutdownHook #4807 * Polish apache/dubbo#4813 : [Feature] add Prioritized implementation for ServiceInstanceCustomizer * Polish apache/dubbo#4815 : [Feature] Add the ServiceLoader for Dubbo's services or components * Polish apache/dubbo#4815 : [Feature] Add the ServiceLoader for Dubbo's services or components * Polish apache/dubbo#4813 : [Feature] add Prioritized implementation for ServiceInstanceCustomizer * Polish apache/dubbo#4807 : Add sort implementation * Refactor * Refactor * Polish apache/dubbo#4845 : [Feature] Enhance the Event-Publishing feature to original ServiceDiscovery * Merge remote-tracking branch 'upstream/cloud-native' into dubbo-cloud-native # Conflicts: # dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/DefaultServiceDiscoveryFactory.java # dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java * Merge remote-tracking branch 'upstream/cloud-native' into dubbo-cloud-native # Conflicts: # dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/DefaultServiceDiscoveryFactory.java # dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java * Polish apache/dubbo#4854 : [Feature] MetadataService supports the Dubbo protocol under auto-increased port * Polish apache/dubbo#4857 : [Enhancement] Sync the Metadata storage type into ApplicationConfig * Polish apache/dubbo#4868 : [Enhancement] Refactor ConfigChangeEvent * Polish apache/dubbo#4868 : [Enhancement] Refactor ConfigChangeEvent * Polish apache/dubbo#4873 : [Feature] Add a conditional EventListener into Event Module * Polish apache/dubbo#4875 : [Feature] Refactor ServiceInstancesChangedListener * Remove the cycle dependencies * Remove the cycle dependencies * Polish apache/dubbo#4903 : [Feature] Set source into the BeanDefinition of Dubbo Config * Polish apache/dubbo#4902 : [Feature] Dubbo Cloud Native to Spring XML scenario * Polish apache/dubbo#4713 : Initial the new module and dependencies * Polish apache/dubbo#4690 : AnnotatedBeanDefinitionRegistryUtils#registerBeans can't remove the duplicated bean definitions * Polish apache/dubbo#4690 : AnnotatedBeanDefinitionRegistryUtils#registerBeans can't remove the duplicated bean definitions * Polish apache/dubbo#4690 : AnnotatedBeanDefinitionRegistryUtils#registerBeans can't remove the duplicated bean definitions * Polish apache/dubbo#4910 : [Feature] To suppoort DubboLifecycleComponentApplicationListener in Spring XML scenario * Polish apache/dubbo#4713 : Add Service discovery implementation for Eureka #4713 * Polish apache/dubbo#4713 : Add Service registration and discovery implementation for Eureka * Polish apache/dubbo#4713 : Add Service registration and discovery implementation for Eureka * Polish apache/dubbo#4920 : [Refactor] Extract the common implementation for URLs' revision * Refactor * Polish apache/dubbo#4925 : ServiceDiscovery limits only one ServiceInstancesChangedListener each service * Polish apache/dubbo#4925 : ServiceDiscovery limits only one ServiceInstancesChangedListener each service * Remove useless classes * Bugfix & Refactor ServiceDiscoveryRegistry * Polish apache/dubbo#4937 : The calculation of Revision should add the parameters of URL * Polish apache/dubbo#4940 : NacosDynamicConfiguration supports getConfigKeys method * Polish apache/dubbo#4942 : Dubbo Cloud Native supports multiple protcols * Polish apache/dubbo#4944 : [Feature] Simplify The metadata of URL for MetadataService * Polish apache/dubbo#4947 : [Feature] Dubbo Cloud-Native supports the REST call to Non-Dubbo * Merge remote-tracking branch 'upstream/cloud-native' into dubbo-cloud-native # Conflicts: # dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java * Refactor --- .../org/apache/dubbo/bootstrap/DubboBootstrap.java | 8 +- .../dubbo/common/constants/CommonConstants.java | 4 +- .../org/apache/dubbo/config/ReferenceConfig.java | 4 +- .../org/apache/dubbo/config/ServiceConfig.java | 4 +- .../dubbo/metadata/WritableMetadataService.java | 4 +- ...g.apache.dubbo.metadata.WritableMetadataService | 4 +- .../store/RemoteWritableMeatadataServiceTest.java | 6 +- .../registry/client/ServiceDiscoveryRegistry.java | 350 ++++++++++++--------- .../metadata/ServiceInstanceMetadataUtils.java | 6 +- .../proxy/RemoteMetadataServiceProxyFactory.java | 4 - .../registry/eureka/EurekaServiceDiscovery.java | 4 +- 11 files changed, 232 insertions(+), 166 deletions(-) diff --git a/dubbo-bootstrap/src/main/java/org/apache/dubbo/bootstrap/DubboBootstrap.java b/dubbo-bootstrap/src/main/java/org/apache/dubbo/bootstrap/DubboBootstrap.java index 03df012..900ab1b 100644 --- a/dubbo-bootstrap/src/main/java/org/apache/dubbo/bootstrap/DubboBootstrap.java +++ b/dubbo-bootstrap/src/main/java/org/apache/dubbo/bootstrap/DubboBootstrap.java @@ -83,8 +83,8 @@ import static java.util.Collections.sort; import static java.util.concurrent.Executors.newSingleThreadExecutor; import static org.apache.dubbo.common.config.ConfigurationUtils.parseProperties; import static org.apache.dubbo.common.config.configcenter.DynamicConfiguration.getDynamicConfiguration; -import static org.apache.dubbo.common.constants.CommonConstants.METADATA_DEFAULT; -import static org.apache.dubbo.common.constants.CommonConstants.METADATA_REMOTE; +import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE; +import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_METADATA_STORAGE_TYPE; import static org.apache.dubbo.common.function.ThrowableAction.execute; import static org.apache.dubbo.common.utils.StringUtils.isNotEmpty; import static org.apache.dubbo.config.context.ConfigManager.getInstance; @@ -175,7 +175,7 @@ public class DubboBootstrap extends GenericEventListener implements Lifecycle { private String getMetadataType() { String type = configManager.getApplicationOrElseThrow().getMetadataType(); if (StringUtils.isEmpty(type)) { - type = METADATA_DEFAULT; + type = DEFAULT_METADATA_STORAGE_TYPE; } return type; } @@ -489,7 +489,7 @@ public class DubboBootstrap extends GenericEventListener implements Lifecycle { // FIXME, multiple metadata config support. Collection<MetadataReportConfig> metadataReportConfigs = configManager.getMetadataConfigs(); if (CollectionUtils.isEmpty(metadataReportConfigs)) { - if (METADATA_REMOTE.equals(metadataType)) { + if (REMOTE_METADATA_STORAGE_TYPE.equals(metadataType)) { throw new IllegalStateException("No MetadataConfig found, you must specify the remote Metadata Center address when 'metadata=remote' is enabled."); } return; diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java index 9481d5d..1d5b934 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java @@ -167,9 +167,9 @@ public interface CommonConstants { String METADATA_KEY = "metadata"; - String METADATA_DEFAULT = "local"; + String DEFAULT_METADATA_STORAGE_TYPE = "default"; - String METADATA_REMOTE = "remote"; + String REMOTE_METADATA_STORAGE_TYPE = "remote"; /** * package version in the manifest diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java index 90423c1..fe0c23a 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java @@ -64,10 +64,10 @@ import static org.apache.dubbo.common.constants.CommonConstants.ANY_VALUE; import static org.apache.dubbo.common.constants.CommonConstants.CLUSTER_KEY; import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SEPARATOR; import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE; +import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE; import static org.apache.dubbo.common.constants.CommonConstants.DUBBO; import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY; import static org.apache.dubbo.common.constants.CommonConstants.LOCALHOST_VALUE; -import static org.apache.dubbo.common.constants.CommonConstants.METADATA_DEFAULT; import static org.apache.dubbo.common.constants.CommonConstants.METADATA_KEY; import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY; import static org.apache.dubbo.common.constants.CommonConstants.MONITOR_KEY; @@ -444,7 +444,7 @@ public class ReferenceConfig<T> extends AbstractReferenceConfig { * ServiceData Store */ String metadata = map.get(METADATA_KEY); - WritableMetadataService metadataService = WritableMetadataService.getExtension(metadata == null ? METADATA_DEFAULT : metadata); + WritableMetadataService metadataService = WritableMetadataService.getExtension(metadata == null ? DEFAULT_METADATA_STORAGE_TYPE : metadata); if (metadataService != null) { URL consumerURL = new URL(CONSUMER_PROTOCOL, map.remove(REGISTER_IP_KEY), 0, map.get(INTERFACE_KEY), map); metadataService.publishServiceDefinition(consumerURL); diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java index d941fa8..f0ebe06 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java @@ -67,10 +67,10 @@ import java.util.concurrent.TimeUnit; import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_KEY; import static org.apache.dubbo.common.constants.CommonConstants.ANY_VALUE; import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN; +import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE; import static org.apache.dubbo.common.constants.CommonConstants.DUBBO; import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_IP_TO_BIND; import static org.apache.dubbo.common.constants.CommonConstants.LOCALHOST_VALUE; -import static org.apache.dubbo.common.constants.CommonConstants.METADATA_DEFAULT; import static org.apache.dubbo.common.constants.CommonConstants.METADATA_KEY; import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY; import static org.apache.dubbo.common.constants.CommonConstants.MONITOR_KEY; @@ -633,7 +633,7 @@ public class ServiceConfig<T> extends AbstractServiceConfig { * @since 2.7.0 * ServiceData Store */ - WritableMetadataService metadataService = WritableMetadataService.getExtension(url.getParameter(METADATA_KEY, METADATA_DEFAULT)); + WritableMetadataService metadataService = WritableMetadataService.getExtension(url.getParameter(METADATA_KEY, DEFAULT_METADATA_STORAGE_TYPE)); if (metadataService != null) { metadataService.publishServiceDefinition(url); } diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/WritableMetadataService.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/WritableMetadataService.java index 7cfa45c..744277b 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/WritableMetadataService.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/WritableMetadataService.java @@ -22,7 +22,7 @@ import org.apache.dubbo.common.extension.SPI; import org.apache.dubbo.metadata.store.InMemoryWritableMetadataService; import org.apache.dubbo.rpc.model.ApplicationModel; -import static org.apache.dubbo.common.constants.CommonConstants.METADATA_DEFAULT; +import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE; import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader; /** @@ -31,7 +31,7 @@ import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoad * * @since 2.7.4 */ -@SPI(METADATA_DEFAULT) +@SPI(DEFAULT_METADATA_STORAGE_TYPE) public interface WritableMetadataService extends MetadataService { /** * Gets the current Dubbo Service name diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.WritableMetadataService b/dubbo-metadata/dubbo-metadata-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.WritableMetadataService index 1e85044..0a456a3 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.WritableMetadataService +++ b/dubbo-metadata/dubbo-metadata-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.WritableMetadataService @@ -1,2 +1,2 @@ -local=org.apache.dubbo.metadata.store.InMemoryWritableMetadataService -remote=org.apache.dubbo.metadata.store.RemoteWritableMetadataServiceDelegate +default=org.apache.dubbo.metadata.store.InMemoryWritableMetadataService +remote=org.apache.dubbo.metadata.store.RemoteWritableMetadataServiceDelegate \ No newline at end of file diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/store/RemoteWritableMeatadataServiceTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/store/RemoteWritableMeatadataServiceTest.java index fe2b4f6..07fb26d 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/store/RemoteWritableMeatadataServiceTest.java +++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/store/RemoteWritableMeatadataServiceTest.java @@ -30,7 +30,7 @@ import org.junit.jupiter.api.Test; import java.util.Map; -import static org.apache.dubbo.common.constants.CommonConstants.METADATA_REMOTE; +import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_METADATA_STORAGE_TYPE; /** * 2018/9/14 @@ -41,14 +41,14 @@ public class RemoteWritableMeatadataServiceTest { @BeforeEach public void before() { - metadataReportService1 = (RemoteWritableMetadataService) WritableMetadataService.getExtension(METADATA_REMOTE); + metadataReportService1 = (RemoteWritableMetadataService) WritableMetadataService.getExtension(REMOTE_METADATA_STORAGE_TYPE); MetadataReportInstance.init(url); } @Test public void testInstance() { - RemoteWritableMetadataService metadataReportService2 = (RemoteWritableMetadataService) WritableMetadataService.getExtension(METADATA_REMOTE); + RemoteWritableMetadataService metadataReportService2 = (RemoteWritableMetadataService) WritableMetadataService.getExtension(REMOTE_METADATA_STORAGE_TYPE); Assertions.assertSame(metadataReportService1, metadataReportService2); } diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java index 581e388..44da3dc 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java @@ -39,7 +39,6 @@ import org.apache.dubbo.registry.support.FailbackRegistry; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedHashSet; @@ -49,6 +48,10 @@ import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.SortedSet; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.function.Supplier; import java.util.stream.Collectors; import static java.lang.String.format; @@ -76,7 +79,7 @@ import static org.apache.dubbo.common.utils.CollectionUtils.isEmpty; import static org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty; import static org.apache.dubbo.common.utils.DubboServiceLoader.loadServices; import static org.apache.dubbo.common.utils.StringUtils.isBlank; -import static org.apache.dubbo.metadata.WritableMetadataService.DEFAULT_EXTENSION; +import static org.apache.dubbo.metadata.MetadataService.toURLs; import static org.apache.dubbo.registry.client.ServiceDiscoveryFactory.getExtension; import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.getExportedServicesRevision; import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.getMetadataStorageType; @@ -115,12 +118,14 @@ public class ServiceDiscoveryRegistry extends FailbackRegistry { private final List<SubscribedURLsSynthesizer> subscribedURLsSynthesizers; + private final ReadWriteLock lock = new ReentrantReadWriteLock(); + /** * A cache for all URLs of services that the subscribed services exported * The key is the service name * The value is a nested {@link Map} whose key is the revision and value is all URLs of services */ - private final Map<String, Map<String, List<URL>>> serviceExportedURLsCache = new LinkedHashMap<>(); + private final Map<String, Map<String, List<URL>>> serviceRevisionExportedURLsCache = new LinkedHashMap<>(); public ServiceDiscoveryRegistry(URL registryURL) { super(registryURL); @@ -381,62 +386,100 @@ public class ServiceDiscoveryRegistry extends FailbackRegistry { return emptyList(); } - expungeStaleRevisionExportedURLs(serviceInstances); - - initTemplateURLs(subscribedURL, serviceInstances); + // Prepare revision exported URLs + prepareServiceRevisionExportedURLs(serviceInstances); // Clone the subscribed URLs from the template URLs List<URL> subscribedURLs = cloneExportedURLs(subscribedURL, serviceInstances); + // clear local service instances serviceInstances.clear(); + return subscribedURLs; } - private void initTemplateURLs(URL subscribedURL, List<ServiceInstance> serviceInstances) { - // Try to get the template URLs until success + /** + * Prepare the {@link #serviceRevisionExportedURLsCache} exclusively + * + * @param serviceInstances {@link ServiceInstance service instances} + * @see #expungeStaleRevisionExportedURLs(List) + * @see #initializeRevisionExportedURLs(List) + */ + private void prepareServiceRevisionExportedURLs(List<ServiceInstance> serviceInstances) { + executeExclusively(() -> { + // 1. expunge stale + expungeStaleRevisionExportedURLs(serviceInstances); + // 2. Initialize + initializeRevisionExportedURLs(serviceInstances); + }); + } + + /** + * Initialize the {@link URL URLs} that {@link ServiceInstance service instances} exported into + * {@link #serviceRevisionExportedURLsCache the cache}. + * <p> + * + * @param serviceInstances {@link ServiceInstance service instances} + */ + private void initializeRevisionExportedURLs(List<ServiceInstance> serviceInstances) { + // initialize the revision exported URLs that the selected service instance exported + initializeSelectedRevisionExportedURLs(serviceInstances); + // initialize the revision exported URLs that other service instances exported + serviceInstances.forEach(this::initializeRevisionExportedURLs); + } + + /** + * One {@link ServiceInstance} that will be selected in order to avoid hot spot + * + * @param serviceInstances {@link ServiceInstance service instances} + */ + private void initializeSelectedRevisionExportedURLs(List<ServiceInstance> serviceInstances) { + // Try to initialize revision exported URLs until success for (int i = 0; i < serviceInstances.size(); i++) { // select a instance of {@link ServiceInstance} ServiceInstance selectedInstance = selectServiceInstance(serviceInstances); - // try to get the template URLs - List<URL> templateURLs = getTemplateExportedURLs(subscribedURL, selectedInstance); - if (isNotEmpty(templateURLs)) { // If the result is valid - break; // break the loop - } else { - serviceInstances.remove(selectedInstance); // remove if the service instance is not available - // There may be one or more service instances from the "serviceInstances" + List<URL> revisionExportedURLs = initializeRevisionExportedURLs(selectedInstance); + if (isNotEmpty(revisionExportedURLs)) { // If the result is valid + break; } } } + /** + * Expunge the revision exported {@link URL URLs} in {@link #serviceRevisionExportedURLsCache the cache} if + * some revisions of {@link ServiceInstance service instance} had been out of date possibly + * + * @param serviceInstances {@link ServiceInstance service instances} + */ private void expungeStaleRevisionExportedURLs(List<ServiceInstance> serviceInstances) { - if (isEmpty(serviceInstances)) { // if empty, return immediately - return; - } - String serviceName = serviceInstances.get(0).getServiceName(); + // revisionExportedURLsMap is mutable + Map<String, List<URL>> revisionExportedURLsMap = getRevisionExportedURLsMap(serviceName); - synchronized (this) { - - // revisionExportedURLs is mutable - Map<String, List<URL>> revisionExportedURLs = serviceExportedURLsCache.computeIfAbsent(serviceName, s -> new HashMap<>()); - - if (revisionExportedURLs.isEmpty()) { // if empty, return immediately - return; - } - - Set<String> existedRevisions = revisionExportedURLs.keySet(); // read-only - Set<String> currentRevisions = serviceInstances.stream() - .map(ServiceInstanceMetadataUtils::getExportedServicesRevision) - .collect(Collectors.toSet()); - // staleRevisions = existedRevisions(copy) - currentRevisions - Set<String> staleRevisions = new HashSet<>(existedRevisions); - staleRevisions.removeAll(currentRevisions); - // remove exported URLs if staled - staleRevisions.forEach(revisionExportedURLs::remove); + if (revisionExportedURLsMap.isEmpty()) { // if empty, return immediately + return; } + + Set<String> existedRevisions = revisionExportedURLsMap.keySet(); // read-only + Set<String> currentRevisions = serviceInstances.stream() + .map(ServiceInstanceMetadataUtils::getExportedServicesRevision) + .collect(Collectors.toSet()); + // staleRevisions = existedRevisions(copy) - currentRevisions + Set<String> staleRevisions = new HashSet<>(existedRevisions); + staleRevisions.removeAll(currentRevisions); + // remove exported URLs if staled + staleRevisions.forEach(revisionExportedURLsMap::remove); } + /** + * Clone the exported URLs that are based on {@link #getTemplateExportedURLs(URL, ServiceInstance) the template URLs} + * from the some of {@link ServiceInstance service instances} with different revisions + * + * @param subscribedURL the subscribed {@link URL url} + * @param serviceInstances {@link ServiceInstance service instances} + * @return non-null + */ private List<URL> cloneExportedURLs(URL subscribedURL, Collection<ServiceInstance> serviceInstances) { if (isEmpty(serviceInstances)) { @@ -494,11 +537,11 @@ public class ServiceDiscoveryRegistry extends FailbackRegistry { * Get the template exported {@link URL urls} from the specified {@link ServiceInstance}. * <p> * First, put the revision {@link ServiceInstance service instance} - * associating {@link #getExportedURLs(URL, ServiceInstance) exported URLs} into cache. + * associating {@link #getExportedURLs(ServiceInstance) exported URLs} into cache. * <p> * And then compare a new {@link ServiceInstance service instances'} revision with cached one,If they are equal, * return the cached template {@link URL urls} immediately, or to get template {@link URL urls} that the provider - * {@link ServiceInstance instance} exported via executing {@link #getExportedURLs(URL, ServiceInstance)} + * {@link ServiceInstance instance} exported via executing {@link ##getExportedURLs(ServiceInstance) (ServiceInstance)} * method. * <p> * Eventually, the retrieving result will be cached and returned. @@ -519,31 +562,84 @@ public class ServiceDiscoveryRegistry extends FailbackRegistry { return filterSubscribedURLs(subscribedURL, exportedURLs); } - private List<URL> filterSubscribedURLs(URL subscribedURL, List<URL> exportedURLs) { - return exportedURLs.stream() - .filter(url -> isSameServiceInterface(subscribedURL, url)) - .filter(url -> isSameParameter(subscribedURL, url, VERSION_KEY)) - .filter(url -> isSameParameter(subscribedURL, url, GROUP_KEY)) - .filter(url -> isCompatibleProtocol(subscribedURL, url)) - .collect(Collectors.toList()); - } + /** + * Initialize the URLs that the specified {@link ServiceInstance service instance} exported + * + * @param providerServiceInstance the {@link ServiceInstance} exports the Dubbo Services + * @return the {@link URL URLs} that the {@link ServiceInstance} exported, it's calculated from + * The invocation to remote {@link MetadataService}, or get from {@link #serviceRevisionExportedURLsCache cache} if + * {@link ServiceInstanceMetadataUtils#getExportedServicesRevision(ServiceInstance) revision} is hit + */ + private List<URL> initializeRevisionExportedURLs(ServiceInstance providerServiceInstance) { - private boolean isSameServiceInterface(URL one, URL another) { - return Objects.equals(one.getServiceInterface(), another.getServiceInterface()); - } + if (providerServiceInstance == null) { + return emptyList(); + } - private boolean isSameParameter(URL one, URL another, String key) { - return Objects.equals(one.getParameter(key), another.getParameter(key)); - } + String serviceName = providerServiceInstance.getServiceName(); + // get the revision from the specified {@link ServiceInstance} + String revision = getExportedServicesRevision(providerServiceInstance); - private boolean isCompatibleProtocol(URL one, URL another) { - String protocol = one.getParameter(PROTOCOL_KEY); - return isCompatibleProtocol(protocol, another); + Map<String, List<URL>> revisionExportedURLsMap = getRevisionExportedURLsMap(serviceName); + + List<URL> revisionExportedURLs = revisionExportedURLsMap.get(revision); + + boolean firstGet = false; + + if (revisionExportedURLs == null) { // The hit is missing in cache + + if (!revisionExportedURLsMap.isEmpty()) { // The case is that current ServiceInstance with the different revision + if (logger.isWarnEnabled()) { + logger.warn(format("The ServiceInstance[id: %s, host : %s , port : %s] has different revision : %s" + + ", please make sure the service [name : %s] is changing or not.", + providerServiceInstance.getId(), + providerServiceInstance.getHost(), + providerServiceInstance.getPort(), + revision, + providerServiceInstance.getServiceName() + )); + } + } else { // Else, it's the first time to get the exported URLs + firstGet = true; + } + + revisionExportedURLs = getExportedURLs(providerServiceInstance); + + if (revisionExportedURLs != null) { // just allow the valid result into exportedURLsMap + + revisionExportedURLsMap.put(revision, revisionExportedURLs); + + if (logger.isDebugEnabled()) { + logger.debug(format("Get the exported URLs[size : %s, first : %s] from the target service " + + "instance [id: %s , service : %s , host : %s , port : %s , revision : %s]", + revisionExportedURLs.size(), firstGet, + providerServiceInstance.getId(), + providerServiceInstance.getServiceName(), + providerServiceInstance.getHost(), + providerServiceInstance.getPort(), + revision + )); + } + } + } else { // Else, The cache is hit + if (logger.isDebugEnabled()) { + logger.debug(format("Get the exported URLs[size : %s] from cache, the instance" + + "[id: %s , service : %s , host : %s , port : %s , revision : %s]", + revisionExportedURLs.size(), + providerServiceInstance.getId(), + providerServiceInstance.getServiceName(), + providerServiceInstance.getHost(), + providerServiceInstance.getPort(), + revision + )); + } + } + + return revisionExportedURLs; } - private boolean isCompatibleProtocol(String protocol, URL targetURL) { - return protocol == null || Objects.equals(protocol, targetURL.getParameter(PROTOCOL_KEY)) - || Objects.equals(protocol, targetURL.getProtocol()); + private Map<String, List<URL>> getRevisionExportedURLsMap(String serviceName) { + return serviceRevisionExportedURLsCache.computeIfAbsent(serviceName, s -> new LinkedHashMap()); } /** @@ -555,7 +651,7 @@ public class ServiceDiscoveryRegistry extends FailbackRegistry { * contract one by one, the "revision" that is the number is introduced to identify all Dubbo exported interfaces in * one {@link ServiceInstance service instance}. * - * @param providerServiceInstance the {@link ServiceInstance} provides the Dubbo Services + * @param providerServiceInstance the {@link ServiceInstance} exports the Dubbo Services * @return the same as {@link #getExportedURLs(ServiceInstance)} */ private List<URL> getRevisionExportedURLs(ServiceInstance providerServiceInstance) { @@ -568,62 +664,23 @@ public class ServiceDiscoveryRegistry extends FailbackRegistry { // get the revision from the specified {@link ServiceInstance} String revision = getExportedServicesRevision(providerServiceInstance); - List<URL> exportedURLs = null; - - synchronized (this) { // It's required to lock here because it may run in the sync or async mode - - Map<String, List<URL>> exportedURLsMap = serviceExportedURLsCache.computeIfAbsent(serviceName, s -> new LinkedHashMap()); - - exportedURLs = exportedURLsMap.get(revision); - - boolean firstGet = false; - - if (exportedURLs == null) { // The hit is missing in cache - - if (!exportedURLsMap.isEmpty()) { // The case is that current ServiceInstance with the different revision - if (logger.isWarnEnabled()) { - logger.warn(format("The ServiceInstance[id: %s, host : %s , port : %s] has different revision : %s" + - ", please make sure the service [name : %s] is changing or not.", - providerServiceInstance.getId(), - providerServiceInstance.getHost(), - providerServiceInstance.getPort(), - revision, - providerServiceInstance.getServiceName() - )); - } - } else {// Else, it's the first time to get the exported URLs - firstGet = true; - } - exportedURLs = getExportedURLs(providerServiceInstance); - - if (exportedURLs != null) { // just allow the valid result into exportedURLsMap - - exportedURLsMap.put(revision, exportedURLs); - - if (logger.isDebugEnabled()) { - logger.debug(format("Getting the exported URLs[size : %s, first : %s] from the target service " + - "instance [id: %s , service : %s , host : %s , port : %s , revision : %s]", - exportedURLs.size(), firstGet, - providerServiceInstance.getId(), - providerServiceInstance.getServiceName(), - providerServiceInstance.getHost(), - providerServiceInstance.getPort(), - revision - )); - } - } - } - } + return getRevisionExportedURLs(serviceName, revision); + } - // Get a copy from source in order to prevent the caller trying to change the cached data - return exportedURLs != null ? new ArrayList<>(exportedURLs) : null; + private List<URL> getRevisionExportedURLs(String serviceName, String revision) { + return executeShared(() -> { + Map<String, List<URL>> revisionExportedURLsMap = getRevisionExportedURLsMap(serviceName); + List<URL> exportedURLs = revisionExportedURLsMap.get(revision); + // Get a copy from source in order to prevent the caller trying to change the cached data + return exportedURLs != null ? new ArrayList<>(exportedURLs) : emptyList(); + }); } /** * Get all services {@link URL URLs} that the specified {@link ServiceInstance service instance} exported * from {@link MetadataService} proxy * - * @param providerServiceInstance the {@link ServiceInstance} provides the Dubbo Services + * @param providerServiceInstance the {@link ServiceInstance} exported the Dubbo services * @return The possible result : * <ol> * <li>The normal result</li> @@ -638,11 +695,10 @@ public class ServiceDiscoveryRegistry extends FailbackRegistry { String metadataStorageType = getMetadataStorageType(providerServiceInstance); try { - MetadataService metadataService = MetadataServiceProxyFactory - .getExtension(metadataStorageType == null ? DEFAULT_EXTENSION : metadataStorageType) + MetadataService metadataService = MetadataServiceProxyFactory.getExtension(metadataStorageType) .getProxy(providerServiceInstance); SortedSet<String> urls = metadataService.getExportedURLs(); - exportedURLs = urls.stream().map(URL::valueOf).collect(Collectors.toList()); + exportedURLs = toURLs(urls); } catch (Throwable e) { if (logger.isErrorEnabled()) { logger.error(format("It's failed to get the exported URLs from the target service instance[%s]", @@ -653,36 +709,24 @@ public class ServiceDiscoveryRegistry extends FailbackRegistry { return exportedURLs; } - /** - * Get the exported {@link URL urls} from the specified provider {@link ServiceInstance instance} - * - * @param subscribedURL the subscribed {@link URL url} - * @param providerServiceInstance the target provider {@link ServiceInstance instance} - * @return non-null {@link List} of {@link URL urls} - */ - protected List<URL> getExportedURLs(URL subscribedURL, ServiceInstance providerServiceInstance) { - - List<URL> exportedURLs = emptyList(); - - String serviceInterface = subscribedURL.getServiceInterface(); - String group = subscribedURL.getParameter(GROUP_KEY); - String version = subscribedURL.getParameter(VERSION_KEY); - // The subscribed protocol may be null - String protocol = subscribedURL.getParameter(PROTOCOL_KEY); - String metadataStorageType = getMetadataStorageType(providerServiceInstance); + private void executeExclusively(Runnable runnable) { + Lock writeLock = lock.writeLock(); + writeLock.lock(); + try { + runnable.run(); + } finally { + writeLock.unlock(); + } + } + private <T> T executeShared(Supplier<T> supplier) { + Lock readLock = lock.readLock(); + readLock.lock(); try { - MetadataService metadataService = MetadataServiceProxyFactory - .getExtension(metadataStorageType == null ? DEFAULT_EXTENSION : metadataStorageType) - .getProxy(providerServiceInstance); - SortedSet<String> urls = metadataService.getExportedURLs(serviceInterface, group, version, protocol); - exportedURLs = urls.stream().map(URL::valueOf).collect(Collectors.toList()); - } catch (Throwable e) { - if (logger.isErrorEnabled()) { - logger.error(e.getMessage(), e); - } + return supplier.get(); + } finally { + readLock.unlock(); } - return exportedURLs; } /** @@ -700,7 +744,6 @@ public class ServiceDiscoveryRegistry extends FailbackRegistry { .collect(Collectors.toList()); } - protected Set<String> getServices(URL subscribedURL) { Set<String> serviceNames = getSubscribedServices(); if (isEmpty(serviceNames)) { @@ -751,4 +794,31 @@ public class ServiceDiscoveryRegistry extends FailbackRegistry { public static boolean supports(URL registryURL) { return SERVICE_REGISTRY_TYPE.equalsIgnoreCase(registryURL.getParameter(REGISTRY_TYPE_KEY)); } + + private static List<URL> filterSubscribedURLs(URL subscribedURL, List<URL> exportedURLs) { + return exportedURLs.stream() + .filter(url -> isSameServiceInterface(subscribedURL, url)) + .filter(url -> isSameParameter(subscribedURL, url, VERSION_KEY)) + .filter(url -> isSameParameter(subscribedURL, url, GROUP_KEY)) + .filter(url -> isCompatibleProtocol(subscribedURL, url)) + .collect(Collectors.toList()); + } + + private static boolean isSameServiceInterface(URL one, URL another) { + return Objects.equals(one.getServiceInterface(), another.getServiceInterface()); + } + + private static boolean isSameParameter(URL one, URL another, String key) { + return Objects.equals(one.getParameter(key), another.getParameter(key)); + } + + private static boolean isCompatibleProtocol(URL one, URL another) { + String protocol = one.getParameter(PROTOCOL_KEY); + return isCompatibleProtocol(protocol, another); + } + + private static boolean isCompatibleProtocol(String protocol, URL targetURL) { + return protocol == null || Objects.equals(protocol, targetURL.getParameter(PROTOCOL_KEY)) + || Objects.equals(protocol, targetURL.getProtocol()); + } } \ No newline at end of file diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java index 31a3e1d..a0a52b1 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java @@ -30,8 +30,8 @@ import java.util.List; import java.util.Map; import static java.util.Collections.emptyMap; -import static org.apache.dubbo.common.constants.CommonConstants.METADATA_DEFAULT; import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY; +import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE; import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY; import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY; import static org.apache.dubbo.common.utils.StringUtils.isBlank; @@ -175,7 +175,7 @@ public class ServiceInstanceMetadataUtils { * @return if not found in {@link URL#getParameters() parameters} of {@link URL registry URL}, return */ public static String getMetadataStorageType(URL registryURL) { - return registryURL.getParameter(METADATA_STORAGE_TYPE_PROPERTY_NAME, METADATA_DEFAULT); + return registryURL.getParameter(METADATA_STORAGE_TYPE_PROPERTY_NAME, DEFAULT_METADATA_STORAGE_TYPE); } /** @@ -186,7 +186,7 @@ public class ServiceInstanceMetadataUtils { */ public static String getMetadataStorageType(ServiceInstance serviceInstance) { Map<String, String> metadata = serviceInstance.getMetadata(); - return metadata.getOrDefault(METADATA_STORAGE_TYPE_PROPERTY_NAME, METADATA_DEFAULT); + return metadata.getOrDefault(METADATA_STORAGE_TYPE_PROPERTY_NAME, DEFAULT_METADATA_STORAGE_TYPE); } /** diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/proxy/RemoteMetadataServiceProxyFactory.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/proxy/RemoteMetadataServiceProxyFactory.java index a4815be..9ca472f 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/proxy/RemoteMetadataServiceProxyFactory.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/proxy/RemoteMetadataServiceProxyFactory.java @@ -17,11 +17,8 @@ package org.apache.dubbo.registry.client.metadata.proxy; import org.apache.dubbo.metadata.MetadataService; -import org.apache.dubbo.metadata.WritableMetadataService; import org.apache.dubbo.registry.client.ServiceInstance; -import static org.apache.dubbo.common.constants.CommonConstants.METADATA_REMOTE; - /** * */ @@ -31,5 +28,4 @@ public class RemoteMetadataServiceProxyFactory extends BaseMetadataServiceProxyF public MetadataService createProxy(ServiceInstance serviceInstance) { return new RemoteMetadataServiceProxy(serviceInstance); } - } diff --git a/dubbo-registry/dubbo-registry-eureka/src/main/java/org/apache/dubbo/registry/eureka/EurekaServiceDiscovery.java b/dubbo-registry/dubbo-registry-eureka/src/main/java/org/apache/dubbo/registry/eureka/EurekaServiceDiscovery.java index 26c9345..54bb7f2 100644 --- a/dubbo-registry/dubbo-registry-eureka/src/main/java/org/apache/dubbo/registry/eureka/EurekaServiceDiscovery.java +++ b/dubbo-registry/dubbo-registry-eureka/src/main/java/org/apache/dubbo/registry/eureka/EurekaServiceDiscovery.java @@ -60,7 +60,7 @@ public class EurekaServiceDiscovery implements ServiceDiscovery { private EurekaClient eurekaClient; - private Map<String, String> subscribedServices; + private Set<String> subscribedServices; /** * last apps hash code is used to identify the {@link Applications} is changed or not @@ -184,7 +184,7 @@ public class EurekaServiceDiscovery implements ServiceDiscovery { } private void dispatchServiceInstancesChangedEvent() { - subscribedServices.forEach((serviceName, protocol) -> { + subscribedServices.forEach((serviceName) -> { eventDispatcher.dispatch(new ServiceInstancesChangedEvent(serviceName, getInstances(serviceName))); }); }