apache / apache/dubbo

[Bug] When Service Discovery is enabled, the same registryId may create two ServiceDiscoveryRegistry

Open
#14,347 2 comments 0 reactions 0 assignees View on GitHub
component/need-triage type/need-triage
Dominant language
Java
Stars
41.6k
Forks
26.4k
Avg merge
15h 13m
Merged PRs (30d)
4

Description

### Pre-check

- [X] I am sure that all the content I provide is in English.

### Search before asking

- [X] I had searched in the [issues](https://github.com/apache/dubbo/issues?q=is%3Aissue) and found no similar issues.

### Apache Dubbo Component

Java SDK (apache/dubbo)

### Dubbo Version

dubbo3.2.12 , jdk17

### Steps to reproduce this issue

We have a Dubbo 3.2 service provider that is also a Dubbo Consumer. With application-level Service Discovery enabled, the same registryId creates two ServiceDiscoveryRegistry after ServiceConfig #doExportUrl and RefrenceConfig#refer.

I created a reproducible[ Dubbo application](https://github.com/huisman6/dubbo-playground), the configuration of application-level Service Discovery is as follows:
```yaml
dubbo:
application:
name: dubbo-playground
metadata-type: local
register-mode: instance
migration.step: FORCE_APPLICATION
registry:
id: registry-multiple
address: default://localhost:8848
use-as-config-center: false
use-as-metadata-center: false
register-mode: instance
parameters:
registry-type: service
```

Our application supports dynamically adjusting instance weights, warm-up duration, and other service discovery metadata through the Http Endpoint runtime.

When the instance metadata changes, it triggers instance re-registration or update. In the underlying implementation, all discovery registries are obtained through RegistryManager#getServiceDiscoveries and its API is called.

Now the same registryId creates two ServiceDiscoveryRegistry, which means that we need to update the metadata once and send two requests to the same service discovery registry.

ServiceDiscoveryRegistry created twice because ServiceDiscoveryRegistryFactory registry cache key contains the full url parameter.

``` java
public class ServiceDiscoveryRegistryFactory extends AbstractRegistryFactory {

@Override
protected String createRegistryCacheKey(URL url) {
return url.toFullString();
}
}
```

When ServiceConfig exports the service, it adds a URL parameter register = false.

``` java
private void doExportUrl(URL url, boolean withMetaData, RegisterTypeEnum registerType) {
if (!url.getParameter(REGISTER_KEY, true)) {
registerType = RegisterTypeEnum.MANUAL_REGISTER;
}
if (registerType == RegisterTypeEnum.NEVER_REGISTER
|| registerType == RegisterTypeEnum.MANUAL_REGISTER
|| registerType == RegisterTypeEnum.AUTO_REGISTER_BY_DEPLOYER) {
url = url.addParameter(REGISTER_KEY, false);
}
```

However, when using ReferenceConfig#createInvoker, there is no parameter register = false in the Registry URL, resulting in two cache keys.

### What you expected to happen

Is it possible to adjust the registry cache key to the following code to ensure that the same registryId always returns the same ServiceDiscoveryRegistry?
``` java
protected String createRegistryCacheKey(URL url) {
String registryCluster=url.getParameter(RegistryConstants.REGISTRY_CLUSTER_KEY);
if (StringUtils.hasText(registryCluster)){
return registryCluster;
}
return url.toFullString();
}
```

### Anything else

_No response_

### Are you willing to submit a pull request to fix on your own?

- [ ] Yes I am willing to submit a pull request on my own!

### Code of Conduct

- [X] I agree to follow this project's [Code of Conduct](https://www.apache.org/foundation/policies/conduct)

Contributor guide

Open the contributing guide

Research direction

Start with ServiceDiscoveryRegistryFactory#createRegistryCacheKey and compare the URLs produced by ServiceConfig#doExportUrl and ReferenceConfig#createInvoker. Trace how RegistryManager#getServiceDiscoveries obtains registries, then use the linked reproducible Dubbo application to verify that one registryId produces one ServiceDiscoveryRegistry and one metadata update request.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
backend, distributed-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.