fix nacos related issues (#1226)

diff --git a/README.md b/README.md
index 2f6029f..924422a 100644
--- a/README.md
+++ b/README.md
@@ -8,11 +8,11 @@
 
 [中文说明](README_ZH.md)
 
-Dubbo Admin is a console for better visualization of Dubbo services, it provides fully support for Dubbo3 and is compatible with 2.7.x, 2.6.x and 2.5.x.
+Dubbo Admin is the console designed for better visualization of Dubbo services, it provides support for Dubbo3 and is compatible with 2.7.x, 2.6.x and 2.5.x.
 
 ![index](https://raw.githubusercontent.com/apache/dubbo-admin/develop/doc/images/index.png)
 
-There are four ways to deploy Dubbo Admin to a production environment
+There are four ways to deploy Dubbo Admin to a production environment.
 
 1. [Linux with Admin](#11-linux-with-admin)
 2. [Docker with Admin](#12-docker-with-admin)
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/common/util/SyncUtils.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/common/util/SyncUtils.java
index 34b4e65..6841aae 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/common/util/SyncUtils.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/common/util/SyncUtils.java
@@ -31,6 +31,7 @@
 import java.util.Map;
 
 import static org.apache.dubbo.admin.common.util.Constants.COLON;
+import static org.apache.dubbo.admin.common.util.Constants.INTERFACE_KEY;
 
 public class SyncUtils {
 
@@ -201,7 +202,7 @@
     }
 
     private static String getServiceInterface(URL url) {
-        String serviceInterface = url.getServiceInterface();
+        String serviceInterface = url.getOriginalParameter(INTERFACE_KEY);
         if (StringUtils.isBlank(serviceInterface) || Constants.ANY_VALUE.equals(serviceInterface)) {
             serviceInterface = url.getPath();
         }
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/config/ConfigCenter.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/config/ConfigCenter.java
index 0e51b62..49377a2 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/config/ConfigCenter.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/config/ConfigCenter.java
@@ -25,15 +25,19 @@
 import org.apache.dubbo.admin.registry.mapping.impl.NacosServiceMapping;
 import org.apache.dubbo.admin.registry.mapping.impl.NoOpServiceMapping;
 import org.apache.dubbo.admin.registry.metadata.MetaDataCollector;
+import org.apache.dubbo.admin.registry.metadata.impl.DubboDelegateMetadataCollector;
 import org.apache.dubbo.admin.registry.metadata.impl.NoOpMetadataCollector;
 import org.apache.dubbo.admin.service.impl.InstanceRegistryCache;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
 import org.apache.dubbo.common.extension.ExtensionLoader;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.metadata.MappingListener;
+import org.apache.dubbo.metadata.report.MetadataReport;
+import org.apache.dubbo.metadata.report.MetadataReportInstance;
 import org.apache.dubbo.registry.Registry;
 import org.apache.dubbo.registry.RegistryFactory;
 import org.apache.dubbo.registry.RegistryService;
@@ -46,6 +50,7 @@
 import org.springframework.context.annotation.DependsOn;
 
 import java.util.Arrays;
+import java.util.Optional;
 
 import static org.apache.dubbo.common.constants.CommonConstants.CLUSTER_KEY;
 import static org.apache.dubbo.common.constants.RegistryConstants.ENABLE_EMPTY_PROTECTION_KEY;
@@ -181,6 +186,15 @@
             metaDataCollector.init();
         } else {
             logger.warn("you are using dubbo.registry.address, which is not recommend, please refer to: https://github.com/apache/dubbo-admin/wiki/Dubbo-Admin-configuration");
+            ApplicationModel applicationModel = ApplicationModel.defaultModel();
+            ScopeBeanFactory beanFactory = applicationModel.getBeanFactory();
+            MetadataReportInstance metadataReportInstance = beanFactory.registerBean(MetadataReportInstance.class);
+
+            Optional<MetadataReport> metadataReport = metadataReportInstance.getMetadataReports(true)
+                    .values().stream().findAny();
+
+            metaDataCollector = new DubboDelegateMetadataCollector(metadataReport.get());
+            metaDataCollector.setUrl(registryUrl);
         }
         return metaDataCollector;
     }
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/controller/ApiDocsController.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/controller/ApiDocsController.java
index 1eddcab..4638040 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/controller/ApiDocsController.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/controller/ApiDocsController.java
@@ -138,14 +138,18 @@
         if (null == paramValues) {
             paramValues = new Object[0];
         }
-        CompletableFuture<Object> future = ApiDocsDubboGenericUtil.invoke(dubboCfg.getRegistryCenterUrl(), dubboCfg.getInterfaceClassName(),
-                dubboCfg.getMethodName(), dubboCfg.isAsync(), dubboCfg.getVersion(), paramTypes, paramValues, dubboCfg.getGroup());
         try {
-            Object objResult = future.get();
-            return JSON.toJSONString(objResult, CLASS_NAME_PRE_FILTER);
-        } catch (InterruptedException | ExecutionException e) {
-            LOG.error(e.getMessage(), e);
-            return "Some exceptions have occurred, please check the log.";
+            CompletableFuture<Object> future = ApiDocsDubboGenericUtil.invoke(dubboCfg.getRegistryCenterUrl(), dubboCfg.getInterfaceClassName(),
+                    dubboCfg.getMethodName(), dubboCfg.isAsync(), dubboCfg.getVersion(), paramTypes, paramValues, dubboCfg.getGroup());
+            try {
+                Object objResult = future.get();
+                return JSON.toJSONString(objResult, CLASS_NAME_PRE_FILTER);
+            } catch (InterruptedException | ExecutionException e) {
+                LOG.error(e.getMessage(), e);
+                return "Some exceptions have occurred, please check the log.";
+            }
+        } catch (Exception e) {
+            return "Error '" + e.getMessage() + "' happened when loading docs from remote. Please make sure api-docs dependency is correctly added to Dubbo providers, check the following link for more instructions: https://cn.dubbo.apache.org/zh-cn/overview/reference/admin/";
         }
     }
 
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/controller/MetricsCollectController.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/controller/MetricsCollectController.java
index aa493f8..e774e75 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/controller/MetricsCollectController.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/controller/MetricsCollectController.java
@@ -31,6 +31,7 @@
 import org.apache.dubbo.admin.service.MetricsService;
 import org.apache.dubbo.admin.service.ProviderService;
 import org.apache.dubbo.admin.service.impl.MetrcisCollectServiceImpl;
+import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
 import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -102,35 +103,39 @@
 
     protected void addMetricsConfigToMap(Map<String, String> configMap, String ip) {
         List<Provider> providers = providerService.findByAddress(ip);
-        if (providers.size() > 0) {
+        if (!providers.isEmpty()) {
             for (int i = 0; i < providers.size() && configMap.isEmpty(); i++) {
                 Provider provider = providers.get(i);
                 String service = provider.getService();
                 MetadataIdentifier providerIdentifier = new MetadataIdentifier(Tool.getInterface(service), Tool.getVersion(service), Tool.getGroup(service),
                         Constants.PROVIDER_SIDE, provider.getApplication());
                 String metaData = providerService.getProviderMetaData(providerIdentifier);
-                FullServiceDefinition providerServiceDefinition = new Gson().fromJson(metaData, FullServiceDefinition.class);
-                Map<String, String> parameters = providerServiceDefinition.getParameters();
-                String metricsPort = parameters.get(Constants.METRICS_PORT);
-                String metricsProtocol = parameters.get(Constants.METRICS_PROTOCOL);
-                if (metricsPort != null && metricsProtocol != null) {
-                    configMap.put(metricsPort, metricsProtocol);
+                if (StringUtils.isNotEmpty(metaData)) {
+                    FullServiceDefinition providerServiceDefinition = new Gson().fromJson(metaData, FullServiceDefinition.class);
+                    Map<String, String> parameters = providerServiceDefinition.getParameters();
+                    String metricsPort = parameters.get(Constants.METRICS_PORT);
+                    String metricsProtocol = parameters.get(Constants.METRICS_PROTOCOL);
+                    if (metricsPort != null && metricsProtocol != null) {
+                        configMap.put(metricsPort, metricsProtocol);
+                    }
                 }
             }
         } else {
             List<Consumer> consumers = consumerService.findByAddress(ip);
-            if (consumers.size() > 0) {
+            if (!consumers.isEmpty()) {
                 for (int i = 0; i < consumers.size() && configMap.isEmpty(); i++) {
                     Consumer consumer = consumers.get(i);
                     String service = consumer.getService();
                     MetadataIdentifier consumerIdentifier = new MetadataIdentifier(Tool.getInterface(service), Tool.getVersion(service), Tool.getGroup(service),
                             Constants.CONSUMER_SIDE, consumer.getApplication());
                     String metaData = consumerService.getConsumerMetadata(consumerIdentifier);
-                    Map<String, String> consumerParameters = new Gson().fromJson(metaData, Map.class);
-                    String metricsPort = consumerParameters.get(Constants.METRICS_PORT);
-                    String metricsProtocol = consumerParameters.get(Constants.METRICS_PROTOCOL);
-                    if (metricsPort != null && metricsProtocol != null) {
-                        configMap.put(metricsPort, metricsProtocol);
+                    if (StringUtils.isNotEmpty(metaData)) {
+                        Map<String, String> consumerParameters = new Gson().fromJson(metaData, Map.class);
+                        String metricsPort = consumerParameters.get(Constants.METRICS_PORT);
+                        String metricsProtocol = consumerParameters.get(Constants.METRICS_PROTOCOL);
+                        if (metricsPort != null && metricsProtocol != null) {
+                            configMap.put(metricsPort, metricsProtocol);
+                        }
                     }
                 }
             }
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/controller/ServiceController.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/controller/ServiceController.java
index bfd801a..92824ed 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/controller/ServiceController.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/controller/ServiceController.java
@@ -32,6 +32,8 @@
 import org.apache.dubbo.admin.service.ProviderService;
 import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
 import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
+import org.apache.dubbo.registry.Registry;
+
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageImpl;
@@ -57,6 +59,9 @@
     private final Gson gson;
 
     @Autowired
+    private Registry registry;
+
+    @Autowired
     public ServiceController(ProviderService providerService, ConsumerService consumerService) {
         this.providerService = providerService;
         this.consumerService = consumerService;
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/mapping/AdminMappingListener.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/mapping/AdminMappingListener.java
index e335755..42a4219 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/mapping/AdminMappingListener.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/mapping/AdminMappingListener.java
@@ -18,20 +18,25 @@
 package org.apache.dubbo.admin.registry.mapping;
 
 import org.apache.dubbo.admin.common.util.Constants;
+import org.apache.dubbo.admin.registry.nacos.NacosData;
+import org.apache.dubbo.admin.registry.nacos.NacosOpenapiUtil;
 import org.apache.dubbo.admin.service.impl.InstanceRegistryCache;
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.utils.CollectionUtils;
 import org.apache.dubbo.common.utils.NetUtils;
 import org.apache.dubbo.metadata.MappingChangedEvent;
 import org.apache.dubbo.metadata.MappingListener;
+import org.apache.dubbo.registry.client.DefaultServiceInstance;
 import org.apache.dubbo.registry.client.InstanceAddressURL;
 import org.apache.dubbo.registry.client.ServiceDiscovery;
 import org.apache.dubbo.registry.client.ServiceInstance;
 import org.apache.dubbo.registry.client.event.ServiceInstancesChangedEvent;
 import org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListener;
+import org.apache.dubbo.registry.nacos.NacosServiceDiscovery;
 
 import com.google.common.collect.Sets;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -39,6 +44,8 @@
 import java.util.concurrent.ConcurrentMap;
 import java.util.stream.Collectors;
 
+import static org.apache.dubbo.admin.common.util.Constants.CATEGORY_KEY;
+
 public class AdminMappingListener implements MappingListener {
 
     private static final URL CONSUMER_URL = new URL(Constants.ADMIN_PROTOCOL, NetUtils.getLocalHost(), 0, "",
@@ -46,7 +53,7 @@
             Constants.GROUP_KEY, Constants.ANY_VALUE,
             Constants.VERSION_KEY, Constants.ANY_VALUE,
             Constants.CLASSIFIER_KEY, Constants.ANY_VALUE,
-            Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY + ","
+            CATEGORY_KEY, Constants.PROVIDERS_CATEGORY + ","
             + Constants.CONSUMERS_CATEGORY + ","
             + Constants.ROUTERS_CATEGORY + ","
             + Constants.CONFIGURATORS_CATEGORY,
@@ -79,13 +86,19 @@
                     if (serviceInstancesChangedListener == null) {
                         AddressChangeListener addressChangeListener = new DefaultAddressChangeListener(serviceName, instanceRegistryCache);
                         serviceInstancesChangedListener = new AdminServiceInstancesChangedListener(Sets.newHashSet(serviceName), serviceDiscovery, addressChangeListener);
-                        serviceInstancesChangedListener.setUrl(CONSUMER_URL);
+//                        serviceInstancesChangedListener.setUrl(CONSUMER_URL);
+                        List<ServiceInstance> allInstances = new ArrayList<>();
                         List<ServiceInstance> serviceInstances = serviceDiscovery.getInstances(serviceName);
+                        if (serviceDiscovery instanceof NacosServiceDiscovery) {
+                            List<ServiceInstance> consumerInstances = convertToInstance(NacosOpenapiUtil.getSubscribeAddressesWithHttpEndpoint(serviceDiscovery.getUrl(), serviceName));
+                            allInstances.addAll(consumerInstances);
+                        }
                         if (CollectionUtils.isNotEmpty(serviceInstances)) {
-                            serviceInstancesChangedListener.onEvent(new ServiceInstancesChangedEvent(serviceName, serviceInstances));
+                            allInstances.addAll(serviceInstances);
+                            serviceInstancesChangedListener.onEvent(new ServiceInstancesChangedEvent(serviceName, allInstances));
                         }
                         serviceListeners.put(serviceName, serviceInstancesChangedListener);
-                        serviceInstancesChangedListener.setUrl(CONSUMER_URL);
+//                        serviceInstancesChangedListener.setUrl(CONSUMER_URL);
                         serviceDiscovery.addServiceInstancesChangedListener(serviceInstancesChangedListener);
                     }
                 }
@@ -93,6 +106,15 @@
         }
     }
 
+    private List<ServiceInstance> convertToInstance(List<NacosData> nacosData) {
+       return nacosData.stream().map(nacos -> {
+           DefaultServiceInstance instance = new DefaultServiceInstance();
+           instance.setHost(nacos.getIp());
+           instance.setPort(nacos.getPort());
+           return instance;
+       }).collect(Collectors.toList());
+    }
+
     private static class DefaultAddressChangeListener implements AddressChangeListener {
 
         private String serviceName;
@@ -107,13 +129,22 @@
         @Override
         public void notifyAddressChanged(String protocolServiceKey, List<URL> urls) {
             String serviceKey = removeProtocol(protocolServiceKey);
+
             ConcurrentMap<String, Map<String, List<InstanceAddressURL>>> appServiceMap = instanceRegistryCache.computeIfAbsent(Constants.PROVIDERS_CATEGORY, key -> new ConcurrentHashMap<>());
+
             Map<String, List<InstanceAddressURL>> serviceMap = appServiceMap.computeIfAbsent(serviceName, key -> new ConcurrentHashMap<>());
+            Map<String, List<URL>> consumerServiceMap = instanceRegistryCache.getSubscribedCache().computeIfAbsent(serviceName, key -> new ConcurrentHashMap<>());
+
             if (CollectionUtils.isEmpty(urls)) {
                 serviceMap.remove(serviceKey);
+                consumerServiceMap.remove(serviceKey);
             } else {
-                List<InstanceAddressURL> instanceAddressUrls = urls.stream().map(url -> (InstanceAddressURL) url).collect(Collectors.toList());
-                serviceMap.put(serviceKey, instanceAddressUrls);
+                if ("consumer".equals(urls.get(0).getParameter(CATEGORY_KEY))) {
+                    consumerServiceMap.put(serviceKey, urls);
+                } else {
+                    List<InstanceAddressURL> instanceAddressUrls = urls.stream().map(url -> (InstanceAddressURL) url).collect(Collectors.toList());
+                    serviceMap.put(serviceKey, instanceAddressUrls);
+                }
             }
             instanceRegistryCache.refreshConsumer(false);
         }
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/mapping/impl/NacosServiceMapping.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/mapping/impl/NacosServiceMapping.java
index 9633ebb..2d40f67 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/mapping/impl/NacosServiceMapping.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/mapping/impl/NacosServiceMapping.java
@@ -25,6 +25,7 @@
 import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.metadata.MappingChangedEvent;
 import org.apache.dubbo.metadata.MappingListener;
+import org.apache.dubbo.registry.client.ServiceInstance;
 import org.apache.dubbo.registry.nacos.NacosNamingServiceWrapper;
 import org.apache.dubbo.registry.nacos.util.NacosNamingServiceUtils;
 
@@ -33,6 +34,10 @@
 import com.alibaba.nacos.api.naming.pojo.ListView;
 import com.google.common.collect.Sets;
 
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
@@ -156,10 +161,8 @@
         }
     }
 
-
     @Override
     public void addMappingListener(MappingListener listener) {
         listeners.add(listener);
     }
-
-}
+}
\ No newline at end of file
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/metadata/impl/DubboDelegateMetadataCollector.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/metadata/impl/DubboDelegateMetadataCollector.java
new file mode 100644
index 0000000..58cdae8
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/metadata/impl/DubboDelegateMetadataCollector.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.admin.registry.metadata.impl;
+
+import org.apache.dubbo.admin.registry.metadata.MetaDataCollector;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.metadata.report.MetadataReport;
+import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
+
+public class DubboDelegateMetadataCollector implements MetaDataCollector {
+    private MetadataReport metadataReport;
+    private URL url;
+
+    public DubboDelegateMetadataCollector(MetadataReport metadataReport) {
+        this.metadataReport = metadataReport;
+    }
+
+    @Override
+    public void setUrl(URL url) {
+        this.url = url;
+    }
+
+    @Override
+    public URL getUrl() {
+        return url;
+    }
+
+    @Override
+    public void init() {
+
+    }
+
+    @Override
+    public String getProviderMetaData(MetadataIdentifier key) {
+        return metadataReport.getServiceDefinition(key);
+    }
+
+    @Override
+    public String getConsumerMetaData(MetadataIdentifier key) {
+        return metadataReport.getServiceDefinition(key);
+    }
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/nacos/NacosData.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/nacos/NacosData.java
new file mode 100644
index 0000000..e764888
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/nacos/NacosData.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.admin.registry.nacos;
+
+public class NacosData {
+    private String addrStr;
+    private String agent;
+    private String app;
+    private String namespaceId;
+    private String serviceName;
+    private String cluster;
+    private String ip;
+    private int port;
+
+    public String getAddrStr() {
+        return addrStr;
+    }
+
+    public void setAddrStr(String addrStr) {
+        this.addrStr = addrStr;
+    }
+
+    public String getAgent() {
+        return agent;
+    }
+
+    public void setAgent(String agent) {
+        this.agent = agent;
+    }
+
+    public String getApp() {
+        return app;
+    }
+
+    public void setApp(String app) {
+        this.app = app;
+    }
+
+    public String getNamespaceId() {
+        return namespaceId;
+    }
+
+    public void setNamespaceId(String namespaceId) {
+        this.namespaceId = namespaceId;
+    }
+
+    public String getServiceName() {
+        return serviceName;
+    }
+
+    public void setServiceName(String serviceName) {
+        this.serviceName = serviceName;
+    }
+
+    public String getCluster() {
+        return cluster;
+    }
+
+    public void setCluster(String cluster) {
+        this.cluster = cluster;
+    }
+
+    public String getIp() {
+        return ip;
+    }
+
+    public void setIp(String ip) {
+        this.ip = ip;
+    }
+
+    public int getPort() {
+        return port;
+    }
+
+    public void setPort(int port) {
+        this.port = port;
+    }
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/nacos/NacosOpenapiUtil.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/nacos/NacosOpenapiUtil.java
new file mode 100644
index 0000000..35bf509
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/nacos/NacosOpenapiUtil.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.admin.registry.nacos;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.StringUtils;
+
+import com.alibaba.fastjson2.JSON;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.util.Collections;
+import java.util.List;
+
+public class NacosOpenapiUtil {
+    public static List<NacosData> getSubscribeAddressesWithHttpEndpoint(URL url, String serviceName) {
+        // 定义Nacos OpenAPI的URL
+        String nacosUrl = "http://" + url.getAddress() + "/nacos/v1/ns/service/subscribers?serviceName=" + serviceName;
+        if (StringUtils.isNotEmpty(url.getParameter("namespace"))) {
+            nacosUrl = nacosUrl + "&namespaceId=" + url.getParameter("namespace");
+        }
+        if (StringUtils.isNotEmpty(url.getParameter("group"))) {
+            nacosUrl = nacosUrl + "&groupName=" + url.getParameter("group");
+        }
+
+        // 创建URL对象
+        java.net.URL netUrl = null;
+        try {
+            netUrl = new java.net.URL(nacosUrl);
+        } catch (MalformedURLException e) {
+            throw new RuntimeException(e);
+        }
+
+        HttpURLConnection connection = null;
+        try {
+
+            // 创建HTTP连接
+            connection = (HttpURLConnection) netUrl.openConnection();
+
+            // 设置请求方法(GET或POST)
+            connection.setRequestMethod("GET");
+
+            // 发送请求并获取响应状态码
+            int responseCode = connection.getResponseCode();
+
+            // 读取响应内容
+            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
+            String line;
+            StringBuilder response = new StringBuilder();
+            while ((line = reader.readLine()) != null) {
+                response.append(line);
+            }
+            reader.close();
+
+            // 打印响应结果
+            System.out.println("Response Code: " + responseCode);
+            System.out.println("Response Body: " + response.toString());
+
+            NacosResponse nacosResponse = JSON.parseObject(response.toString(), NacosResponse.class);
+            return nacosResponse.getSubscribers();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            // 关闭连接
+            if (connection != null) {
+                connection.disconnect();
+            }
+        }
+        return Collections.EMPTY_LIST;
+    }
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/nacos/NacosResponse.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/nacos/NacosResponse.java
new file mode 100644
index 0000000..8b05a9a
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/nacos/NacosResponse.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.admin.registry.nacos;
+
+import java.util.List;
+
+public class NacosResponse {
+    private int count;
+    private List<NacosData> subscribers;
+
+    public int getCount() {
+        return count;
+    }
+
+    public void setCount(int count) {
+        this.count = count;
+    }
+
+    public List<NacosData> getSubscribers() {
+        return subscribers;
+    }
+
+    public void setSubscribers(List<NacosData> subscribers) {
+        this.subscribers = subscribers;
+    }
+}
+
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/AdminProviderFirstParams.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/AdminProviderFirstParams.java
new file mode 100644
index 0000000..86a4aa2
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/AdminProviderFirstParams.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.admin.service;
+
+import org.apache.dubbo.registry.ProviderFirstParams;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.RELEASE_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.TAG_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
+
+public class AdminProviderFirstParams implements ProviderFirstParams {
+    private static final Set<String> PARAMS = Collections.unmodifiableSet(new HashSet<String>() {{
+        addAll(Arrays.asList(INTERFACE_KEY, APPLICATION_KEY));
+    }});
+    @Override
+    public Set<String> params() {
+        return PARAMS;
+    }
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/RegistryServerSync.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/RegistryServerSync.java
index 886c5b6..1e94533 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/RegistryServerSync.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/RegistryServerSync.java
@@ -28,6 +28,8 @@
 import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.registry.NotifyListener;
 import org.apache.dubbo.registry.Registry;
+import org.apache.dubbo.registry.client.InstanceAddressURL;
+import org.apache.dubbo.registry.nacos.NacosRegistry;
 
 import org.springframework.beans.factory.DisposableBean;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -43,13 +45,15 @@
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
+import static org.apache.dubbo.admin.common.util.Constants.INTERFACE_KEY;
+
 @Component
 public class RegistryServerSync implements DisposableBean, NotifyListener {
 
     private static final Logger logger = LoggerFactory.getLogger(RegistryServerSync.class);
 
     private static final URL SUBSCRIBE = new URL(Constants.ADMIN_PROTOCOL, NetUtils.getLocalHost(), 0, "",
-            Constants.INTERFACE_KEY, Constants.ANY_VALUE,
+            INTERFACE_KEY, Constants.ANY_VALUE,
             Constants.GROUP_KEY, Constants.ANY_VALUE,
             Constants.VERSION_KEY, Constants.ANY_VALUE,
             Constants.CLASSIFIER_KEY, Constants.ANY_VALUE,
@@ -96,6 +100,9 @@
         final Map<String, Map<String, Map<String, URL>>> categories = new HashMap<>();
         String interfaceName = null;
         for (URL url : urls) {
+            if (url instanceof InstanceAddressURL) {
+                continue;
+            }
             String category = url.getUrlParam().getParameter(Constants.CATEGORY_KEY);
             if (category == null) {
                 // Assign an initial value to category according to the information in url
@@ -175,7 +182,7 @@
     }
 
     private String getServiceInterface(URL url) {
-        String serviceInterface = url.getServiceInterface();
+        String serviceInterface = url.getOriginalParameter(INTERFACE_KEY);
         if (StringUtils.isBlank(serviceInterface) || Constants.ANY_VALUE.equals(serviceInterface)) {
             serviceInterface = url.getPath();
         }
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/ConsumerServiceImpl.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/ConsumerServiceImpl.java
index 8395026..c6163ba 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/ConsumerServiceImpl.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/ConsumerServiceImpl.java
@@ -20,10 +20,16 @@
 import org.apache.dubbo.admin.common.util.Constants;
 import org.apache.dubbo.admin.common.util.SyncUtils;
 import org.apache.dubbo.admin.model.domain.Consumer;
+import org.apache.dubbo.admin.registry.nacos.NacosData;
+import org.apache.dubbo.admin.registry.nacos.NacosOpenapiUtil;
 import org.apache.dubbo.admin.service.ConsumerService;
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.NetUtils;
 import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
+import org.apache.dubbo.registry.Registry;
+import org.apache.dubbo.registry.client.DefaultServiceInstance;
+import org.apache.dubbo.registry.nacos.NacosRegistry;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
@@ -31,6 +37,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 @Component
 public class ConsumerServiceImpl extends AbstractService implements ConsumerService {
@@ -38,13 +45,38 @@
     @Autowired
     private InstanceRegistryQueryHelper instanceRegistryQueryHelper;
 
+    @Autowired
+    private Registry registry;
+
     @Override
     public List<Consumer> findByService(String service) {
         List<Consumer> consumers = SyncUtils.url2ConsumerList(findConsumerUrlByService(service));
+        if (registry.getUrl().getProtocol().equals("nacos")) {
+            consumers.addAll(convertToConsumer(NacosOpenapiUtil.getSubscribeAddressesWithHttpEndpoint(registry.getUrl(), getNacosDastaId(service))));
+        }
         consumers.addAll(instanceRegistryQueryHelper.findConsumerByService(service));
         return consumers;
     }
 
+    private static String getNacosDastaId(String service) {
+        // interface:version:group
+        int len = service.split(":").length;
+        if (len == 1) {
+            service += "::";
+        } else if (len == 2) {
+            service += ":";
+        }
+        return service;
+    }
+
+    private List<Consumer> convertToConsumer(List<NacosData> nacosData) {
+        return nacosData.stream().map(nacos -> {
+            Consumer c = new Consumer();
+            c.setAddress(nacos.getIp() + ":" + nacos.getPort());
+            c.setApplication(nacos.getApp());
+            return c;
+        }).collect(Collectors.toList());
+    }
 
     @Override
     public List<Consumer> findAll() {
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/InstanceRegistryCache.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/InstanceRegistryCache.java
index 32aa956..4a4037f 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/InstanceRegistryCache.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/InstanceRegistryCache.java
@@ -54,7 +54,7 @@
 
     private final ConcurrentMap<String, ConcurrentMap<String, Map<String, List<InstanceAddressURL>>>> registryCache = new ConcurrentHashMap<>();
 
-    private final Map<String, Map<String, List<URL>>> subscribedCache = new ConcurrentHashMap<>();
+    private final ConcurrentMap<String, Map<String, List<URL>>> subscribedCache = new ConcurrentHashMap<>();
 
     private final AtomicBoolean startRefresh = new AtomicBoolean(false);
 
diff --git a/dubbo-admin-server/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.ProviderFirstParams b/dubbo-admin-server/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.ProviderFirstParams
new file mode 100644
index 0000000..52ac297
--- /dev/null
+++ b/dubbo-admin-server/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.ProviderFirstParams
@@ -0,0 +1 @@
+admin=org.apache.dubbo.admin.service.AdminProviderFirstParams
diff --git a/dubbo-admin-server/src/main/resources/application.properties b/dubbo-admin-server/src/main/resources/application.properties
index 0e3ff31..accb327 100644
--- a/dubbo-admin-server/src/main/resources/application.properties
+++ b/dubbo-admin-server/src/main/resources/application.properties
@@ -19,7 +19,7 @@
 dubbo.protocol.port=30880
 dubbo.application.qos-port=32222
 
-# centers in dubbo2.7, if you want to add parameters, please add them to the url
+# centers in dubbo, if you want to add parameters, please add them to the url
 admin.registry.address=zookeeper://127.0.0.1:2181
 admin.config-center=zookeeper://127.0.0.1:2181
 admin.metadata-report.address=zookeeper://127.0.0.1:2181
diff --git a/pom.xml b/pom.xml
index f7ae409..1dffc6f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -56,9 +56,9 @@
 		<revision>0.5.0-SNAPSHOT</revision>
 		<main.basedir>${project.basedir}</main.basedir>
 		<commons-lang3-version>3.7</commons-lang3-version>
-		<dubbo-version>3.1.6</dubbo-version>
+		<dubbo-version>3.2.5</dubbo-version>
 		<fastjson-version>1.2.83</fastjson-version>
-		<springfox-swagger-version>2.10.0</springfox-swagger-version>
+		<springfox-swagger-version>2.9.2</springfox-swagger-version>
 		<jacoco-version>0.8.2</jacoco-version>
 		<apollo-version>1.2.0</apollo-version>
 		<guava-version>20.0</guava-version>