You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by ra...@apache.org on 2021/09/03 03:15:35 UTC
[dubbo-admin] branch develop updated: Nacos support application
discover (#812)
This is an automated email from the ASF dual-hosted git repository.
ranke pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/dubbo-admin.git
The following commit(s) were added to refs/heads/develop by this push:
new 237fd26 Nacos support application discover (#812)
237fd26 is described below
commit 237fd266a686e70b359ccf2ff8b2311d0b3ebdc5
Author: haoyann <10...@qq.com>
AuthorDate: Fri Sep 3 11:13:33 2021 +0800
Nacos support application discover (#812)
---
.../apache/dubbo/admin/common/util/SyncUtils.java | 14 +-
.../registry/mapping/impl/NacosServiceMapping.java | 170 +++++++++++++++++++++
.../dubbo/admin/service/RegistryServerSync.java | 17 ++-
...che.dubbo.admin.registry.mapping.ServiceMapping | 3 +-
4 files changed, 197 insertions(+), 7 deletions(-)
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 88e9e73..7a36c0b 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
@@ -21,6 +21,7 @@ import org.apache.dubbo.admin.model.domain.Provider;
import org.apache.dubbo.admin.model.domain.RegistrySource;
import org.apache.dubbo.common.BaseServiceMetadata;
import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.StringUtils;
import java.util.ArrayList;
import java.util.HashMap;
@@ -52,7 +53,7 @@ public class SyncUtils {
p.setHash(id);
String group = url.getUrlParam().getParameter(Constants.GROUP_KEY);
String version = url.getUrlParam().getParameter(Constants.VERSION_KEY);
- String service = BaseServiceMetadata.buildServiceKey(url.getServiceInterface(), group, version);
+ String service = BaseServiceMetadata.buildServiceKey(getServiceInterface(url), group, version);
p.setService(service);
p.setAddress(url.getAddress());
p.setApplication(url.getParameter(Constants.APPLICATION_KEY));
@@ -91,7 +92,7 @@ public class SyncUtils {
c.setHash(id);
String group = url.getUrlParam().getParameter(Constants.GROUP_KEY);
String version = url.getUrlParam().getParameter(Constants.VERSION_KEY);
- String service = BaseServiceMetadata.buildServiceKey(url.getServiceInterface(), group, version);
+ String service = BaseServiceMetadata.buildServiceKey(getServiceInterface(url), group, version);
c.setService(service);
c.setAddress(url.getHost());
c.setApplication(url.getParameter(Constants.APPLICATION_KEY));
@@ -188,4 +189,13 @@ public class SyncUtils {
}
return null;
}
+
+ private static String getServiceInterface(URL url) {
+ String serviceInterface = url.getServiceInterface();
+ if (StringUtils.isBlank(serviceInterface) || Constants.ANY_VALUE.equals(serviceInterface)) {
+ serviceInterface = url.getPath();
+ }
+ return serviceInterface;
+ }
+
}
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
new file mode 100644
index 0000000..6749da6
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/mapping/impl/NacosServiceMapping.java
@@ -0,0 +1,170 @@
+/*
+ * 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.mapping.impl;
+
+import org.apache.dubbo.admin.registry.mapping.ServiceMapping;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.utils.ConcurrentHashSet;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.metadata.MappingChangedEvent;
+import org.apache.dubbo.metadata.MappingListener;
+import org.apache.dubbo.registry.nacos.NacosNamingServiceWrapper;
+import org.apache.dubbo.registry.nacos.util.NacosNamingServiceUtils;
+
+import com.alibaba.nacos.api.common.Constants;
+import com.alibaba.nacos.api.exception.NacosException;
+import com.alibaba.nacos.api.naming.pojo.ListView;
+import com.google.common.collect.Sets;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import static com.alibaba.nacos.api.PropertyKeyConst.NAMING_LOAD_CACHE_AT_START;
+import static org.apache.dubbo.common.constants.RegistryConstants.CONFIGURATORS_CATEGORY;
+import static org.apache.dubbo.common.constants.RegistryConstants.CONSUMERS_CATEGORY;
+import static org.apache.dubbo.common.constants.RegistryConstants.PROVIDERS_CATEGORY;
+import static org.apache.dubbo.common.constants.RegistryConstants.ROUTERS_CATEGORY;
+
+/**
+ * Nacos not support batch listen config feature. Therefore, regularly query the service list instead of notification
+ */
+public class NacosServiceMapping implements ServiceMapping {
+
+ /**
+ * All 2.x supported categories
+ */
+ private static final List<String> ALL_SUPPORTED_CATEGORIES = Arrays.asList(
+ PROVIDERS_CATEGORY,
+ CONSUMERS_CATEGORY,
+ ROUTERS_CATEGORY,
+ CONFIGURATORS_CATEGORY
+ );
+
+ /**
+ * The separator for service name
+ * Change a constant to be configurable, it's designed for Windows file name that is compatible with old
+ * Nacos binary release(< 0.6.1)
+ */
+ private static final String SERVICE_NAME_SEPARATOR = System.getProperty("nacos.service.name.separator", ":");
+
+ private static final long LOOKUP_INTERVAL = Long.getLong("nacos.service.names.lookup.interval", 30);
+
+ private ScheduledExecutorService scheduledExecutorService;
+
+ private final Set<MappingListener> listeners = new ConcurrentHashSet<>();
+
+ private static final int PAGINATION_SIZE = 100;
+
+ private NacosNamingServiceWrapper namingService;
+
+ private Set<String> anyServices = new HashSet<>();
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(NacosServiceMapping.class);
+
+ @Override
+ public void init(URL url) {
+ url.addParameter(NAMING_LOAD_CACHE_AT_START, "false");
+ namingService = NacosNamingServiceUtils.createNamingService(url);
+ scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
+ listenerAll();
+ }
+
+ @Override
+ public void listenerAll() {
+
+ try {
+ anyServices = getAllServiceNames();
+ } catch (Exception e) {
+ LOGGER.error("Get nacos all services fail ", e);
+ }
+ for (String service : anyServices) {
+ notifyMappingChangedEvent(service);
+ }
+ scheduledExecutorService.scheduleAtFixedRate(() -> {
+ try {
+ Set<String> serviceNames = getAllServiceNames();
+ for (String serviceName : serviceNames) {
+ if (anyServices.add(serviceName)) {
+ notifyMappingChangedEvent(serviceName);
+ }
+ }
+ } catch (Exception e) {
+ LOGGER.error("Get nacos all services fail ", e);
+ }
+
+ }, LOOKUP_INTERVAL, LOOKUP_INTERVAL, TimeUnit.SECONDS);
+ }
+
+ private Set<String> getAllServiceNames() throws NacosException {
+
+ Set<String> serviceNames = new HashSet<>();
+ int pageIndex = 1;
+ ListView<String> listView = namingService.getServicesOfServer(pageIndex, PAGINATION_SIZE,
+ Constants.DEFAULT_GROUP);
+ // First page data
+ List<String> firstPageData = listView.getData();
+ // Append first page into list
+ serviceNames.addAll(firstPageData);
+ // the total count
+ int count = listView.getCount();
+ // the number of pages
+ int pageNumbers = count / PAGINATION_SIZE;
+ int remainder = count % PAGINATION_SIZE;
+ // remain
+ if (remainder > 0) {
+ pageNumbers += 1;
+ }
+ // If more than 1 page
+ while (pageIndex < pageNumbers) {
+ listView = namingService.getServicesOfServer(++pageIndex, PAGINATION_SIZE, Constants.DEFAULT_GROUP);
+ serviceNames.addAll(listView.getData());
+ }
+
+ return serviceNames;
+ }
+
+ private void notifyMappingChangedEvent(String service) {
+ if (StringUtils.isBlank(service)) {
+ return;
+ }
+ for (String category : ALL_SUPPORTED_CATEGORIES) {
+ String prefix = category + SERVICE_NAME_SEPARATOR;
+ if (service.startsWith(prefix)) {
+ return;
+ }
+ }
+ MappingChangedEvent event = new MappingChangedEvent(null, Sets.newHashSet(service));
+ for (MappingListener listener : listeners) {
+ listener.onEvent(event);
+ }
+ }
+
+
+ @Override
+ public void addMappingListener(MappingListener listener) {
+ listeners.add(listener);
+ }
+
+}
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 dab1a43..475bb31 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
@@ -110,11 +110,11 @@ public class RegistryServerSync implements DisposableBean, NotifyListener {
String version = url.getUrlParam().getParameter(Constants.VERSION_KEY);
// NOTE: group and version in empty protocol is *
if (!Constants.ANY_VALUE.equals(group) && !Constants.ANY_VALUE.equals(version)) {
- services.remove(url.getServiceInterface());
+ services.remove(getServiceInterface(url));
} else {
for (Map.Entry<String, Map<String, URL>> serviceEntry : services.entrySet()) {
String service = serviceEntry.getKey();
- if (Tool.getInterface(service).equals(url.getServiceInterface())
+ if (Tool.getInterface(service).equals(getServiceInterface(url))
&& (Constants.ANY_VALUE.equals(group) || StringUtils.isEquals(group, Tool.getGroup(service)))
&& (Constants.ANY_VALUE.equals(version) || StringUtils.isEquals(version, Tool.getVersion(service)))) {
services.remove(service);
@@ -124,7 +124,7 @@ public class RegistryServerSync implements DisposableBean, NotifyListener {
}
} else {
if (StringUtils.isEmpty(interfaceName)) {
- interfaceName = url.getServiceInterface();
+ interfaceName = getServiceInterface(url);
}
Map<String, Map<String, URL>> services = categories.get(category);
if (services == null) {
@@ -133,7 +133,7 @@ public class RegistryServerSync implements DisposableBean, NotifyListener {
}
String group = url.getUrlParam().getParameter(Constants.GROUP_KEY);
String version = url.getUrlParam().getParameter(Constants.VERSION_KEY);
- String service = BaseServiceMetadata.buildServiceKey(url.getServiceInterface(), group, version);
+ String service = BaseServiceMetadata.buildServiceKey(getServiceInterface(url), group, version);
Map<String, URL> ids = services.get(service);
if (ids == null) {
ids = new HashMap<>();
@@ -170,5 +170,14 @@ public class RegistryServerSync implements DisposableBean, NotifyListener {
services.putAll(categoryEntry.getValue());
}
}
+
+ private String getServiceInterface(URL url) {
+ String serviceInterface = url.getServiceInterface();
+ if (StringUtils.isBlank(serviceInterface) || Constants.ANY_VALUE.equals(serviceInterface)) {
+ serviceInterface = url.getPath();
+ }
+ return serviceInterface;
+ }
+
}
diff --git a/dubbo-admin-server/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.admin.registry.mapping.ServiceMapping b/dubbo-admin-server/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.admin.registry.mapping.ServiceMapping
index 83709e7..90c6c4a 100644
--- a/dubbo-admin-server/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.admin.registry.mapping.ServiceMapping
+++ b/dubbo-admin-server/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.admin.registry.mapping.ServiceMapping
@@ -1 +1,2 @@
-zookeeper=org.apache.dubbo.admin.registry.mapping.impl.ZookeeperServiceMapping
\ No newline at end of file
+zookeeper=org.apache.dubbo.admin.registry.mapping.impl.ZookeeperServiceMapping
+nacos=org.apache.dubbo.admin.registry.mapping.impl.NacosServiceMapping
\ No newline at end of file