Reuse Nacos NamingService connections across registry groups#15891
Reuse Nacos NamingService connections across registry groups#15891somiljain2006 wants to merge 15 commits intoapache:3.3from
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## 3.3 #15891 +/- ##
=========================================
Coverage 60.75% 60.75%
- Complexity 11710 11720 +10
=========================================
Files 1938 1938
Lines 88694 88744 +50
Branches 13387 13390 +3
=========================================
+ Hits 53882 53917 +35
- Misses 29288 29297 +9
- Partials 5524 5530 +6
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR introduces a reference-counted caching mechanism to prevent duplicate Nacos NamingService connections when multiple Dubbo registry groups point to the same Nacos server. The implementation ensures that a single physical connection is shared across registry groups with different group parameters, and connections are only closed when all references are released.
Key changes:
- Introduced
NacosNamingServiceHolderwith atomic reference counting to track shared NamingService wrapper usage - Added URL normalization to create consistent cache keys by removing group parameters and sorting server addresses
- Implemented
releaseNamingService()method for proper connection lifecycle management with reference counting
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
NacosNamingServiceUtils.java |
Core implementation: added connection caching with reference counting, URL normalization for cache key generation, and release mechanism |
NacosRegistry.java |
Updated destroy() method to call releaseNamingService() instead of directly shutting down the wrapper; added cleanup for originToAggregateListener |
NacosNamingServiceUtilsTest.java |
Added @AfterEach cleanup to clear cache between tests; removed unnecessary throws clause from testRetryCreate(); added explicit cache clear in testRetryCreate() |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
...gistry-nacos/src/main/java/org/apache/dubbo/registry/nacos/util/NacosNamingServiceUtils.java
Outdated
Show resolved
Hide resolved
...gistry-nacos/src/main/java/org/apache/dubbo/registry/nacos/util/NacosNamingServiceUtils.java
Show resolved
Hide resolved
...ry-nacos/src/test/java/org/apache/dubbo/registry/nacos/util/NacosNamingServiceUtilsTest.java
Show resolved
Hide resolved
...gistry-nacos/src/main/java/org/apache/dubbo/registry/nacos/util/NacosNamingServiceUtils.java
Outdated
Show resolved
Hide resolved
...gistry-nacos/src/main/java/org/apache/dubbo/registry/nacos/util/NacosNamingServiceUtils.java
Outdated
Show resolved
Hide resolved
...gistry-nacos/src/main/java/org/apache/dubbo/registry/nacos/util/NacosNamingServiceUtils.java
Show resolved
Hide resolved
...gistry-nacos/src/main/java/org/apache/dubbo/registry/nacos/util/NacosNamingServiceUtils.java
Show resolved
Hide resolved
|
Hmm. I’m wondering if we just remove the call to addParameter(CONFIG_NAMESPACE_KEY) from org.apache.dubbo.registry.nacos.NacosRegistryFactory#createRegistryCacheKey, will we get the same result? |
|
No, that would cause different namespaces to collapse into the same cache key. Also, relying solely on RegistryFactory caching is unsafe when multiple services share a Registry instance; one service calling destroy() would physically kill the connection for everyone else. We need the reference counting to manage that lifecycle. |
Regarding the first point, I don’t know what problems the same cache key will cause. In fact, I think the same cache key should yield the correct result—maybe there’s some reason behind the special logic. However, I don’t think the second scenario exists. Because as for the registry, I believe we only destroy it when destroying all components; nor do I think there’s any scenario that requires destroying a nacos group. Moreover, the logic should be that one Nacos server corresponds to one registry instance. |
I don’t mean I’m correct. But I think we must find out why Nacos has this special group-related logic, and what scenarios would trigger the destroy logic. |
|
That makes sense. I agree we should understand the intent behind Nacos’s group-related logic and the lifecycle assumptions more clearly. From what I’ve seen, Nacos treats groups as a naming-level concern, while the NamingService itself is bound to a specific server + namespace. That’s why the Nacos API exposes a group on registration/subscription methods rather than requiring a separate NamingService per group. On the destroy side, the primary scenario guards against is the shutdown race condition. When multiple registry wrappers share a single NamingService, they are destroyed in sequence during application shutdown. Without reference counting, the first registry to close would call shutdown() on the shared connection, instantly killing it. |
What is the purpose of the change?
This change prevents the creation of multiple physical Nacos NamingService connections when a single Dubbo application uses multiple registry groups pointing to the same Nacos server. It introduces a reference-counted cache that reuses a single NamingService instance per unique Nacos connection identity, ensuring connections are only closed when no registries remain.
Fixes #15624
Checklist