diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java index 3583b15f1cc..4ffe016d12b 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java @@ -352,7 +352,7 @@ public void checkConnectivity() { } }, reconnectTaskPeriod, TimeUnit.MILLISECONDS); } - MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary())); + MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta())); } /** @@ -366,7 +366,11 @@ public void refreshInvoker() { if (invokersInitialized) { refreshInvokerInternal(); } - MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary())); + MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta())); + } + + protected Map getDirectoryMeta() { + return Collections.emptyMap(); } private synchronized void refreshInvokerInternal() { @@ -395,7 +399,7 @@ public void addDisabledInvoker(Invoker invoker) { removeValidInvoker(invoker); logger.info("Disable service address: " + invoker.getUrl() + "."); } - MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary())); + MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta())); } @Override @@ -408,7 +412,7 @@ public void recoverDisabledInvoker(Invoker invoker) { } } - MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary())); + MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta())); } protected final void refreshRouter(BitList> newlyInvokers, Runnable switchAction) { @@ -465,7 +469,7 @@ protected void setInvokers(BitList> invokers) { refreshInvokerInternal(); this.invokersInitialized = true; - MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary())); + MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta())); } protected void destroyInvokers() { @@ -480,7 +484,7 @@ private boolean addValidInvoker(Invoker invoker) { synchronized (this.validInvokers) { result = this.validInvokers.add(invoker); } - MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary())); + MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta())); return result; } @@ -489,7 +493,7 @@ private boolean removeValidInvoker(Invoker invoker) { synchronized (this.validInvokers) { result = this.validInvokers.remove(invoker); } - MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary())); + MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta())); return result; } @@ -519,18 +523,7 @@ private Map> getSummary() { } private Map groupByServiceKey(Collection> invokers) { - - Map serviceNumMap = new HashMap<>(); - for (Invoker invoker : invokers) { - if (invoker.getClass().getSimpleName().contains("Mockito")) { - return serviceNumMap; - } - } - if (invokers.size() > 0) { - serviceNumMap = invokers.stream().filter(invoker -> invoker.getInterface() != null).collect(Collectors.groupingBy(invoker -> invoker.getInterface().getName(), Collectors.reducing(0, e -> 1, Integer::sum))); - } - - return serviceNumMap; + return Collections.singletonMap(getConsumerUrl().getServiceKey(), invokers.size()); } @Override diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/StaticDirectory.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/StaticDirectory.java index 36e3d3eb59b..d5ec1e512b8 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/StaticDirectory.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/StaticDirectory.java @@ -27,9 +27,12 @@ import org.apache.dubbo.rpc.cluster.SingleRouterChain; import org.apache.dubbo.rpc.cluster.router.state.BitList; +import java.util.Collections; import java.util.List; +import java.util.Map; import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_FAILED_SITE_SELECTION; +import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_KEY; /** * StaticDirectory @@ -125,4 +128,8 @@ protected List> doList(SingleRouterChain singleRouterChain, BitLis return invokers; } + @Override + protected Map getDirectoryMeta() { + return Collections.singletonMap(REGISTRY_KEY, "static"); + } } diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/support/MetricsClusterFilter.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/support/MetricsClusterFilter.java index 03c90185171..56342023847 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/support/MetricsClusterFilter.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/support/MetricsClusterFilter.java @@ -22,7 +22,7 @@ import org.apache.dubbo.metrics.collector.DefaultMetricsCollector; import org.apache.dubbo.metrics.event.MetricsDispatcher; import org.apache.dubbo.metrics.event.MetricsEventBus; -import org.apache.dubbo.metrics.event.RequestBeforeEvent; +import org.apache.dubbo.metrics.event.RequestEvent; import org.apache.dubbo.rpc.BaseFilter; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; @@ -73,7 +73,7 @@ private void handleMethodException(Throwable t, Invocation invocation) { if (t instanceof RpcException) { RpcException e = (RpcException) t; if (e.isForbidden()) { - MetricsEventBus.publish(RequestBeforeEvent.toEvent(applicationModel, appName, metricsDispatcher, invocation, CONSUMER_SIDE)); + MetricsEventBus.publish(RequestEvent.toRequestErrorEvent(applicationModel, appName, metricsDispatcher, invocation, CONSUMER_SIDE, e.getCode())); } } } 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 134cd349953..88d687c5040 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 @@ -241,6 +241,8 @@ public interface CommonConstants { String INTERFACE_REGISTER_MODE = "interface"; + String INSTANCE_REGISTER_MODE = "instance"; + String DEFAULT_REGISTER_MODE = "all"; String GENERIC_KEY = "generic"; @@ -642,4 +644,5 @@ public interface CommonConstants { String SERVICE_DEPLOYER_ATTRIBUTE_KEY = "serviceDeployer"; String RESTEASY_NETTY_HTTP_REQUEST_ATTRIBUTE_KEY = "resteasyNettyHttpRequest"; + String DUBBO_MANUAL_REGISTER_KEY = "dubbo.application.manual-register"; } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/logger/log4j2/Log4j2LoggerAdapter.java b/dubbo-common/src/main/java/org/apache/dubbo/common/logger/log4j2/Log4j2LoggerAdapter.java index 0a74a637399..c8f25d59e52 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/logger/log4j2/Log4j2LoggerAdapter.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/logger/log4j2/Log4j2LoggerAdapter.java @@ -21,6 +21,7 @@ import org.apache.dubbo.common.logger.LoggerAdapter; import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.core.config.Configurator; import java.io.File; @@ -30,6 +31,12 @@ public class Log4j2LoggerAdapter implements LoggerAdapter { private Level level; public Log4j2LoggerAdapter() { + try { + org.apache.logging.log4j.Logger logger = LogManager.getRootLogger(); + this.level = fromLog4j2Level(logger.getLevel()); + } catch (Exception t) { + // ignore + } } private static org.apache.logging.log4j.Level toLog4j2Level(Level level) { @@ -94,6 +101,7 @@ public Level getLevel() { @Override public void setLevel(Level level) { this.level = level; + Configurator.setLevel(LogManager.getRootLogger(), toLog4j2Level(level)); } @Override diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/logger/slf4j/Slf4jLogger.java b/dubbo-common/src/main/java/org/apache/dubbo/common/logger/slf4j/Slf4jLogger.java index d212cb183d7..592c1a6717e 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/logger/slf4j/Slf4jLogger.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/logger/slf4j/Slf4jLogger.java @@ -16,6 +16,7 @@ */ package org.apache.dubbo.common.logger.slf4j; +import org.apache.dubbo.common.logger.Level; import org.apache.dubbo.common.logger.Logger; import org.apache.dubbo.common.logger.support.FailsafeLogger; @@ -198,4 +199,27 @@ public boolean isErrorEnabled() { return logger.isErrorEnabled(); } + public static Level getLevel(org.slf4j.Logger logger) { + if (logger.isTraceEnabled()) { + return Level.TRACE; + } + if (logger.isDebugEnabled()) { + return Level.DEBUG; + } + if (logger.isInfoEnabled()) { + return Level.INFO; + } + if (logger.isWarnEnabled()) { + return Level.WARN; + } + if (logger.isErrorEnabled()) { + return Level.ERROR; + } + return Level.OFF; + } + + public Level getLevel() { + return getLevel(logger); + } + } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/logger/slf4j/Slf4jLoggerAdapter.java b/dubbo-common/src/main/java/org/apache/dubbo/common/logger/slf4j/Slf4jLoggerAdapter.java index 1f56242ddae..47f4c170c39 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/logger/slf4j/Slf4jLoggerAdapter.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/logger/slf4j/Slf4jLoggerAdapter.java @@ -20,14 +20,21 @@ import org.apache.dubbo.common.logger.Logger; import org.apache.dubbo.common.logger.LoggerAdapter; import org.apache.dubbo.common.utils.ClassUtils; - +import org.slf4j.LoggerFactory; import java.io.File; public class Slf4jLoggerAdapter implements LoggerAdapter { public static final String NAME = "slf4j"; + private Level level; private File file; + private static final org.slf4j.Logger ROOT_LOGGER = LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME); + + public Slf4jLoggerAdapter() { + this.level = Slf4jLogger.getLevel(ROOT_LOGGER); + } + @Override public Logger getLogger(String key) { return new Slf4jLogger(org.slf4j.LoggerFactory.getLogger(key)); @@ -45,6 +52,7 @@ public Level getLevel() { @Override public void setLevel(Level level) { + System.err.printf("The level of slf4j logger current can not be set, using the default level: %s \n", Slf4jLogger.getLevel(ROOT_LOGGER)); this.level = level; } 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 98aab862d28..697c3eee518 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 @@ -38,8 +38,6 @@ import org.apache.dubbo.config.support.Parameter; import org.apache.dubbo.config.utils.ConfigValidationUtils; import org.apache.dubbo.metadata.ServiceNameMapping; -import org.apache.dubbo.metrics.event.MetricsEventBus; -import org.apache.dubbo.metrics.registry.event.RegistryEvent; import org.apache.dubbo.registry.client.metadata.MetadataUtils; import org.apache.dubbo.rpc.Exporter; import org.apache.dubbo.rpc.Invoker; @@ -310,7 +308,9 @@ public void export(RegisterTypeEnum registerType) { if (shouldDelay()) { // should register if delay export doDelayExport(); - } else if (Integer.valueOf(-1).equals(getDelay())) { + } else if (Integer.valueOf(-1).equals(getDelay()) && + Boolean.parseBoolean(ConfigurationUtils.getProperty( + getScopeModel(), CommonConstants.DUBBO_MANUAL_REGISTER_KEY, "false"))) { // should not register by default doExport(RegisterTypeEnum.MANUAL_REGISTER); } else { @@ -514,21 +514,17 @@ private void doExportUrls(RegisterTypeEnum registerType) { List registryURLs = ConfigValidationUtils.loadRegistries(this, true); - MetricsEventBus.post(RegistryEvent.toRsEvent(getApplicationModel(), getUniqueServiceName(), protocols.size() * registryURLs.size()), () -> { - for (ProtocolConfig protocolConfig : protocols) { - String pathKey = URL.buildKey(getContextPath(protocolConfig) - .map(p -> p + "/" + path) - .orElse(path), group, version); - // stub service will use generated service name - if (!serverService) { - // In case user specified path, registerImmediately service one more time to map it to path. - repository.registerService(pathKey, interfaceClass); - } - doExportUrlsFor1Protocol(protocolConfig, registryURLs, registerType); - } - return null; + for (ProtocolConfig protocolConfig : protocols) { + String pathKey = URL.buildKey(getContextPath(protocolConfig) + .map(p -> p + "/" + path) + .orElse(path), group, version); + // stub service will use generated service name + if (!serverService) { + // In case user specified path, register service one more time to map it to path. + repository.registerService(pathKey, interfaceClass); } - ); + doExportUrlsFor1Protocol(protocolConfig, registryURLs, registerType); + } providerModel.setServiceUrls(urls); } diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java index ac012ee3d5f..b075acaa448 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java @@ -55,7 +55,6 @@ import org.apache.dubbo.metrics.collector.DefaultMetricsCollector; import org.apache.dubbo.metrics.config.event.ConfigCenterEvent; import org.apache.dubbo.metrics.event.MetricsEventBus; -import org.apache.dubbo.metrics.registry.event.RegistryEvent; import org.apache.dubbo.metrics.report.DefaultMetricsReporterFactory; import org.apache.dubbo.metrics.report.MetricsReporter; import org.apache.dubbo.metrics.report.MetricsReporterFactory; @@ -899,16 +898,10 @@ private DynamicConfiguration getDynamicConfiguration(URL connectionURL) { private void registerServiceInstance() { try { registered = true; - MetricsEventBus.post(RegistryEvent.toRegisterEvent(applicationModel), - () -> { - ServiceInstanceMetadataUtils.registerMetadataAndInstance(applicationModel); - return null; - } - ); + ServiceInstanceMetadataUtils.registerMetadataAndInstance(applicationModel); } catch (Exception e) { logger.error(CONFIG_REGISTER_INSTANCE_ERROR, "configuration server disconnected", "", "Register instance error.", e); } - if (registered) { // scheduled task for updating Metadata and ServiceInstance asyncMetadataFuture = frameworkExecutorRepository.getSharedScheduledExecutor().scheduleWithFixedDelay(() -> { diff --git a/dubbo-config/dubbo-config-spring/pom.xml b/dubbo-config/dubbo-config-spring/pom.xml index c31bc83698e..bece9fde05c 100644 --- a/dubbo-config/dubbo-config-spring/pom.xml +++ b/dubbo-config/dubbo-config-spring/pom.xml @@ -27,7 +27,7 @@ The spring config module of dubbo project false - 2.7.13 + 2.7.14 diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboInfraBeanRegisterPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboInfraBeanRegisterPostProcessor.java index fcd759578e6..b54b506e551 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboInfraBeanRegisterPostProcessor.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboInfraBeanRegisterPostProcessor.java @@ -85,7 +85,7 @@ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) // Extract dubbo props from Spring env and put them to app config ConfigurableEnvironment environment = (ConfigurableEnvironment) applicationContext.getEnvironment(); SortedMap dubboProperties = EnvironmentUtils.filterDubboProperties(environment); - applicationModel.modelEnvironment().setAppConfigMap(dubboProperties); + applicationModel.modelEnvironment().getAppConfigMap().putAll(dubboProperties); // register ConfigManager singleton beanFactory.registerSingleton(ConfigManager.BEAN_NAME, applicationModel.getApplicationConfigManager()); diff --git a/dubbo-demo/dubbo-demo-annotation/pom.xml b/dubbo-demo/dubbo-demo-annotation/pom.xml index ea1af4ed9f5..8e46e0d3c03 100644 --- a/dubbo-demo/dubbo-demo-annotation/pom.xml +++ b/dubbo-demo/dubbo-demo-annotation/pom.xml @@ -30,7 +30,7 @@ true - 2.7.13 + 2.7.14 diff --git a/dubbo-demo/dubbo-demo-api/pom.xml b/dubbo-demo/dubbo-demo-api/pom.xml index 270d23969d6..6b59e1a693d 100644 --- a/dubbo-demo/dubbo-demo-api/pom.xml +++ b/dubbo-demo/dubbo-demo-api/pom.xml @@ -36,7 +36,7 @@ true - 2.7.13 + 2.7.14 dubbo-demo-api diff --git a/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-consumer/pom.xml b/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-consumer/pom.xml index c639ab7319c..ec7a066aa87 100644 --- a/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-consumer/pom.xml +++ b/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-consumer/pom.xml @@ -31,7 +31,7 @@ 8 8 1.7.33 - 2.7.13 + 2.7.14 true diff --git a/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-provider/pom.xml b/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-provider/pom.xml index 8fb88bc394d..ea0dfd62356 100644 --- a/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-provider/pom.xml +++ b/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-provider/pom.xml @@ -31,7 +31,7 @@ 8 8 1.7.33 - 2.7.13 + 2.7.14 true diff --git a/dubbo-demo/dubbo-demo-spring-boot/pom.xml b/dubbo-demo/dubbo-demo-spring-boot/pom.xml index 2c2a9645657..9170101e54b 100644 --- a/dubbo-demo/dubbo-demo-spring-boot/pom.xml +++ b/dubbo-demo/dubbo-demo-spring-boot/pom.xml @@ -36,9 +36,9 @@ 8 8 true - 2.7.13 - 2.7.13 - 1.11.1 + 2.7.14 + 2.7.14 + 1.11.2 diff --git a/dubbo-demo/dubbo-demo-xml/pom.xml b/dubbo-demo/dubbo-demo-xml/pom.xml index 6115b3c7696..aee62543729 100644 --- a/dubbo-demo/dubbo-demo-xml/pom.xml +++ b/dubbo-demo/dubbo-demo-xml/pom.xml @@ -32,7 +32,7 @@ true - 2.7.13 + 2.7.14 diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index f4479f8fab0..b5764a91a39 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -92,11 +92,11 @@ 5.3.25 - 5.8.4 + 5.8.5 3.29.2-GA 1.14.5 3.2.10.Final - 4.1.94.Final + 4.1.95.Final 2.2.1 2.4.4 4.5.14 @@ -133,13 +133,13 @@ 3.12.0 1.8.0 0.1.35 - 1.11.1 + 1.11.2 - 1.1.2 + 1.1.3 3.3 0.16.0 1.0.4 - 3.5.7 + 3.5.8 2.2.21 3.14.9 @@ -147,7 +147,7 @@ 3.15.6.Final 1.9.13 8.5.87 - 0.7.5 + 0.7.6 2.2.4 1.56.1 0.8.1 @@ -175,17 +175,16 @@ 2.2.7 1.2.0 1.18.3 - 0.7.5 + 0.7.6 3.2.13 1.6.11 - 1.1.10.1 + 1.1.10.3 1.70 2.0.6 5.4.3 2.10.1 2.15.2 - 1.6 6.1.26 2.0 1.5.0 @@ -771,11 +770,6 @@ jackson-datatype-jsr310 ${jackson_version} - - com.github.briandilley.jsonrpc4j - jsonrpc4j - ${jsonrpc_version} - javax.portlet portlet-api diff --git a/dubbo-metadata/dubbo-metadata-definition-protobuf/src/main/java/org/apache/dubbo/metadata/definition/protobuf/ProtobufTypeBuilder.java b/dubbo-metadata/dubbo-metadata-definition-protobuf/src/main/java/org/apache/dubbo/metadata/definition/protobuf/ProtobufTypeBuilder.java index 2f5640ad3b6..a6b4850ad6c 100644 --- a/dubbo-metadata/dubbo-metadata-definition-protobuf/src/main/java/org/apache/dubbo/metadata/definition/protobuf/ProtobufTypeBuilder.java +++ b/dubbo-metadata/dubbo-metadata-definition-protobuf/src/main/java/org/apache/dubbo/metadata/definition/protobuf/ProtobufTypeBuilder.java @@ -16,6 +16,7 @@ */ package org.apache.dubbo.metadata.definition.protobuf; +import org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.common.lang.Prioritized; import org.apache.dubbo.common.logger.Logger; import org.apache.dubbo.common.logger.LoggerFactory; @@ -37,6 +38,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +@Activate(onClass = "com.google.protobuf.GeneratedMessageV3") public class ProtobufTypeBuilder implements TypeBuilder, Prioritized { private final Logger logger = LoggerFactory.getLogger(getClass()); private static final Pattern MAP_PATTERN = Pattern.compile("^java\\.util\\.Map<(\\S+), (\\S+)>$"); @@ -258,11 +260,7 @@ private boolean isSimplePropertySettingMethod(Method method) { // Enum property has two setting method. // skip setXXXValue(int value) // parse setXXX(SomeEnum value) - if (methodName.endsWith("Value") && types[0] == int.class) { - return false; - } - - return true; + return !methodName.endsWith("Value") || types[0] != int.class; } @@ -289,11 +287,7 @@ boolean isListPropertyGettingMethod(Method method) { } // if field name end with List, should skip - if (!List.class.isAssignableFrom(type)) { - return false; - } - - return true; + return List.class.isAssignableFrom(type); } /** @@ -307,10 +301,6 @@ boolean isListPropertyGettingMethod(Method method) { private boolean isMapPropertySettingMethod(Method methodTemp) { String methodName = methodTemp.getName(); Class[] parameters = methodTemp.getParameterTypes(); - if (methodName.startsWith("putAll") && parameters.length == 1 && Map.class.isAssignableFrom(parameters[0])) { - return true; - } - - return false; + return methodName.startsWith("putAll") && parameters.length == 1 && Map.class.isAssignableFrom(parameters[0]); } } diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/MetricsConstants.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/MetricsConstants.java index a99e4c6657a..232de1fa59a 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/MetricsConstants.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/MetricsConstants.java @@ -22,8 +22,8 @@ public interface MetricsConstants { String INVOCATION = "metric_filter_invocation"; String METHOD_METRICS = "metric_filter_method_metrics"; String INVOCATION_METRICS_COUNTER = "metric_filter_invocation_counter"; - String INVOCATION_SIDE = "metric_filter_side"; + String INVOCATION_REQUEST_ERROR = "metric_request_error"; String ATTACHMENT_KEY_SERVICE = "serviceKey"; String ATTACHMENT_KEY_SIZE = "size"; diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/CombMetricsCollector.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/CombMetricsCollector.java index 81ae03eb40c..66fb5f2aeeb 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/CombMetricsCollector.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/CombMetricsCollector.java @@ -34,7 +34,7 @@ public abstract class CombMetricsCollector extends AbstractMetricsListener implements ApplicationMetricsCollector, ServiceMetricsCollector, MethodMetricsCollector { - private final BaseStatComposite stats; + protected final BaseStatComposite stats; private MetricsEventMulticaster eventMulticaster; @@ -108,5 +108,9 @@ public void onEventFinish(TimeCounterEvent event) { public void onEventError(TimeCounterEvent event) { eventMulticaster.publishErrorEvent(event); } + + protected BaseStatComposite getStats() { + return stats; + } } diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/data/BaseStatComposite.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/data/BaseStatComposite.java index c7ddd9dee02..ef987e7e15d 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/data/BaseStatComposite.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/data/BaseStatComposite.java @@ -18,8 +18,10 @@ package org.apache.dubbo.metrics.data; import org.apache.dubbo.metrics.collector.MetricsCollector; +import org.apache.dubbo.metrics.model.ApplicationMetric; import org.apache.dubbo.metrics.model.MethodMetric; import org.apache.dubbo.metrics.model.MetricsCategory; +import org.apache.dubbo.metrics.model.ServiceKeyMetric; import org.apache.dubbo.metrics.model.key.MetricsKey; import org.apache.dubbo.metrics.model.key.MetricsKeyWrapper; import org.apache.dubbo.metrics.model.sample.MetricSample; @@ -29,6 +31,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Map; /** @@ -70,11 +73,11 @@ protected void init(RtStatComposite rtStatComposite) { } public void calcApplicationRt(String registryOpType, Long responseTime) { - rtStatComposite.calcApplicationRt(registryOpType, responseTime); + rtStatComposite.calcServiceKeyRt(registryOpType, responseTime, new ApplicationMetric(rtStatComposite.getApplicationModel())); } public void calcServiceKeyRt(String serviceKey, String registryOpType, Long responseTime) { - rtStatComposite.calcServiceKeyRt(serviceKey, registryOpType, responseTime); + rtStatComposite.calcServiceKeyRt(registryOpType, responseTime, new ServiceKeyMetric(rtStatComposite.getApplicationModel(), serviceKey)); } public void calcServiceKeyRt(Invocation invocation, String registryOpType, Long responseTime) { @@ -89,6 +92,10 @@ public void setServiceKey(MetricsKeyWrapper metricsKey, String serviceKey, int n serviceStatComposite.setServiceKey(metricsKey, serviceKey, num); } + public void setServiceKey(MetricsKeyWrapper metricsKey, String serviceKey, int num, Map extra) { + serviceStatComposite.setExtraServiceKey(metricsKey, serviceKey, num, extra); + } + public void incrementApp(MetricsKey metricsKey, int size) { applicationStatComposite.incrementSize(metricsKey, size); } @@ -97,6 +104,10 @@ public void incrementServiceKey(MetricsKeyWrapper metricsKeyWrapper, String attS serviceStatComposite.incrementServiceKey(metricsKeyWrapper, attServiceKey, size); } + public void incrementServiceKey(MetricsKeyWrapper metricsKeyWrapper, String attServiceKey, Map extra, int size) { + serviceStatComposite.incrementExtraServiceKey(metricsKeyWrapper, attServiceKey, extra, size); + } + public void incrementMethodKey(MetricsKeyWrapper metricsKeyWrapper, MethodMetric methodMetric, int size) { methodStatComposite.incrementMethodKey(metricsKeyWrapper, methodMetric, size); } diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/data/RtStatComposite.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/data/RtStatComposite.java index 5a3d96c9b35..e6d0bae6e7a 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/data/RtStatComposite.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/data/RtStatComposite.java @@ -17,7 +17,6 @@ package org.apache.dubbo.metrics.data; -import org.apache.dubbo.metrics.model.ApplicationMetric; import org.apache.dubbo.metrics.model.MethodMetric; import org.apache.dubbo.metrics.model.Metric; import org.apache.dubbo.metrics.model.MetricsCategory; @@ -89,20 +88,7 @@ private List> initStats(MetricsPlaceValue placeV return singleRtStats; } - public void calcApplicationRt(String registryOpType, Long responseTime) { - ApplicationMetric key = new ApplicationMetric(getApplicationModel()); - for (LongContainer container : rtStats.get(registryOpType)) { - Number current = (Number) container.get(key); - if (current == null) { - container.putIfAbsent(key, container.getInitFunc().apply(key)); - current = (Number) container.get(key); - } - container.getConsumerFunc().accept(responseTime, current); - } - } - - public void calcServiceKeyRt(String serviceKey, String registryOpType, Long responseTime) { - ServiceKeyMetric key = new ServiceKeyMetric(getApplicationModel(), serviceKey); + public void calcServiceKeyRt(String registryOpType, Long responseTime, Metric key) { for (LongContainer container : rtStats.get(registryOpType)) { Number current = (Number) container.get(key); if (current == null) { diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/data/ServiceStatComposite.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/data/ServiceStatComposite.java index 3399541c424..afedd716417 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/data/ServiceStatComposite.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/data/ServiceStatComposite.java @@ -53,21 +53,37 @@ public void initWrapper(List metricsKeyWrappers) { } public void incrementServiceKey(MetricsKeyWrapper wrapper, String serviceKey, int size) { + incrementExtraServiceKey(wrapper, serviceKey, null, size); + } + + public void incrementExtraServiceKey(MetricsKeyWrapper wrapper, String serviceKey, Map extra, int size) { if (!serviceWrapperNumStats.containsKey(wrapper)) { return; } - serviceWrapperNumStats.get(wrapper).computeIfAbsent(new ServiceKeyMetric(getApplicationModel(), serviceKey), k -> new AtomicLong(0L)).getAndAdd(size); + ServiceKeyMetric serviceKeyMetric = new ServiceKeyMetric(getApplicationModel(), serviceKey); + if (extra != null) { + serviceKeyMetric.setExtraInfo(extra); + } + serviceWrapperNumStats.get(wrapper).computeIfAbsent(serviceKeyMetric, k -> new AtomicLong(0L)).getAndAdd(size); // MetricsSupport.fillZero(serviceWrapperNumStats); } public void setServiceKey(MetricsKeyWrapper wrapper, String serviceKey, int num) { + setExtraServiceKey(wrapper, serviceKey, num, null); + } + + public void setExtraServiceKey(MetricsKeyWrapper wrapper, String serviceKey, int num, Map extra) { if (!serviceWrapperNumStats.containsKey(wrapper)) { return; } - serviceWrapperNumStats.get(wrapper).computeIfAbsent(new ServiceKeyMetric(getApplicationModel(), serviceKey), k -> new AtomicLong(0L)).set(num); -// MetricsSupport.fillZero(serviceWrapperNumStats); + ServiceKeyMetric serviceKeyMetric = new ServiceKeyMetric(getApplicationModel(), serviceKey); + if (extra != null) { + serviceKeyMetric.setExtraInfo(extra); + } + serviceWrapperNumStats.get(wrapper).computeIfAbsent(serviceKeyMetric, k -> new AtomicLong(0L)).set(num); } + @Override public List export(MetricsCategory category) { List list = new ArrayList<>(); for (MetricsKeyWrapper wrapper : serviceWrapperNumStats.keySet()) { diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEvent.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEvent.java index 4203d81a637..3b22dfa818b 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEvent.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEvent.java @@ -23,6 +23,7 @@ import org.apache.dubbo.metrics.model.key.TypeWrapper; import org.apache.dubbo.rpc.model.ApplicationModel; +import java.util.Collections; import java.util.IdentityHashMap; import java.util.Map; @@ -40,7 +41,7 @@ public abstract class MetricsEvent { private final String appName; private final MetricsDispatcher metricsDispatcher; - private final Map attachment = new IdentityHashMap<>(8); + private final Map attachments = new IdentityHashMap<>(8); public MetricsEvent(ApplicationModel source, TypeWrapper typeWrapper) { this(source, null, null, typeWrapper); @@ -82,11 +83,19 @@ public T getAttachmentValue(String key) { if (key == null) { throw new MetricsNeverHappenException("Attachment key is null"); } - return (T) attachment.get(key); + return (T) attachments.get(key); + } + + public Map getAttachments() { + return Collections.unmodifiableMap(attachments); } public void putAttachment(String key, Object value) { - attachment.put(key, value); + attachments.put(key, value); + } + + public void putAttachments(Map attachments) { + this.attachments.putAll(attachments); } public void setAvailable(boolean available) { diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEventBus.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEventBus.java index 6c514bafdab..8757454e025 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEventBus.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEventBus.java @@ -17,15 +17,22 @@ package org.apache.dubbo.metrics.event; +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; + import java.util.Optional; import java.util.function.Function; import java.util.function.Supplier; +import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_METRICS_COLLECTOR_EXCEPTION; + /** * Dispatches events to listeners, and provides ways for listeners to register themselves. */ public class MetricsEventBus { + private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(MetricsEventBus.class); + /** * Posts an event to all registered subscribers and only once. * @@ -63,27 +70,46 @@ public static T post(MetricsEvent event, Supplier targetSupplier) { */ public static T post(MetricsEvent event, Supplier targetSupplier, Function trFunction) { T result; - before(event); + tryInvoke(() -> { + before(event); + }); if (trFunction == null) { try { result = targetSupplier.get(); } catch (Throwable e) { - error(event); + tryInvoke(() -> { + error(event); + }); throw e; } - after(event, result); + tryInvoke(() -> { + after(event, result); + }); } else { // Custom failure status result = targetSupplier.get(); if (trFunction.apply(result)) { - after(event, result); + tryInvoke(() -> { + after(event, result); + }); } else { - error(event); + tryInvoke(() -> { + error(event); + }); } } return result; } + public static void tryInvoke(Runnable runnable) { + try { + runnable.run(); + } catch (Throwable e) { + logger.warn(COMMON_METRICS_COLLECTOR_EXCEPTION, "" + + "", "", "invoke metric event error" + e.getMessage()); + } + } + /** * Applicable to the scene where execution and return are separated, * eventSaveRunner saves the event, so that the calculation rt is introverted diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/AbstractMetricsKeyListener.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/AbstractMetricsKeyListener.java index 04c18f52635..2ba791e0e1f 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/AbstractMetricsKeyListener.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/AbstractMetricsKeyListener.java @@ -27,6 +27,7 @@ /** * According to the event template of {@link MetricsEventBus}, * build a consistent static method for general and custom monitoring consume methods + * */ public abstract class AbstractMetricsKeyListener extends AbstractMetricsListener implements MetricsLifeListener { diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/AbstractMetricsListener.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/AbstractMetricsListener.java index 63ac20b8778..0a3b9e65f9a 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/AbstractMetricsListener.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/AbstractMetricsListener.java @@ -28,7 +28,7 @@ public abstract class AbstractMetricsListener implements private final Map eventMatchCache = new ConcurrentHashMap<>(); /** - * Whether to support the general determination of event points depends on the event type + * Only interested in events of the current listener's generic parameter type */ public boolean isSupport(MetricsEvent event) { Boolean eventMatch = eventMatchCache.get(System.identityHashCode(event.getClass())); diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsApplicationListener.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsApplicationListener.java index 57d52ccb29b..96891e6bb02 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsApplicationListener.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsApplicationListener.java @@ -21,19 +21,37 @@ import org.apache.dubbo.metrics.model.key.MetricsKey; import org.apache.dubbo.metrics.model.key.MetricsPlaceValue; +/** + * App-level listener type, in most cases, can use the static method + * to produce an anonymous listener for general monitoring + */ public class MetricsApplicationListener extends AbstractMetricsKeyListener { public MetricsApplicationListener(MetricsKey metricsKey) { super(metricsKey); } - public static AbstractMetricsKeyListener onPostEventBuild(MetricsKey metricsKey, CombMetricsCollector collector) { + /** + * Perform auto-increment on the monitored key, + * Can use a custom listener instead of this generic operation + * + * @param metricsKey Monitor key + * @param collector Corresponding collector + */ + public static AbstractMetricsKeyListener onPostEventBuild(MetricsKey metricsKey, CombMetricsCollector collector) { return AbstractMetricsKeyListener.onEvent(metricsKey, - event -> collector.increment(metricsKey) + event -> collector.increment(metricsKey) ); } - public static AbstractMetricsKeyListener onFinishEventBuild(MetricsKey metricsKey, MetricsPlaceValue placeType, CombMetricsCollector collector) { + /** + * To end the monitoring normally, in addition to increasing the number of corresponding indicators, + * use the introspection method to calculate the relevant rt indicators + * + * @param metricsKey Monitor key + * @param collector Corresponding collector + */ + public static AbstractMetricsKeyListener onFinishEventBuild(MetricsKey metricsKey, MetricsPlaceValue placeType, CombMetricsCollector collector) { return AbstractMetricsKeyListener.onFinish(metricsKey, event -> { collector.increment(metricsKey); @@ -42,7 +60,10 @@ public static AbstractMetricsKeyListener onFinishEventBuild(MetricsKey metricsKe ); } - public static AbstractMetricsKeyListener onErrorEventBuild(MetricsKey metricsKey, MetricsPlaceValue placeType, CombMetricsCollector collector) { + /** + * Similar to onFinishEventBuild + */ + public static AbstractMetricsKeyListener onErrorEventBuild(MetricsKey metricsKey, MetricsPlaceValue placeType, CombMetricsCollector collector) { return AbstractMetricsKeyListener.onError(metricsKey, event -> { collector.increment(metricsKey); diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsServiceListener.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsServiceListener.java index 18989d78b48..40f27b18ca3 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsServiceListener.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsServiceListener.java @@ -23,6 +23,11 @@ import org.apache.dubbo.metrics.model.key.MetricsKey; import org.apache.dubbo.metrics.model.key.MetricsPlaceValue; +/** + * Service-level listener type, in most cases, can use the static method + * to produce an anonymous listener for general monitoring. + * Similar to App-level + */ public class MetricsServiceListener extends AbstractMetricsKeyListener { public MetricsServiceListener(MetricsKey metricsKey) { diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/ApplicationMetric.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/ApplicationMetric.java index 6752139e89f..20d03ca523f 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/ApplicationMetric.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/ApplicationMetric.java @@ -17,25 +17,14 @@ package org.apache.dubbo.metrics.model; -import org.apache.dubbo.common.Version; -import org.apache.dubbo.metrics.model.key.MetricsKey; import org.apache.dubbo.rpc.model.ApplicationModel; -import java.util.HashMap; import java.util.Map; import java.util.Objects; -import static org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_NAME; -import static org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_VERSION_KEY; -import static org.apache.dubbo.common.constants.MetricsConstants.TAG_HOSTNAME; -import static org.apache.dubbo.common.constants.MetricsConstants.TAG_IP; -import static org.apache.dubbo.common.utils.NetUtils.getLocalHost; -import static org.apache.dubbo.common.utils.NetUtils.getLocalHostName; - public class ApplicationMetric implements Metric { private final ApplicationModel applicationModel; - private static final String version = Version.getVersion(); - private static final String commitId = Version.getLastCommitId(); + protected Map extraInfo; public ApplicationMetric(ApplicationModel applicationModel) { this.applicationModel = applicationModel; @@ -49,27 +38,29 @@ public String getApplicationName() { return getApplicationModel().getApplicationName(); } - public String getData() { - return version; - } - @Override public Map getTags() { - Map tags = new HashMap<>(); - tags.put(TAG_IP, getLocalHost()); - tags.put(TAG_HOSTNAME, getLocalHostName()); - tags.put(TAG_APPLICATION_NAME, getApplicationName()); - tags.put(TAG_APPLICATION_VERSION_KEY, version); - tags.put(MetricsKey.METADATA_GIT_COMMITID_METRIC.getName(), commitId); - return tags; + return MetricsSupport.applicationTags(applicationModel, getExtraInfo()); + } + + public Map getExtraInfo() { + return extraInfo; + } + + public void setExtraInfo(Map extraInfo) { + this.extraInfo = extraInfo; } @Override public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof ApplicationMetric)) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } ApplicationMetric that = (ApplicationMetric) o; - return Objects.equals(getApplicationName(), that.applicationModel.getApplicationName()); + return getApplicationName().equals(that.applicationModel.getApplicationName()) && Objects.equals(extraInfo, that.extraInfo); } private volatile int hashCode; @@ -77,8 +68,9 @@ public boolean equals(Object o) { @Override public int hashCode() { if (hashCode == 0) { - hashCode = Objects.hash(getApplicationName()); + hashCode = Objects.hash(getApplicationName(), extraInfo); } return hashCode; } + } diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsSupport.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsSupport.java index 034bcbea02a..404018dfb51 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsSupport.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsSupport.java @@ -18,12 +18,12 @@ package org.apache.dubbo.metrics.model; import org.apache.dubbo.common.Version; +import org.apache.dubbo.common.lang.Nullable; import org.apache.dubbo.common.utils.CollectionUtils; import org.apache.dubbo.metrics.collector.MethodMetricsCollector; import org.apache.dubbo.metrics.collector.ServiceMetricsCollector; import org.apache.dubbo.metrics.event.MetricsEvent; import org.apache.dubbo.metrics.event.TimeCounterEvent; -import org.apache.dubbo.metrics.exception.MetricsNeverHappenException; import org.apache.dubbo.metrics.model.key.MetricsKey; import org.apache.dubbo.metrics.model.key.MetricsKeyWrapper; import org.apache.dubbo.metrics.model.key.MetricsPlaceValue; @@ -62,6 +62,10 @@ public class MetricsSupport { private static final String commitId = Version.getLastCommitId(); public static Map applicationTags(ApplicationModel applicationModel) { + return applicationTags(applicationModel, null); + } + + public static Map applicationTags(ApplicationModel applicationModel, @Nullable Map extraInfo) { Map tags = new HashMap<>(); tags.put(TAG_IP, getLocalHost()); tags.put(TAG_HOSTNAME, getLocalHostName()); @@ -69,23 +73,18 @@ public static Map applicationTags(ApplicationModel applicationMo tags.put(TAG_APPLICATION_MODULE, applicationModel.getInternalId()); tags.put(TAG_APPLICATION_VERSION_KEY, version); tags.put(MetricsKey.METADATA_GIT_COMMITID_METRIC.getName(), commitId); + if (CollectionUtils.isNotEmptyMap(extraInfo)) { + tags.putAll(extraInfo); + } return tags; } - public static Map serviceTags(ApplicationModel applicationModel, String serviceKey) { - Map tags = applicationTags(applicationModel); + public static Map serviceTags(ApplicationModel applicationModel, String serviceKey, Map extraInfo) { + Map tags = applicationTags(applicationModel, extraInfo); tags.put(TAG_INTERFACE_KEY, serviceKey); return tags; } - public static Map methodTags(ApplicationModel applicationModel, String names) { - String[] keys = names.split("_"); - if (keys.length != 2) { - throw new MetricsNeverHappenException("Error names: " + names); - } - return methodTags(applicationModel, keys[0], keys[1]); - } - public static Map methodTags(ApplicationModel applicationModel, String serviceKey, String methodName) { Map tags = applicationTags(applicationModel); tags.put(TAG_INTERFACE_KEY, serviceKey); @@ -211,7 +210,6 @@ public static void incrAndAddRt(MetricsKey metricsKey, MetricsPlaceValue placeTy Invocation invocation = event.getAttachmentValue(INVOCATION); if (invocation != null) { collector.addServiceRt(invocation, placeType.getType(), event.getTimePair().calc()); - return; } else { collector.addServiceRt((String) event.getAttachmentValue(ATTACHMENT_KEY_SERVICE), placeType.getType(), event.getTimePair().calc()); } @@ -240,9 +238,9 @@ public static void incrAndAddRt(MetricsKey metricsKey, MetricsPlaceValue placeTy } /** - * Generate a complete indicator item for an interface/method + * Generate a complete indicator item for an interface/method */ - public static void fillZero(Map> data) { + public static void fillZero(Map> data) { if (CollectionUtils.isEmptyMap(data)) { return; } diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/ServiceKeyMetric.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/ServiceKeyMetric.java index 1b1d220ceab..361fd9f06e0 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/ServiceKeyMetric.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/ServiceKeyMetric.java @@ -35,7 +35,7 @@ public ServiceKeyMetric(ApplicationModel applicationModel, String serviceKey) { @Override public Map getTags() { - return MetricsSupport.serviceTags(getApplicationModel(), serviceKey); + return MetricsSupport.serviceTags(getApplicationModel(), serviceKey, getExtraInfo()); } public String getServiceKey() { @@ -47,16 +47,11 @@ public boolean equals(Object o) { if (this == o) { return true; } - if (o == null || getClass() != o.getClass()) { + if (!(o instanceof ServiceKeyMetric)) { return false; } - ServiceKeyMetric that = (ServiceKeyMetric) o; - - if (!getApplicationName().equals(that.getApplicationName())) { - return false; - } - return serviceKey.equals(that.serviceKey); + return serviceKey.equals(that.serviceKey) && Objects.equals(extraInfo, that.extraInfo); } @@ -65,7 +60,7 @@ public boolean equals(Object o) { @Override public int hashCode() { if (hashCode == 0) { - hashCode = Objects.hash(getApplicationName(), serviceKey); + hashCode = Objects.hash(getApplicationName(), serviceKey, extraInfo); } return hashCode; } diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/MetricsCat.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/MetricsCat.java index cf1c8134199..d085aa7ee98 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/MetricsCat.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/MetricsCat.java @@ -43,7 +43,7 @@ public MetricsCat(MetricsKey metricsKey, BiFunction tpFunc) { this.eventFunc = collector -> tpFunc.apply(metricsKey, placeType, collector); diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/MetricsKeyWrapper.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/MetricsKeyWrapper.java index 21bb7648e90..095cc5f3057 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/MetricsKeyWrapper.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/MetricsKeyWrapper.java @@ -18,11 +18,8 @@ package org.apache.dubbo.metrics.model.key; import io.micrometer.common.lang.Nullable; -import org.apache.dubbo.metrics.model.MetricsSupport; import org.apache.dubbo.metrics.model.sample.MetricSample; -import org.apache.dubbo.rpc.model.ApplicationModel; -import java.util.Map; import java.util.Objects; /** @@ -105,19 +102,6 @@ public String targetDesc() { } } - public Map tagName(ApplicationModel applicationModel, String key) { - MetricsLevel level = getLevel(); - switch (level) { - case APP: - return MetricsSupport.applicationTags(applicationModel); - case SERVICE: - return MetricsSupport.serviceTags(applicationModel, key); - case METHOD: - return MetricsSupport.methodTags(applicationModel, key); - } - return MetricsSupport.applicationTags(applicationModel); - } - public static MetricsKeyWrapper wrapper(MetricsKey metricsKey) { return new MetricsKeyWrapper(metricsKey, null); } diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/MetricsLevel.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/MetricsLevel.java index 783de999483..9a81e17ef8e 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/MetricsLevel.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/MetricsLevel.java @@ -18,5 +18,5 @@ package org.apache.dubbo.metrics.model.key; public enum MetricsLevel { - APP, SERVICE, METHOD, CONFIG + APP, SERVICE, METHOD, CONFIG, REGISTRY } diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollector.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollector.java index 4f669921604..7fbd4af06e6 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollector.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollector.java @@ -188,6 +188,9 @@ private MethodMetric calcWindowCounter(RequestEvent event, MetricsKey targetKey) @Override public List collect() { List list = new ArrayList<>(); + if (!isCollectEnabled()){ + return list; + } collectRequests(list); collectQPS(list); collectRT(list); diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/DefaultMetricsCollector.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/DefaultMetricsCollector.java index c4c3ef9ec02..45811417716 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/DefaultMetricsCollector.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/DefaultMetricsCollector.java @@ -29,7 +29,6 @@ import org.apache.dubbo.metrics.data.RtStatComposite; import org.apache.dubbo.metrics.event.DefaultSubDispatcher; import org.apache.dubbo.metrics.event.MetricsEvent; -import org.apache.dubbo.metrics.event.RequestBeforeEvent; import org.apache.dubbo.metrics.event.RequestEvent; import org.apache.dubbo.metrics.model.ApplicationMetric; import org.apache.dubbo.metrics.model.MetricsCategory; @@ -138,7 +137,7 @@ public List collect() { @Override public boolean isSupport(MetricsEvent event) { - return event instanceof RequestEvent || event instanceof RequestBeforeEvent; + return event instanceof RequestEvent; } public SimpleMetricsCountSampler applicationSampler = new SimpleMetricsCountSampler() { diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/event/DefaultSubDispatcher.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/event/DefaultSubDispatcher.java index 9894c67d113..807736709b6 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/event/DefaultSubDispatcher.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/event/DefaultSubDispatcher.java @@ -43,17 +43,16 @@ public DefaultSubDispatcher(DefaultMetricsCollector collector) { super.addListener(categoryOverall.getFinish().getEventFunc().apply(collector)); super.addListener(categoryOverall.getError().getEventFunc().apply(collector)); - super.addListener(new MetricsListener() { + super.addListener(new MetricsListener() { @Override public boolean isSupport(MetricsEvent event) { - return event instanceof RequestBeforeEvent; + return event instanceof RequestEvent && ((RequestEvent) event).isRequestErrorEvent(); } - private final MetricsPlaceValue dynamicPlaceType = MetricsPlaceValue.of(CommonConstants.CONSUMER, MetricsLevel.METHOD); @Override - public void onEvent(RequestBeforeEvent event) { + public void onEvent(RequestEvent event) { MetricsSupport.increment(METRIC_REQUESTS_SERVICE_UNAVAILABLE_FAILED, dynamicPlaceType, (MethodMetricsCollector) collector, event); } }); diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/event/RequestBeforeEvent.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/event/RequestBeforeEvent.java deleted file mode 100644 index 5b7d7c64da3..00000000000 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/event/RequestBeforeEvent.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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.metrics.event; - -import org.apache.dubbo.metrics.MetricsConstants; -import org.apache.dubbo.metrics.model.MethodMetric; -import org.apache.dubbo.metrics.model.MetricsSupport; -import org.apache.dubbo.metrics.model.key.MetricsKey; -import org.apache.dubbo.metrics.model.key.MetricsLevel; -import org.apache.dubbo.metrics.model.key.TypeWrapper; -import org.apache.dubbo.rpc.Invocation; -import org.apache.dubbo.rpc.model.ApplicationModel; - -import static org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_KEY_SERVICE; - -/** - * Acts on MetricsClusterFilter to monitor exceptions that occur before request execution - */ -public class RequestBeforeEvent extends TimeCounterEvent { - - public RequestBeforeEvent(ApplicationModel source, String appName, MetricsDispatcher metricsDispatcher, TypeWrapper typeWrapper) { - super(source, appName, metricsDispatcher, typeWrapper); - - } - - private static final TypeWrapper REQUEST_BEFORE_EVENT = new TypeWrapper(MetricsLevel.METHOD, MetricsKey.METRIC_REQUESTS); - public static RequestBeforeEvent toEvent(ApplicationModel applicationModel, String appName, MetricsDispatcher metricsDispatcher, Invocation invocation, String side) { - RequestBeforeEvent event = new RequestBeforeEvent(applicationModel, appName, metricsDispatcher, REQUEST_BEFORE_EVENT); - event.putAttachment(ATTACHMENT_KEY_SERVICE, MetricsSupport.getInterfaceName(invocation)); - event.putAttachment(MetricsConstants.INVOCATION_SIDE, side); - event.putAttachment(MetricsConstants.INVOCATION, invocation); - event.putAttachment(MetricsConstants.METHOD_METRICS, new MethodMetric(applicationModel, invocation)); - return event; - } - -} diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/event/RequestEvent.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/event/RequestEvent.java index acb0aad159f..93ad680df1c 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/event/RequestEvent.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/event/RequestEvent.java @@ -23,6 +23,7 @@ import org.apache.dubbo.metrics.exception.MetricsNeverHappenException; import org.apache.dubbo.metrics.model.MethodMetric; import org.apache.dubbo.metrics.model.MetricsSupport; +import org.apache.dubbo.metrics.model.key.MetricsKey; import org.apache.dubbo.metrics.model.key.MetricsLevel; import org.apache.dubbo.metrics.model.key.TypeWrapper; import org.apache.dubbo.rpc.Invocation; @@ -39,7 +40,8 @@ * Request related events */ public class RequestEvent extends TimeCounterEvent { - private static final TypeWrapper TYPE_WRAPPER = new TypeWrapper(MetricsLevel.SERVICE, METRIC_REQUESTS, METRIC_REQUESTS_SUCCEED, METRIC_REQUEST_BUSINESS_FAILED); + private static final TypeWrapper REQUEST_EVENT = new TypeWrapper(MetricsLevel.SERVICE, METRIC_REQUESTS, METRIC_REQUESTS_SUCCEED, METRIC_REQUEST_BUSINESS_FAILED); + private static final TypeWrapper REQUEST_ERROR_EVENT = new TypeWrapper(MetricsLevel.METHOD, MetricsKey.METRIC_REQUESTS); public RequestEvent(ApplicationModel applicationModel, String appName, MetricsDispatcher metricsDispatcher, DefaultMetricsCollector collector, TypeWrapper TYPE_WRAPPER) { super(applicationModel, appName, metricsDispatcher, TYPE_WRAPPER); @@ -56,7 +58,7 @@ public static RequestEvent toRequestEvent(ApplicationModel applicationModel, Str MetricsDispatcher metricsDispatcher, DefaultMetricsCollector collector, Invocation invocation, String side) { MethodMetric methodMetric = new MethodMetric(applicationModel, invocation); - RequestEvent requestEvent = new RequestEvent(applicationModel, appName, metricsDispatcher, collector, TYPE_WRAPPER); + RequestEvent requestEvent = new RequestEvent(applicationModel, appName, metricsDispatcher, collector, REQUEST_EVENT); requestEvent.putAttachment(MetricsConstants.INVOCATION, invocation); requestEvent.putAttachment(MetricsConstants.METHOD_METRICS, methodMetric); requestEvent.putAttachment(ATTACHMENT_KEY_SERVICE, MetricsSupport.getInterfaceName(invocation)); @@ -74,4 +76,21 @@ public void customAfterPost(Object postResult) { } super.putAttachment(METRIC_THROWABLE, ((Result) postResult).getException()); } + + /** + * Acts on MetricsClusterFilter to monitor exceptions that occur before request execution + */ + public static RequestEvent toRequestErrorEvent(ApplicationModel applicationModel, String appName, MetricsDispatcher metricsDispatcher, Invocation invocation, String side, int code) { + RequestEvent event = new RequestEvent(applicationModel, appName, metricsDispatcher, null, REQUEST_ERROR_EVENT); + event.putAttachment(ATTACHMENT_KEY_SERVICE, MetricsSupport.getInterfaceName(invocation)); + event.putAttachment(MetricsConstants.INVOCATION_SIDE, side); + event.putAttachment(MetricsConstants.INVOCATION, invocation); + event.putAttachment(MetricsConstants.INVOCATION_REQUEST_ERROR, code); + event.putAttachment(MetricsConstants.METHOD_METRICS, new MethodMetric(applicationModel, invocation)); + return event; + } + + public boolean isRequestErrorEvent(){ + return super.getAttachmentValue(MetricsConstants.INVOCATION_REQUEST_ERROR) != null; + } } diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/report/AbstractMetricsReporter.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/report/AbstractMetricsReporter.java index 3dfed9b4666..c6eb309b36e 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/report/AbstractMetricsReporter.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/report/AbstractMetricsReporter.java @@ -21,7 +21,6 @@ import io.micrometer.core.instrument.binder.MeterBinder; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.beans.factory.ScopeBeanFactory; -import org.apache.dubbo.common.constants.MetricsConstants; import org.apache.dubbo.common.lang.ShutdownHookCallbacks; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; @@ -38,7 +37,6 @@ import io.micrometer.core.instrument.Gauge; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Tag; -import io.micrometer.core.instrument.Tags; import io.micrometer.core.instrument.binder.jvm.ClassLoaderMetrics; import io.micrometer.core.instrument.binder.jvm.JvmGcMetrics; import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics; @@ -49,7 +47,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.Optional; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -112,21 +109,19 @@ protected ApplicationModel getApplicationModel() { private void addJvmMetrics() { boolean enableJvmMetrics = url.getParameter(ENABLE_JVM_METRICS_KEY, false); if (enableJvmMetrics) { - Tags extraTags = Tags.of(MetricsConstants.TAG_APPLICATION_NAME, - Optional.ofNullable(applicationModel.getApplicationName()).orElse("")); - new ClassLoaderMetrics(extraTags).bindTo(compositeRegistry); - new JvmMemoryMetrics(extraTags).bindTo(compositeRegistry); + new ClassLoaderMetrics().bindTo(compositeRegistry); + new JvmMemoryMetrics().bindTo(compositeRegistry); @SuppressWarnings("java:S2095") // Do not change JvmGcMetrics to try-with-resources as the JvmGcMetrics will not be available after (auto-)closing. // See https://github.com/micrometer-metrics/micrometer/issues/1492 - JvmGcMetrics jvmGcMetrics = new JvmGcMetrics(extraTags); + JvmGcMetrics jvmGcMetrics = new JvmGcMetrics(); jvmGcMetrics.bindTo(compositeRegistry); Runtime.getRuntime().addShutdownHook(new Thread(jvmGcMetrics::close)); - bindTo(new ProcessorMetrics(extraTags)); - new JvmThreadMetrics(extraTags).bindTo(compositeRegistry); - bindTo(new UptimeMetrics(extraTags)); + bindTo(new ProcessorMetrics()); + new JvmThreadMetrics().bindTo(compositeRegistry); + bindTo(new UptimeMetrics()); } } diff --git a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollectorTest.java b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollectorTest.java index a99be4735d1..652d335ab86 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollectorTest.java +++ b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollectorTest.java @@ -31,7 +31,6 @@ import org.apache.dubbo.metrics.aggregate.TimeWindowCounter; import org.apache.dubbo.metrics.event.MetricsDispatcher; import org.apache.dubbo.metrics.event.MetricsEventBus; -import org.apache.dubbo.metrics.event.RequestBeforeEvent; import org.apache.dubbo.metrics.event.RequestEvent; import org.apache.dubbo.metrics.filter.MetricsFilter; import org.apache.dubbo.metrics.listener.MetricsListener; @@ -143,9 +142,10 @@ public void setup() { void testListener() { AggregateMetricsCollector metricsCollector = new AggregateMetricsCollector(applicationModel); RequestEvent event = RequestEvent.toRequestEvent(applicationModel, null, null, null, invocation, MetricsSupport.getSide(invocation)); - RequestBeforeEvent beforeEvent = new RequestBeforeEvent(applicationModel, null, null, new TypeWrapper(MetricsLevel.METHOD, MetricsKey.METRIC_REQUESTS)); + RequestEvent beforeEvent = RequestEvent.toRequestErrorEvent(applicationModel, null, null, invocation, MetricsSupport.getSide(invocation), RpcException.FORBIDDEN_EXCEPTION); + Assertions.assertTrue(metricsCollector.isSupport(event)); - Assertions.assertFalse(metricsCollector.isSupport(beforeEvent)); + Assertions.assertTrue(metricsCollector.isSupport(beforeEvent)); } @AfterEach diff --git a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/collector/DefaultCollectorTest.java b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/collector/DefaultCollectorTest.java index 6113908990f..450da8a7c6c 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/collector/DefaultCollectorTest.java +++ b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/collector/DefaultCollectorTest.java @@ -22,7 +22,6 @@ import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.metrics.TestMetricsInvoker; import org.apache.dubbo.metrics.event.MetricsDispatcher; -import org.apache.dubbo.metrics.event.RequestBeforeEvent; import org.apache.dubbo.metrics.event.RequestEvent; import org.apache.dubbo.metrics.filter.MetricsFilter; import org.apache.dubbo.metrics.model.MetricsSupport; @@ -114,7 +113,8 @@ public void setup() { void testListener() { DefaultMetricsCollector metricsCollector = new DefaultMetricsCollector(applicationModel); RequestEvent event = RequestEvent.toRequestEvent(applicationModel, null, null, null, invocation, MetricsSupport.getSide(invocation)); - RequestBeforeEvent beforeEvent = new RequestBeforeEvent(applicationModel, null, null, new TypeWrapper(MetricsLevel.METHOD, MetricsKey.METRIC_REQUESTS)); + RequestEvent beforeEvent = RequestEvent.toRequestErrorEvent(applicationModel, null, null, invocation, MetricsSupport.getSide(invocation), RpcException.FORBIDDEN_EXCEPTION); + Assertions.assertTrue(metricsCollector.isSupport(event)); Assertions.assertTrue(metricsCollector.isSupport(beforeEvent)); } diff --git a/dubbo-metrics/dubbo-metrics-prometheus/src/test/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterTest.java b/dubbo-metrics/dubbo-metrics-prometheus/src/test/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterTest.java index e6aae6745da..6b4122753ea 100644 --- a/dubbo-metrics/dubbo-metrics-prometheus/src/test/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterTest.java +++ b/dubbo-metrics/dubbo-metrics-prometheus/src/test/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterTest.java @@ -80,7 +80,7 @@ void testJvmMetrics() { Double d2 = prometheusRegistry.getPrometheusRegistry().getSampleValue("jvm_gc_memory_promoted_bytes_total", new String[]{"application_name"}, new String[]{name}); Assertions.assertNull(d1); - Assertions.assertNotNull(d2); + Assertions.assertNull(d2); } @Test diff --git a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/RegistryMetricsConstants.java b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/RegistryMetricsConstants.java index e7adbc9622e..18dac35bc69 100644 --- a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/RegistryMetricsConstants.java +++ b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/RegistryMetricsConstants.java @@ -23,6 +23,7 @@ import org.apache.dubbo.metrics.model.key.MetricsPlaceValue; import java.util.Arrays; +import java.util.Collections; import java.util.List; import static org.apache.dubbo.metrics.model.key.MetricsKey.DIRECTORY_METRIC_NUM_ALL; @@ -46,17 +47,23 @@ public interface RegistryMetricsConstants { + String ATTACHMENT_REGISTRY_KEY = "registryKey"; + String ATTACHMENT_REGISTRY_SINGLE_KEY = "registrySingleKey"; + MetricsPlaceValue OP_TYPE_REGISTER = MetricsPlaceValue.of("register", MetricsLevel.APP); MetricsPlaceValue OP_TYPE_SUBSCRIBE = MetricsPlaceValue.of("subscribe", MetricsLevel.APP); MetricsPlaceValue OP_TYPE_NOTIFY = MetricsPlaceValue.of("notify", MetricsLevel.APP); MetricsPlaceValue OP_TYPE_DIRECTORY = MetricsPlaceValue.of("directory", MetricsLevel.APP); - MetricsPlaceValue OP_TYPE_REGISTER_SERVICE = MetricsPlaceValue.of("register.service", MetricsLevel.SERVICE); + MetricsPlaceValue OP_TYPE_REGISTER_SERVICE = MetricsPlaceValue.of("register.service", MetricsLevel.REGISTRY); MetricsPlaceValue OP_TYPE_SUBSCRIBE_SERVICE = MetricsPlaceValue.of("subscribe.service", MetricsLevel.SERVICE); // App-level - List APP_LEVEL_KEYS = Arrays.asList(REGISTER_METRIC_REQUESTS, REGISTER_METRIC_REQUESTS_SUCCEED, REGISTER_METRIC_REQUESTS_FAILED, - SUBSCRIBE_METRIC_NUM, SUBSCRIBE_METRIC_NUM_SUCCEED, SUBSCRIBE_METRIC_NUM_FAILED, - NOTIFY_METRIC_REQUESTS); + List APP_LEVEL_KEYS = Collections.singletonList(NOTIFY_METRIC_REQUESTS); + + // Registry-level + List REGISTER_LEVEL_KEYS = Arrays.asList(REGISTER_METRIC_REQUESTS, REGISTER_METRIC_REQUESTS_SUCCEED, REGISTER_METRIC_REQUESTS_FAILED, + SUBSCRIBE_METRIC_NUM, SUBSCRIBE_METRIC_NUM_SUCCEED, SUBSCRIBE_METRIC_NUM_FAILED + ); // Service-level List SERVICE_LEVEL_KEYS = Arrays.asList( diff --git a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/RegistryMetricsCollector.java b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/RegistryMetricsCollector.java index b18ed313f71..b510ed541b6 100644 --- a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/RegistryMetricsCollector.java +++ b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/RegistryMetricsCollector.java @@ -17,6 +17,7 @@ package org.apache.dubbo.metrics.registry.collector; +import org.apache.dubbo.common.constants.RegistryConstants; import org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.config.context.ConfigManager; import org.apache.dubbo.metrics.collector.CombMetricsCollector; @@ -25,7 +26,11 @@ import org.apache.dubbo.metrics.data.BaseStatComposite; import org.apache.dubbo.metrics.data.RtStatComposite; import org.apache.dubbo.metrics.data.ServiceStatComposite; +import org.apache.dubbo.metrics.model.ApplicationMetric; import org.apache.dubbo.metrics.model.MetricsCategory; +import org.apache.dubbo.metrics.model.ServiceKeyMetric; +import org.apache.dubbo.metrics.model.key.MetricsKey; +import org.apache.dubbo.metrics.model.key.MetricsKeyWrapper; import org.apache.dubbo.metrics.model.sample.MetricSample; import org.apache.dubbo.metrics.registry.RegistryMetricsConstants; import org.apache.dubbo.metrics.registry.event.RegistryEvent; @@ -33,7 +38,9 @@ import org.apache.dubbo.rpc.model.ApplicationModel; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Optional; import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_NOTIFY; @@ -51,6 +58,7 @@ public class RegistryMetricsCollector extends CombMetricsCollector collect() { return list; } list.addAll(super.export(MetricsCategory.REGISTRY)); + list.addAll(internalStat.export(MetricsCategory.REGISTRY)); return list; } + public void incrMetricsNum(MetricsKey metricsKey, List registryClusterNames) { + registryClusterNames.forEach(name -> internalStat.incrMetricsNum(metricsKey, name)); + } + + public void incrRegisterFinishNum(MetricsKey metricsKey, String registryOpType, List registryClusterNames, Long responseTime) { + registryClusterNames.forEach(name -> + { + ApplicationMetric applicationMetric = new ApplicationMetric(applicationModel); + applicationMetric.setExtraInfo(Collections.singletonMap(RegistryConstants.REGISTRY_CLUSTER_KEY.toLowerCase(), name)); + internalStat.incrMetricsNum(metricsKey, name); + getStats().getRtStatComposite().calcServiceKeyRt(registryOpType, responseTime, applicationMetric); + }); + + } + + public void incrServiceRegisterNum(MetricsKeyWrapper wrapper, String serviceKey, List registryClusterNames, int size) { + registryClusterNames.forEach(name -> + stats.incrementServiceKey(wrapper, serviceKey, Collections.singletonMap(RegistryConstants.REGISTRY_CLUSTER_KEY.toLowerCase(), name), size) + ); + } + + public void incrServiceRegisterFinishNum(MetricsKeyWrapper wrapper, String serviceKey, List registryClusterNames, int size, Long responseTime) { + registryClusterNames.forEach(name -> + { + Map extraInfo = Collections.singletonMap(RegistryConstants.REGISTRY_CLUSTER_KEY.toLowerCase(), name); + ServiceKeyMetric serviceKeyMetric = new ServiceKeyMetric(applicationModel, serviceKey); + serviceKeyMetric.setExtraInfo(extraInfo); + stats.incrementServiceKey(wrapper, serviceKey, extraInfo, size); + getStats().getRtStatComposite().calcServiceKeyRt(wrapper.getType(), responseTime, serviceKeyMetric); + } + ); + } + + public void setNum(MetricsKeyWrapper metricsKey, String serviceKey, int num, Map attachments) { + this.stats.setServiceKey(metricsKey, serviceKey, num, attachments); + } + } diff --git a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/RegistryStatComposite.java b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/RegistryStatComposite.java new file mode 100644 index 00000000000..a60c5c4b498 --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/RegistryStatComposite.java @@ -0,0 +1,81 @@ +/* + * 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.metrics.registry.collector; + +import org.apache.dubbo.common.constants.RegistryConstants; +import org.apache.dubbo.common.utils.CollectionUtils; +import org.apache.dubbo.metrics.model.ApplicationMetric; +import org.apache.dubbo.metrics.model.MetricsCategory; +import org.apache.dubbo.metrics.model.MetricsSupport; +import org.apache.dubbo.metrics.model.key.MetricsKey; +import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; +import org.apache.dubbo.metrics.model.sample.MetricSample; +import org.apache.dubbo.metrics.registry.RegistryMetricsConstants; +import org.apache.dubbo.metrics.report.AbstractMetricsExport; +import org.apache.dubbo.rpc.model.ApplicationModel; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; + +import static org.apache.dubbo.metrics.MetricsConstants.SELF_INCREMENT_SIZE; + +public class RegistryStatComposite extends AbstractMetricsExport { + + private final Map> appStats = new ConcurrentHashMap<>(); + + public RegistryStatComposite(ApplicationModel applicationModel) { + super(applicationModel); + init(RegistryMetricsConstants.REGISTER_LEVEL_KEYS); + } + + public void init(List appKeys) { + if (CollectionUtils.isEmpty(appKeys)) { + return; + } + appKeys.forEach(appKey -> appStats.put(appKey, new ConcurrentHashMap<>())); + } + + @Override + public List export(MetricsCategory category) { + List list = new ArrayList<>(); + for (MetricsKey metricsKey : appStats.keySet()) { + Map stringAtomicLongMap = appStats.get(metricsKey); + for (ApplicationMetric registerKeyMetric : stringAtomicLongMap.keySet()) { + list.add(new GaugeMetricSample<>(metricsKey, registerKeyMetric.getTags(), category, stringAtomicLongMap, value -> value.get(registerKeyMetric).get())); + } + } + return list; + } + + public void incrMetricsNum(MetricsKey metricsKey, String name) { + if (!appStats.containsKey(metricsKey)) { + return; + } + ApplicationMetric applicationMetric = new ApplicationMetric(getApplicationModel()); + applicationMetric.setExtraInfo(Collections.singletonMap(RegistryConstants.REGISTRY_CLUSTER_KEY.toLowerCase(), name)); + appStats.get(metricsKey).computeIfAbsent(applicationMetric, k -> new AtomicLong(0L)).getAndAdd(SELF_INCREMENT_SIZE); + MetricsSupport.fillZero(appStats); + } + + public Map> getAppStats() { + return appStats; + } +} diff --git a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistryEvent.java b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistryEvent.java index 5ed721c6951..97b9bac1ac2 100644 --- a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistryEvent.java +++ b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistryEvent.java @@ -22,9 +22,12 @@ import org.apache.dubbo.metrics.model.key.MetricsKey; import org.apache.dubbo.metrics.model.key.MetricsLevel; import org.apache.dubbo.metrics.model.key.TypeWrapper; +import org.apache.dubbo.metrics.registry.RegistryMetricsConstants; import org.apache.dubbo.metrics.registry.collector.RegistryMetricsCollector; import org.apache.dubbo.rpc.model.ApplicationModel; +import java.util.Collections; +import java.util.List; import java.util.Map; import static org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_DIRECTORY_MAP; @@ -48,18 +51,25 @@ public RegistryEvent(ApplicationModel applicationModel, TypeWrapper typeWrapper) } private static final TypeWrapper REGISTER_EVENT = new TypeWrapper(MetricsLevel.APP, MetricsKey.REGISTER_METRIC_REQUESTS, MetricsKey.REGISTER_METRIC_REQUESTS_SUCCEED, MetricsKey.REGISTER_METRIC_REQUESTS_FAILED); - public static RegistryEvent toRegisterEvent(ApplicationModel applicationModel) { - return new RegistryEvent(applicationModel, REGISTER_EVENT); + + public static RegistryEvent toRegisterEvent(ApplicationModel applicationModel, List registryClusterNames) { + RegistryEvent registryEvent = new RegistryEvent(applicationModel, REGISTER_EVENT); + registryEvent.putAttachment(RegistryMetricsConstants.ATTACHMENT_REGISTRY_KEY, registryClusterNames); + return registryEvent; } private static final TypeWrapper SUBSCRIBE_EVENT = new TypeWrapper(MetricsLevel.APP, MetricsKey.SUBSCRIBE_METRIC_NUM, MetricsKey.SUBSCRIBE_METRIC_NUM_SUCCEED, MetricsKey.SUBSCRIBE_METRIC_NUM_FAILED); - public static RegistryEvent toSubscribeEvent(ApplicationModel applicationModel) { - return new RegistryEvent(applicationModel, SUBSCRIBE_EVENT); + + public static RegistryEvent toSubscribeEvent(ApplicationModel applicationModel, String registryClusterName) { + RegistryEvent ddEvent = new RegistryEvent(applicationModel, SUBSCRIBE_EVENT); + ddEvent.putAttachment(RegistryMetricsConstants.ATTACHMENT_REGISTRY_KEY, Collections.singletonList(registryClusterName)); + return ddEvent; } private static final TypeWrapper NOTIFY_EVENT = new TypeWrapper(MetricsLevel.APP, MetricsKey.NOTIFY_METRIC_REQUESTS, MetricsKey.NOTIFY_METRIC_NUM_LAST, (MetricsKey) null); + public static RegistryEvent toNotifyEvent(ApplicationModel applicationModel) { return new RegistryEvent(applicationModel, NOTIFY_EVENT) { @Override @@ -70,24 +80,31 @@ public void customAfterPost(Object postResult) { } private static final TypeWrapper RS_EVENT = new TypeWrapper(MetricsLevel.SERVICE, MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS, MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_SUCCEED, MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_FAILED); - public static RegistryEvent toRsEvent(ApplicationModel applicationModel, String serviceKey, int size) { + + public static RegistryEvent toRsEvent(ApplicationModel applicationModel, String serviceKey, int size, List serviceDiscoveryNames) { RegistryEvent ddEvent = new RegistryEvent(applicationModel, RS_EVENT); ddEvent.putAttachment(ATTACHMENT_KEY_SERVICE, serviceKey); ddEvent.putAttachment(ATTACHMENT_KEY_SIZE, size); + ddEvent.putAttachment(RegistryMetricsConstants.ATTACHMENT_REGISTRY_KEY, serviceDiscoveryNames); return ddEvent; } private static final TypeWrapper SS_EVENT = new TypeWrapper(MetricsLevel.SERVICE, MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM, MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM_SUCCEED, MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM_FAILED); - public static RegistryEvent toSsEvent(ApplicationModel applicationModel, String serviceKey) { + + public static RegistryEvent toSsEvent(ApplicationModel applicationModel, String serviceKey, List serviceDiscoveryNames) { RegistryEvent ddEvent = new RegistryEvent(applicationModel, SS_EVENT); ddEvent.putAttachment(ATTACHMENT_KEY_SERVICE, serviceKey); + ddEvent.putAttachment(ATTACHMENT_KEY_SIZE, 1); + ddEvent.putAttachment(RegistryMetricsConstants.ATTACHMENT_REGISTRY_KEY, serviceDiscoveryNames); return ddEvent; } private static final TypeWrapper DIRECTORY_EVENT = new TypeWrapper(MetricsLevel.APP, MetricsKey.DIRECTORY_METRIC_NUM_VALID, null, null); - public static RegistryEvent refreshDirectoryEvent(ApplicationModel applicationModel, Map> summaryMap) { + + public static RegistryEvent refreshDirectoryEvent(ApplicationModel applicationModel, Map> summaryMap, Map attachments) { RegistryEvent registryEvent = new RegistryEvent(applicationModel, DIRECTORY_EVENT); registryEvent.putAttachment(ATTACHMENT_DIRECTORY_MAP, summaryMap); + registryEvent.putAttachments(attachments); return registryEvent; } diff --git a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistrySpecListener.java b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistrySpecListener.java new file mode 100644 index 00000000000..6e44fea1b1f --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistrySpecListener.java @@ -0,0 +1,154 @@ +/* + * 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.metrics.registry.event; + +import org.apache.dubbo.common.utils.CollectionUtils; +import org.apache.dubbo.metrics.collector.CombMetricsCollector; +import org.apache.dubbo.metrics.event.MetricsEvent; +import org.apache.dubbo.metrics.listener.AbstractMetricsKeyListener; +import org.apache.dubbo.metrics.listener.MetricsApplicationListener; +import org.apache.dubbo.metrics.model.key.MetricsKey; +import org.apache.dubbo.metrics.model.key.MetricsKeyWrapper; +import org.apache.dubbo.metrics.model.key.MetricsPlaceValue; +import org.apache.dubbo.metrics.registry.RegistryMetricsConstants; +import org.apache.dubbo.metrics.registry.collector.RegistryMetricsCollector; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import static org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_DIRECTORY_MAP; +import static org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_KEY_LAST_NUM_MAP; +import static org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_KEY_SERVICE; +import static org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_KEY_SIZE; +import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_DIRECTORY; +import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_NOTIFY; +import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_REGISTER; + +/** + * Different from the general-purpose listener constructor {@link MetricsApplicationListener} , + * it provides registry custom listeners + */ +public class RegistrySpecListener { + + /** + * Perform auto-increment on the monitored key, + * Can use a custom listener instead of this generic operation + */ + public static AbstractMetricsKeyListener onPost(MetricsKey metricsKey, CombMetricsCollector collector) { + return AbstractMetricsKeyListener.onEvent(metricsKey, + event -> ((RegistryMetricsCollector) collector).incrMetricsNum(metricsKey, getRgs(event)) + ); + } + + public static AbstractMetricsKeyListener onFinish(MetricsKey metricsKey, CombMetricsCollector collector) { + return AbstractMetricsKeyListener.onFinish(metricsKey, + event -> ((RegistryMetricsCollector) collector).incrRegisterFinishNum(metricsKey, OP_TYPE_REGISTER.getType(), getRgs(event), event.getTimePair().calc()) + ); + } + + public static AbstractMetricsKeyListener onError(MetricsKey metricsKey, CombMetricsCollector collector) { + return AbstractMetricsKeyListener.onError(metricsKey, + event -> ((RegistryMetricsCollector) collector).incrRegisterFinishNum(metricsKey, OP_TYPE_REGISTER.getType(), getRgs(event), event.getTimePair().calc()) + ); + } + + public static AbstractMetricsKeyListener onPostOfService(MetricsKey metricsKey, MetricsPlaceValue placeType, CombMetricsCollector collector) { + return AbstractMetricsKeyListener.onEvent(metricsKey, + event -> ((RegistryMetricsCollector) collector).incrServiceRegisterNum(new MetricsKeyWrapper(metricsKey, placeType), getServiceKey(event), getRgs(event), getSize(event)) + ); + } + + public static AbstractMetricsKeyListener onFinishOfService(MetricsKey metricsKey, MetricsPlaceValue placeType, CombMetricsCollector collector) { + return AbstractMetricsKeyListener.onFinish(metricsKey, + event -> ((RegistryMetricsCollector) collector).incrServiceRegisterFinishNum(new MetricsKeyWrapper(metricsKey, placeType), getServiceKey(event), getRgs(event), getSize(event), event.getTimePair().calc()) + ); + } + + public static AbstractMetricsKeyListener onErrorOfService(MetricsKey metricsKey, MetricsPlaceValue placeType, CombMetricsCollector collector) { + return AbstractMetricsKeyListener.onError(metricsKey, + event -> ((RegistryMetricsCollector) collector).incrServiceRegisterFinishNum(new MetricsKeyWrapper(metricsKey, placeType), getServiceKey(event), getRgs(event), getSize(event), event.getTimePair().calc()) + ); + } + + /** + * Every time an event is triggered, multiple serviceKey related to notify are increment + */ + public static AbstractMetricsKeyListener onFinishOfNotify(MetricsKey metricsKey, MetricsPlaceValue placeType, CombMetricsCollector collector) { + return AbstractMetricsKeyListener.onFinish(metricsKey, + event -> + { + collector.addServiceRt(event.appName(), placeType.getType(), event.getTimePair().calc()); + Map lastNumMap = Collections.unmodifiableMap(event.getAttachmentValue(ATTACHMENT_KEY_LAST_NUM_MAP)); + lastNumMap.forEach( + (k, v) -> collector.setNum(new MetricsKeyWrapper(metricsKey, OP_TYPE_NOTIFY), k, v)); + } + ); + } + + /** + * Every time an event is triggered, multiple fixed key related to directory are increment, which has nothing to do with the monitored key + */ + public static AbstractMetricsKeyListener onPostOfDirectory(MetricsKey metricsKey, CombMetricsCollector collector) { + return AbstractMetricsKeyListener.onEvent(metricsKey, + event -> { + Map> summaryMap = event.getAttachmentValue(ATTACHMENT_DIRECTORY_MAP); + Map otherAttachments = new HashMap<>(); + for (Map.Entry entry : event.getAttachments().entrySet()) { + if (entry.getValue() instanceof String) { + otherAttachments.put(entry.getKey().toLowerCase(Locale.ROOT), (String) entry.getValue()); + } + } + summaryMap.forEach((summaryKey, map) -> + map.forEach( + (k, v) -> + { + if (CollectionUtils.isEmptyMap(otherAttachments)) { + collector.setNum(new MetricsKeyWrapper(summaryKey, OP_TYPE_DIRECTORY), k, v); + } else { + ((RegistryMetricsCollector) collector).setNum(new MetricsKeyWrapper(summaryKey, OP_TYPE_DIRECTORY), k, v, otherAttachments); + } + } + + )); + + } + ); + } + + + /** + * Get the number of multiple registries + */ + public static List getRgs(MetricsEvent event) { + return event.getAttachmentValue(RegistryMetricsConstants.ATTACHMENT_REGISTRY_KEY); + } + + /** + * Get the exposed number of the protocol + */ + public static int getSize(MetricsEvent event) { + return event.getAttachmentValue(ATTACHMENT_KEY_SIZE); + } + + public static String getServiceKey(MetricsEvent event) { + return event.getAttachmentValue(ATTACHMENT_KEY_SERVICE); + } + +} diff --git a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistrySubDispatcher.java b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistrySubDispatcher.java index fd314443db6..27cbcb4f617 100644 --- a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistrySubDispatcher.java +++ b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistrySubDispatcher.java @@ -18,22 +18,15 @@ package org.apache.dubbo.metrics.registry.event; import org.apache.dubbo.metrics.event.SimpleMetricsEventMulticaster; -import org.apache.dubbo.metrics.listener.AbstractMetricsKeyListener; import org.apache.dubbo.metrics.listener.MetricsApplicationListener; -import org.apache.dubbo.metrics.listener.MetricsServiceListener; import org.apache.dubbo.metrics.model.key.CategoryOverall; import org.apache.dubbo.metrics.model.key.MetricsCat; import org.apache.dubbo.metrics.model.key.MetricsKey; -import org.apache.dubbo.metrics.model.key.MetricsKeyWrapper; import org.apache.dubbo.metrics.registry.collector.RegistryMetricsCollector; import java.util.Arrays; -import java.util.Collections; import java.util.List; -import java.util.Map; -import static org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_DIRECTORY_MAP; -import static org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_KEY_LAST_NUM_MAP; import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_DIRECTORY; import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_NOTIFY; import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_REGISTER; @@ -74,55 +67,37 @@ interface CategorySet { /** - * {@link MetricsCat} MetricsCat collection, for better classification processing - * Except for a few custom functions, most of them can build standard event listening functions through the static methods of MetricsApplicationListener + * {@link MetricsCat} MetricsCat collection, for better classification processing + * Except for a few custom functions, most of them can build standard event listening functions through the static methods of MetricsApplicationListener */ interface MCat { // MetricsRegisterListener - MetricsCat APPLICATION_REGISTER_POST = new MetricsCat(MetricsKey.REGISTER_METRIC_REQUESTS, MetricsApplicationListener::onPostEventBuild); - MetricsCat APPLICATION_REGISTER_FINISH = new MetricsCat(MetricsKey.REGISTER_METRIC_REQUESTS_SUCCEED, MetricsApplicationListener::onFinishEventBuild); - MetricsCat APPLICATION_REGISTER_ERROR = new MetricsCat(MetricsKey.REGISTER_METRIC_REQUESTS_FAILED, MetricsApplicationListener::onErrorEventBuild); + MetricsCat APPLICATION_REGISTER_POST = new MetricsCat(MetricsKey.REGISTER_METRIC_REQUESTS, RegistrySpecListener::onPost); + MetricsCat APPLICATION_REGISTER_FINISH = new MetricsCat(MetricsKey.REGISTER_METRIC_REQUESTS_SUCCEED, RegistrySpecListener::onFinish); + MetricsCat APPLICATION_REGISTER_ERROR = new MetricsCat(MetricsKey.REGISTER_METRIC_REQUESTS_FAILED, RegistrySpecListener::onError); // MetricsSubscribeListener - MetricsCat APPLICATION_SUBSCRIBE_POST = new MetricsCat(MetricsKey.SUBSCRIBE_METRIC_NUM, MetricsApplicationListener::onPostEventBuild); - MetricsCat APPLICATION_SUBSCRIBE_FINISH = new MetricsCat(MetricsKey.SUBSCRIBE_METRIC_NUM_SUCCEED, MetricsApplicationListener::onFinishEventBuild); - MetricsCat APPLICATION_SUBSCRIBE_ERROR = new MetricsCat(MetricsKey.SUBSCRIBE_METRIC_NUM_FAILED, MetricsApplicationListener::onErrorEventBuild); + MetricsCat APPLICATION_SUBSCRIBE_POST = new MetricsCat(MetricsKey.SUBSCRIBE_METRIC_NUM, RegistrySpecListener::onPost); + MetricsCat APPLICATION_SUBSCRIBE_FINISH = new MetricsCat(MetricsKey.SUBSCRIBE_METRIC_NUM_SUCCEED, RegistrySpecListener::onFinish); + MetricsCat APPLICATION_SUBSCRIBE_ERROR = new MetricsCat(MetricsKey.SUBSCRIBE_METRIC_NUM_FAILED, RegistrySpecListener::onError); // MetricsNotifyListener MetricsCat APPLICATION_NOTIFY_POST = new MetricsCat(MetricsKey.NOTIFY_METRIC_REQUESTS, MetricsApplicationListener::onPostEventBuild); - MetricsCat APPLICATION_NOTIFY_FINISH = new MetricsCat(MetricsKey.NOTIFY_METRIC_NUM_LAST, - (key, placeType, collector) -> AbstractMetricsKeyListener.onFinish(key, - event -> { - collector.addServiceRt(event.appName(), placeType.getType(), event.getTimePair().calc()); - Map lastNumMap = Collections.unmodifiableMap(event.getAttachmentValue(ATTACHMENT_KEY_LAST_NUM_MAP)); - lastNumMap.forEach( - (k, v) -> collector.setNum(new MetricsKeyWrapper(key, OP_TYPE_NOTIFY), k, v)); - - } - )); - - - MetricsCat APPLICATION_DIRECTORY_POST = new MetricsCat(MetricsKey.DIRECTORY_METRIC_NUM_VALID, (key, placeType, collector) -> AbstractMetricsKeyListener.onEvent(key, - event -> - { - Map> summaryMap = event.getAttachmentValue(ATTACHMENT_DIRECTORY_MAP); - summaryMap.forEach((metricsKey, map) -> - map.forEach( - (k, v) -> collector.setNum(new MetricsKeyWrapper(metricsKey, OP_TYPE_DIRECTORY), k, v))); - } - )); + MetricsCat APPLICATION_NOTIFY_FINISH = new MetricsCat(MetricsKey.NOTIFY_METRIC_NUM_LAST, RegistrySpecListener::onFinishOfNotify); + + MetricsCat APPLICATION_DIRECTORY_POST = new MetricsCat(MetricsKey.DIRECTORY_METRIC_NUM_VALID, RegistrySpecListener::onPostOfDirectory); // MetricsServiceRegisterListener - MetricsCat SERVICE_REGISTER_POST = new MetricsCat(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS, MetricsServiceListener::onPostEventBuild); - MetricsCat SERVICE_REGISTER_FINISH = new MetricsCat(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_SUCCEED, MetricsServiceListener::onFinishEventBuild); - MetricsCat SERVICE_REGISTER_ERROR = new MetricsCat(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_FAILED, MetricsServiceListener::onErrorEventBuild); + MetricsCat SERVICE_REGISTER_POST = new MetricsCat(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS, RegistrySpecListener::onPostOfService); + MetricsCat SERVICE_REGISTER_FINISH = new MetricsCat(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_SUCCEED, RegistrySpecListener::onFinishOfService); + MetricsCat SERVICE_REGISTER_ERROR = new MetricsCat(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_FAILED, RegistrySpecListener::onErrorOfService); // MetricsServiceSubscribeListener - MetricsCat SERVICE_SUBSCRIBE_POST = new MetricsCat(MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM, MetricsServiceListener::onPostEventBuild); - MetricsCat SERVICE_SUBSCRIBE_FINISH = new MetricsCat(MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM_SUCCEED, MetricsServiceListener::onFinishEventBuild); - MetricsCat SERVICE_SUBSCRIBE_ERROR = new MetricsCat(MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM_FAILED, MetricsServiceListener::onErrorEventBuild); + MetricsCat SERVICE_SUBSCRIBE_POST = new MetricsCat(MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM, RegistrySpecListener::onPostOfService); + MetricsCat SERVICE_SUBSCRIBE_FINISH = new MetricsCat(MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM_SUCCEED, RegistrySpecListener::onFinishOfService); + MetricsCat SERVICE_SUBSCRIBE_ERROR = new MetricsCat(MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM_FAILED, RegistrySpecListener::onErrorOfService); } diff --git a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsCollectorTest.java b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsCollectorTest.java index 00352ecf2af..ff289caca33 100644 --- a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsCollectorTest.java +++ b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsCollectorTest.java @@ -17,6 +17,7 @@ package org.apache.dubbo.metrics.registry.metrics.collector; +import com.google.common.collect.Lists; import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.metrics.event.MetricsDispatcher; import org.apache.dubbo.metrics.event.MetricsEventBus; @@ -30,12 +31,12 @@ import org.apache.dubbo.metrics.registry.event.RegistryEvent; import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.FrameworkModel; - import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -43,9 +44,11 @@ import java.util.stream.Collectors; import static org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_NAME; +import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.APP_LEVEL_KEYS; import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_REGISTER; import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_REGISTER_SERVICE; import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_SUBSCRIBE_SERVICE; +import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.REGISTER_LEVEL_KEYS; class RegistryMetricsCollectorTest { @@ -74,12 +77,12 @@ public void teardown() { @Test void testRegisterMetrics() { - RegistryEvent registryEvent = RegistryEvent.toRegisterEvent(applicationModel); + RegistryEvent registryEvent = RegistryEvent.toRegisterEvent(applicationModel, Lists.newArrayList("reg1")); MetricsEventBus.post(registryEvent, () -> { List metricSamples = collector.collect(); - // push success +1 -> other default 0 = RegistryMetricsConstants.APP_LEVEL_KEYS.size() - Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size(), metricSamples.size()); + // push success +1 -> other default 0 = APP_LEVEL_KEYS.size() + Assertions.assertEquals(APP_LEVEL_KEYS.size() + REGISTER_LEVEL_KEYS.size(), metricSamples.size()); Assertions.assertTrue(metricSamples.stream().allMatch(metricSample -> metricSample instanceof GaugeMetricSample)); Assertions.assertTrue(metricSamples.stream().anyMatch(metricSample -> ((GaugeMetricSample) metricSample).applyAsDouble() == 1)); return null; @@ -88,12 +91,12 @@ void testRegisterMetrics() { // push finish rt +1 List metricSamples = collector.collect(); - // RegistryMetricsConstants.APP_LEVEL_KEYS.size() + rt(5) = 12 - Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 5, metricSamples.size()); + // APP_LEVEL_KEYS.size() + rt(5) = 12 + Assertions.assertEquals(APP_LEVEL_KEYS.size() + REGISTER_LEVEL_KEYS.size() + 5, metricSamples.size()); long c1 = registryEvent.getTimePair().calc(); - registryEvent = RegistryEvent.toRegisterEvent(applicationModel); + registryEvent = RegistryEvent.toRegisterEvent(applicationModel, Lists.newArrayList("reg1")); TimePair lastTimePair = registryEvent.getTimePair(); MetricsEventBus.post(registryEvent, () -> { @@ -111,7 +114,7 @@ void testRegisterMetrics() { metricSamples = collector.collect(); // num(total+success+error) + rt(5) - Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 5, metricSamples.size()); + Assertions.assertEquals(APP_LEVEL_KEYS.size() + REGISTER_LEVEL_KEYS.size() + 5, metricSamples.size()); // calc rt for (MetricSample sample : metricSamples) { @@ -134,8 +137,9 @@ void testRegisterMetrics() { void testServicePushMetrics() { String serviceName = "demo.gameService"; + List rcNames = Lists.newArrayList("demo1"); - RegistryEvent registryEvent = RegistryEvent.toRsEvent(applicationModel, serviceName, 2); + RegistryEvent registryEvent = RegistryEvent.toRsEvent(applicationModel, serviceName, 2, rcNames); MetricsEventBus.post(registryEvent, () -> { List metricSamples = collector.collect(); @@ -154,7 +158,7 @@ void testServicePushMetrics() { Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 5 + 2, metricSamples.size()); long c1 = registryEvent.getTimePair().calc(); - registryEvent = RegistryEvent.toRsEvent(applicationModel, serviceName, 2); + registryEvent = RegistryEvent.toRsEvent(applicationModel, serviceName, 2, rcNames); TimePair lastTimePair = registryEvent.getTimePair(); MetricsEventBus.post(registryEvent, () -> { @@ -196,7 +200,7 @@ void testServiceSubscribeMetrics() { String serviceName = "demo.gameService"; - RegistryEvent subscribeEvent = RegistryEvent.toSsEvent(applicationModel, serviceName); + RegistryEvent subscribeEvent = RegistryEvent.toSsEvent(applicationModel, serviceName, Collections.singletonList("demo1")); MetricsEventBus.post(subscribeEvent, () -> { List metricSamples = collector.collect(); @@ -216,7 +220,7 @@ void testServiceSubscribeMetrics() { Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 5 + 2, metricSamples.size()); long c1 = subscribeEvent.getTimePair().calc(); - subscribeEvent = RegistryEvent.toSsEvent(applicationModel, serviceName); + subscribeEvent = RegistryEvent.toSsEvent(applicationModel, serviceName, Collections.singletonList("demo1")); TimePair lastTimePair = subscribeEvent.getTimePair(); MetricsEventBus.post(subscribeEvent, () -> { diff --git a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsTest.java b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsTest.java index 0e1bf073465..5610bef2321 100644 --- a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsTest.java +++ b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsTest.java @@ -17,6 +17,7 @@ package org.apache.dubbo.metrics.registry.metrics.collector; +import com.google.common.collect.Lists; import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.config.MetricsConfig; import org.apache.dubbo.config.context.ConfigManager; @@ -28,7 +29,6 @@ import org.apache.dubbo.metrics.registry.event.RegistryEvent; import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.FrameworkModel; - import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -289,19 +289,20 @@ void eventFailed(RegistryEvent event) { } RegistryEvent registerEvent() { - RegistryEvent event = RegistryEvent.toRegisterEvent(applicationModel); + RegistryEvent event = RegistryEvent.toRegisterEvent(applicationModel, Lists.newArrayList("reg1")); event.setAvailable(true); return event; } RegistryEvent rsEvent() { - RegistryEvent event = RegistryEvent.toRsEvent(applicationModel, "TestServiceInterface1", 1); + List rcNames = Lists.newArrayList("demo1"); + RegistryEvent event = RegistryEvent.toRsEvent(applicationModel, "TestServiceInterface1", 1, rcNames); event.setAvailable(true); return event; } RegistryEvent subscribeEvent() { - RegistryEvent event = RegistryEvent.toSubscribeEvent(applicationModel); + RegistryEvent event = RegistryEvent.toSubscribeEvent(applicationModel, "registryClusterName_test"); event.setAvailable(true); return event; } diff --git a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryStatCompositeTest.java b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryStatCompositeTest.java index 5ce44d04ad5..3c0d00826e8 100644 --- a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryStatCompositeTest.java +++ b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryStatCompositeTest.java @@ -17,6 +17,7 @@ package org.apache.dubbo.metrics.registry.metrics.collector; +import org.apache.dubbo.common.constants.RegistryConstants; import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.metrics.data.ApplicationStatComposite; import org.apache.dubbo.metrics.data.BaseStatComposite; @@ -29,12 +30,15 @@ import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; import org.apache.dubbo.metrics.model.sample.MetricSample; import org.apache.dubbo.metrics.registry.RegistryMetricsConstants; +import org.apache.dubbo.metrics.registry.collector.RegistryStatComposite; import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.FrameworkModel; + import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; @@ -55,6 +59,7 @@ public class RegistryStatCompositeTest { private ApplicationModel applicationModel; private String applicationName; private BaseStatComposite statComposite; + private RegistryStatComposite regStatComposite; @BeforeEach public void setup() { @@ -83,6 +88,7 @@ protected void init(RtStatComposite rtStatComposite) { rtStatComposite.init(OP_TYPE_REGISTER, OP_TYPE_SUBSCRIBE, OP_TYPE_NOTIFY, OP_TYPE_REGISTER_SERVICE, OP_TYPE_SUBSCRIBE_SERVICE); } }; + regStatComposite = new RegistryStatComposite(applicationModel); } @Test @@ -102,8 +108,10 @@ void testInit() { @Test void testIncrement() { - statComposite.incrementApp(REGISTER_METRIC_REQUESTS, 1); - Assertions.assertEquals(1L, statComposite.getApplicationStatComposite().getApplicationNumStats().get(REGISTER_METRIC_REQUESTS).get()); + regStatComposite.incrMetricsNum(REGISTER_METRIC_REQUESTS, "beijing"); + ApplicationMetric applicationMetric = new ApplicationMetric(applicationModel); + applicationMetric.setExtraInfo(Collections.singletonMap(RegistryConstants.REGISTRY_CLUSTER_KEY.toLowerCase(), "beijing")); + Assertions.assertEquals(1L, regStatComposite.getAppStats().get(REGISTER_METRIC_REQUESTS).get(applicationMetric).get()); } @Test diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/protocol/QosProtocolWrapper.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/protocol/QosProtocolWrapper.java index 127fa8bb42c..a06b246ab4c 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/protocol/QosProtocolWrapper.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/protocol/QosProtocolWrapper.java @@ -23,9 +23,7 @@ import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.qos.api.PermissionLevel; import org.apache.dubbo.qos.common.QosConstants; -import org.apache.dubbo.qos.pu.QosWireProtocol; import org.apache.dubbo.qos.server.Server; -import org.apache.dubbo.remoting.api.WireProtocol; import org.apache.dubbo.rpc.Exporter; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Protocol; @@ -104,10 +102,6 @@ private void startQosServer(URL url) { } boolean qosEnable = url.getParameter(QOS_ENABLE, true); - WireProtocol qosWireProtocol = frameworkModel.getExtensionLoader(WireProtocol.class).getExtension("qos"); - if (qosWireProtocol != null) { - ((QosWireProtocol) qosWireProtocol).setQosEnable(qosEnable); - } if (!qosEnable) { logger.info("qos won't be started because it is disabled. " + "Please check dubbo.application.qos.enable is configured either in system property, " + diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/QosDetector.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/QosDetector.java deleted file mode 100644 index 6a914053525..00000000000 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/QosDetector.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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.qos.pu; - -import org.apache.dubbo.remoting.api.ProtocolDetector; -import org.apache.dubbo.remoting.buffer.ChannelBuffer; -import org.apache.dubbo.rpc.model.FrameworkModel; - -public class QosDetector implements ProtocolDetector { - - private final QosHTTP1Detector qosHTTP1Detector = new QosHTTP1Detector(); - private final TelnetDetector telnetDetector; - private boolean QosEnableFlag = true; - - public void setQosEnableFlag(boolean qosEnableFlag) { - QosEnableFlag = qosEnableFlag; - } - - public QosDetector(FrameworkModel frameworkModel) { - this.telnetDetector = new TelnetDetector(frameworkModel); - } - - @Override - public Result detect(ChannelBuffer in) { - if(!QosEnableFlag) { - return Result.UNRECOGNIZED; - } - Result h1Res = qosHTTP1Detector.detect(in); - if(h1Res.equals(Result.RECOGNIZED)) { - return h1Res; - } - Result telRes = telnetDetector.detect(in); - if(telRes.equals(Result.RECOGNIZED)) { - return telRes; - } - if(h1Res.equals(Result.NEED_MORE_DATA) || telRes.equals(Result.NEED_MORE_DATA)) { - return Result.NEED_MORE_DATA; - } - return Result.UNRECOGNIZED; - } - -} diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/QosHTTP1Detector.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/QosHTTP1Detector.java deleted file mode 100644 index 9a62b841b1f..00000000000 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/QosHTTP1Detector.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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.qos.pu; - -import org.apache.dubbo.remoting.api.ProtocolDetector; -import org.apache.dubbo.remoting.buffer.ChannelBuffer; - -public class QosHTTP1Detector implements ProtocolDetector { - private static boolean isHttp(int magic) { - return magic == 'G' || magic == 'P'; - } - - @Override - public Result detect(ChannelBuffer in) { - if (in.readableBytes() < 2) { - return Result.NEED_MORE_DATA; - } - final int magic = in.getByte(in.readerIndex()); - // h2 starts with "PR" - if (isHttp(magic) && in.getByte(in.readerIndex()+1) != 'R' ){ - return Result.RECOGNIZED; - } - return Result.UNRECOGNIZED; - } -} diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/QosWireProtocol.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/QosWireProtocol.java deleted file mode 100644 index 8d27679d6bd..00000000000 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/QosWireProtocol.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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.qos.pu; - -import org.apache.dubbo.common.URL; -import org.apache.dubbo.common.extension.Activate; -import org.apache.dubbo.common.utils.StringUtils; -import org.apache.dubbo.qos.api.PermissionLevel; -import org.apache.dubbo.qos.server.DubboLogo; -import org.apache.dubbo.qos.api.QosConfiguration; -import org.apache.dubbo.qos.server.handler.QosProcessHandler; -import org.apache.dubbo.remoting.ChannelHandler; -import org.apache.dubbo.remoting.api.AbstractWireProtocol; -import org.apache.dubbo.remoting.api.pu.ChannelHandlerPretender; -import org.apache.dubbo.remoting.api.pu.ChannelOperator; -import org.apache.dubbo.rpc.model.FrameworkModel; -import org.apache.dubbo.rpc.model.ScopeModelAware; - -import java.util.ArrayList; -import java.util.List; - -@Activate -public class QosWireProtocol extends AbstractWireProtocol implements ScopeModelAware { - - public QosWireProtocol(FrameworkModel frameworkModel) { - super(new QosDetector(frameworkModel)); - } - - public void setQosEnable(boolean flag) { - ((QosDetector)this.detector()).setQosEnableFlag(flag); - } - - @Override - public void configServerProtocolHandler(URL url, ChannelOperator operator) { - // add qosProcess handler - QosProcessHandler handler = new QosProcessHandler(url.getOrDefaultFrameworkModel(), - QosConfiguration.builder() - .welcome(DubboLogo.DUBBO) - .acceptForeignIp(false) - .acceptForeignIpWhitelist(StringUtils.EMPTY_STRING) - .anonymousAccessPermissionLevel(PermissionLevel.PUBLIC.name()) - .build() - ); - List handlers = new ArrayList<>(); - handlers.add(new ChannelHandlerPretender(handler)); - operator.configChannelHandler(handlers); - } - -} diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/TelnetDetector.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/TelnetDetector.java deleted file mode 100644 index d40f858377d..00000000000 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/TelnetDetector.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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.qos.pu; - -import org.apache.dubbo.qos.api.BaseCommand; -import org.apache.dubbo.qos.api.CommandContext; -import org.apache.dubbo.qos.command.decoder.TelnetCommandDecoder; -import org.apache.dubbo.remoting.api.ProtocolDetector; -import org.apache.dubbo.remoting.buffer.ChannelBuffer; -import org.apache.dubbo.remoting.buffer.ChannelBuffers; -import org.apache.dubbo.remoting.buffer.HeapChannelBuffer; -import org.apache.dubbo.rpc.model.FrameworkModel; - -import io.netty.util.CharsetUtil; - -import static java.lang.Math.min; - - -public class TelnetDetector implements ProtocolDetector { - - private final FrameworkModel frameworkModel; - private final int MaxSize = 2048; - private final ChannelBuffer AytPreface = new HeapChannelBuffer(new byte[]{(byte) 0xff, (byte) 0xf6}); - - public TelnetDetector(FrameworkModel frameworkModel) { - this.frameworkModel = frameworkModel; - } - - @Override - public Result detect(ChannelBuffer in) { - if (in.readableBytes() >= MaxSize) { - return Result.UNRECOGNIZED; - } - Result resCommand = commandDetect(in); - if (resCommand.equals(Result.RECOGNIZED)) { - return resCommand; - } - Result resAyt = telnetAytDetect(in); - if (resAyt.equals(Result.RECOGNIZED)) { - return resAyt; - } - if (resAyt.equals(Result.UNRECOGNIZED) && resCommand.equals(Result.UNRECOGNIZED)) { - return Result.UNRECOGNIZED; - } - return Result.NEED_MORE_DATA; - } - - private Result commandDetect(ChannelBuffer in) { - // detect if remote channel send a qos command to server - ChannelBuffer back = in.copy(); - byte[] backBytes; - try { - backBytes = new byte[back.readableBytes()]; - back.getBytes(back.readerIndex(), backBytes); - } finally { - back.release(); - } - - String s = new String(backBytes, CharsetUtil.UTF_8); - // trim /r/n to let parser work for input - s = s.trim(); - CommandContext commandContext = TelnetCommandDecoder.decode(s); - if (frameworkModel.getExtensionLoader(BaseCommand.class).hasExtension(commandContext.getCommandName())) { - return Result.RECOGNIZED; - } - return Result.UNRECOGNIZED; - } - - private Result telnetAytDetect(ChannelBuffer in) { - // detect if remote channel send a telnet ayt command to server - int prefaceLen = AytPreface.readableBytes(); - int bytesRead = min(in.readableBytes(), prefaceLen); - if (bytesRead == 0 || !ChannelBuffers.prefixEquals(in, AytPreface, bytesRead)) { - return Result.UNRECOGNIZED; - } - if (bytesRead == prefaceLen) { - // we need to consume preface because it's not a qos command - // consume and remember to mark, pu server handler reset reader index - in.readBytes(AytPreface.readableBytes()); - in.markReaderIndex(); - return Result.RECOGNIZED; - } - return Result.NEED_MORE_DATA; - } - -} diff --git a/dubbo-plugin/dubbo-qos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.remoting.api.WireProtocol b/dubbo-plugin/dubbo-qos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.remoting.api.WireProtocol deleted file mode 100644 index cd4d62dd5cc..00000000000 --- a/dubbo-plugin/dubbo-qos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.remoting.api.WireProtocol +++ /dev/null @@ -1 +0,0 @@ -qos=org.apache.dubbo.qos.pu.QosWireProtocol diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/pu/QosWireProtocolTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/pu/QosWireProtocolTest.java deleted file mode 100644 index febeda154f7..00000000000 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/pu/QosWireProtocolTest.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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.qos.pu; - -import org.apache.dubbo.common.URL; -import org.apache.dubbo.remoting.api.pu.ChannelOperator; -import org.apache.dubbo.rpc.model.FrameworkModel; - -import org.junit.jupiter.api.Test; - -import static org.mockito.ArgumentMatchers.anyList; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -class QosWireProtocolTest { - - @Test - void ShouldNotThrowExOnConfigServerProtocolHandler_GivenHappyPassConfig() { - final QosWireProtocol target = new QosWireProtocol(FrameworkModel.defaultModel()); - final URL url = mock(URL.class); - final ChannelOperator channelOperator = mock(ChannelOperator.class); - target.configServerProtocolHandler(url, channelOperator); - verify(channelOperator).configChannelHandler(anyList()); - - } -} diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java index 9da383d771b..b3b771c20e4 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java @@ -132,11 +132,13 @@ public synchronized void register() throws RuntimeException { if (isDestroy) { return; } - ServiceInstance serviceInstance = createServiceInstance(this.metadataInfo); - if (!isValidInstance(serviceInstance)) { - return; + if (this.serviceInstance == null) { + ServiceInstance serviceInstance = createServiceInstance(this.metadataInfo); + if (!isValidInstance(serviceInstance)) { + return; + } + this.serviceInstance = serviceInstance; } - this.serviceInstance = serviceInstance; boolean revisionUpdated = calOrUpdateInstanceRevision(this.serviceInstance); if (revisionUpdated) { reportMetadata(this.metadataInfo); diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscoveryFactory.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscoveryFactory.java index 57b4213433a..469a507510c 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscoveryFactory.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscoveryFactory.java @@ -50,9 +50,14 @@ public List getAllServiceDiscoveries() { @Override public ServiceDiscovery getServiceDiscovery(URL registryURL) { - String key = registryURL.toServiceStringWithoutResolving(); + String key = createRegistryCacheKey(registryURL); return ConcurrentHashMapUtils.computeIfAbsent(discoveries, key, k -> createDiscovery(registryURL)); } + protected String createRegistryCacheKey(URL url) { + return url.toServiceStringWithoutResolving(); + } + protected abstract ServiceDiscovery createDiscovery(URL registryURL); + } diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/NopServiceDiscovery.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/NopServiceDiscovery.java index 7cf8d329307..2df58f9b193 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/NopServiceDiscovery.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/NopServiceDiscovery.java @@ -55,4 +55,10 @@ public Set getServices() { public List getInstances(String serviceName) throws NullPointerException { return null; } + + @Override + public boolean isAvailable() { + // NopServiceDiscovery is designed for compatibility, check availability is meaningless, just return true + return true; + } } diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscovery.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscovery.java index 29960b39e97..9f9cc984d5d 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscovery.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscovery.java @@ -21,6 +21,7 @@ import org.apache.dubbo.common.URL; import org.apache.dubbo.common.lang.Prioritized; +import org.apache.dubbo.common.utils.CollectionUtils; import org.apache.dubbo.metadata.MetadataInfo; import org.apache.dubbo.registry.RegistryService; import org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListener; @@ -94,6 +95,13 @@ default long getDelay() { return getUrl().getParameter(REGISTRY_DELAY_NOTIFICATION_KEY, 5000); } + /** + * Get services is the default way for service discovery to be available + */ + default boolean isAvailable() { + return !isDestroy() && CollectionUtils.isNotEmpty(getServices()); + } + /** * A human-readable description of the implementation * 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 d808a05b977..95a196466e9 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 @@ -17,6 +17,7 @@ package org.apache.dubbo.registry.client; import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.constants.RegistryConstants; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.utils.CollectionUtils; @@ -33,6 +34,7 @@ import org.apache.dubbo.registry.support.FailbackRegistry; import org.apache.dubbo.rpc.model.ApplicationModel; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; @@ -110,7 +112,7 @@ public ServiceDiscovery getServiceDiscovery() { */ protected ServiceDiscovery createServiceDiscovery(URL registryURL) { return getServiceDiscovery(registryURL.addParameter(INTERFACE_KEY, ServiceDiscovery.class.getName()) - .removeParameter(REGISTRY_TYPE_KEY)); + .removeParameter(REGISTRY_TYPE_KEY)); } /** @@ -278,11 +280,8 @@ public List lookup(URL url) { @Override public boolean isAvailable() { - if (serviceDiscovery instanceof NopServiceDiscovery) { - // NopServiceDiscovery is designed for compatibility, check availability is meaningless, just return true - return true; - } - return !serviceDiscovery.isDestroy() && !serviceDiscovery.getServices().isEmpty(); + //serviceDiscovery isAvailable has a default method, which can be used as a reference when implementing + return serviceDiscovery.isAvailable(); } @Override @@ -331,7 +330,9 @@ protected void subscribeURLs(URL url, NotifyListener listener, Set servi serviceInstancesChangedListener.addListenerAndNotify(url, listener); ServiceInstancesChangedListener finalServiceInstancesChangedListener = serviceInstancesChangedListener; - MetricsEventBus.post(RegistryEvent.toSsEvent(url.getApplicationModel(), serviceKey), + String serviceDiscoveryName = url.getParameter(RegistryConstants.REGISTRY_CLUSTER_KEY, url.getProtocol()); + + MetricsEventBus.post(RegistryEvent.toSsEvent(url.getApplicationModel(), serviceKey, Collections.singletonList(serviceDiscoveryName)), () -> { serviceDiscovery.addServiceInstancesChangedListener(finalServiceInstancesChangedListener); return null; diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistryDirectory.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistryDirectory.java index baec948745d..d5168aaf7c2 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistryDirectory.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistryDirectory.java @@ -21,6 +21,7 @@ import org.apache.dubbo.common.URLBuilder; import org.apache.dubbo.common.config.configcenter.DynamicConfiguration; import org.apache.dubbo.common.constants.CommonConstants; +import org.apache.dubbo.common.constants.RegistryConstants; import org.apache.dubbo.common.extension.ExtensionLoader; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; @@ -34,6 +35,7 @@ import org.apache.dubbo.registry.AddressListener; import org.apache.dubbo.registry.Constants; import org.apache.dubbo.registry.ProviderFirstParams; +import org.apache.dubbo.registry.Registry; import org.apache.dubbo.registry.integration.AbstractConfiguratorListener; import org.apache.dubbo.registry.integration.DynamicDirectory; import org.apache.dubbo.rpc.Invocation; @@ -58,6 +60,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -66,6 +69,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY; import static org.apache.dubbo.common.constants.CommonConstants.DISABLED_KEY; import static org.apache.dubbo.common.constants.CommonConstants.ENABLED_KEY; +import static org.apache.dubbo.common.constants.CommonConstants.INSTANCE_REGISTER_MODE; import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY; import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY; import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_FAILED_DESTROY_INVOKER; @@ -73,6 +77,8 @@ import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_UNSUPPORTED; import static org.apache.dubbo.common.constants.RegistryConstants.DEFAULT_HASHMAP_LOAD_FACTOR; import static org.apache.dubbo.common.constants.RegistryConstants.EMPTY_PROTOCOL; +import static org.apache.dubbo.common.constants.RegistryConstants.REGISTER_MODE_KEY; +import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_KEY; import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_TYPE_KEY; import static org.apache.dubbo.common.constants.RegistryConstants.SERVICE_REGISTRY_TYPE; import static org.apache.dubbo.registry.Constants.CONFIGURATORS_SUFFIX; @@ -498,6 +504,18 @@ protected void destroyAllInvokers() { this.destroyInvokers(); } + @Override + protected Map getDirectoryMeta() { + String registryKey = Optional.ofNullable(getRegistry()) + .map(Registry::getUrl) + .map(url -> url.getParameter(RegistryConstants.REGISTRY_CLUSTER_KEY, url.getParameter(RegistryConstants.REGISTRY_KEY, url.getProtocol()))) + .orElse("unknown"); + Map metas = new HashMap<>(); + metas.put(REGISTRY_KEY, registryKey); + metas.put(REGISTER_MODE_KEY, INSTANCE_REGISTER_MODE); + return metas; + } + /** * Check whether the invoker in the cache needs to be destroyed * If set attribute of url: refer.autodestroy=false, the invokers will only increase without decreasing,there may be a refer leak diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistryFactory.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistryFactory.java index c5d5ab9c53b..def02318b00 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistryFactory.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistryFactory.java @@ -26,6 +26,11 @@ public class ServiceDiscoveryRegistryFactory extends AbstractRegistryFactory { + @Override + protected String createRegistryCacheKey(URL url) { + return url.toFullString(); + } + @Override protected Registry createRegistry(URL url) { if (UrlUtils.hasServiceDiscoveryRegistryProtocol(url)) { 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 13434ceabc5..fbb858aac04 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 @@ -17,6 +17,7 @@ package org.apache.dubbo.registry.client.metadata; import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.constants.RegistryConstants; import org.apache.dubbo.common.extension.ExtensionLoader; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; @@ -24,6 +25,8 @@ import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.metadata.MetadataInfo; import org.apache.dubbo.metadata.MetadataService; +import org.apache.dubbo.metrics.event.MetricsEventBus; +import org.apache.dubbo.metrics.registry.event.RegistryEvent; import org.apache.dubbo.registry.client.DefaultServiceInstance; import org.apache.dubbo.registry.client.DefaultServiceInstance.Endpoint; import org.apache.dubbo.registry.client.ServiceDiscovery; @@ -33,6 +36,7 @@ import org.apache.dubbo.rpc.model.ApplicationModel; import java.util.ArrayList; +import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -44,6 +48,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.PORT_KEY; import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY; import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY; +import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_KEY; import static org.apache.dubbo.common.utils.StringUtils.isBlank; import static org.apache.dubbo.registry.integration.InterfaceCompatibleRegistryProtocol.DEFAULT_REGISTER_PROVIDER_KEYS; import static org.apache.dubbo.rpc.Constants.DEPRECATED_KEY; @@ -201,7 +206,22 @@ public static void registerMetadataAndInstance(ApplicationModel applicationModel LOGGER.info("Start registering instance address to registry."); RegistryManager registryManager = applicationModel.getBeanFactory().getBean(RegistryManager.class); // register service instance - registryManager.getServiceDiscoveries().forEach(ServiceDiscovery::register); + List serviceDiscoveries = registryManager.getServiceDiscoveries(); + for (ServiceDiscovery serviceDiscovery : serviceDiscoveries) { + MetricsEventBus.post(RegistryEvent.toRegisterEvent(applicationModel, + Collections.singletonList(getServiceDiscoveryName(serviceDiscovery))), + () -> { + // register service instance + serviceDiscoveries.forEach(ServiceDiscovery::register); + return null; + } + ); + } + } + + private static String getServiceDiscoveryName(ServiceDiscovery serviceDiscovery) { + return serviceDiscovery.getUrl().getParameter(RegistryConstants.REGISTRY_CLUSTER_KEY, + serviceDiscovery.getUrl().getParameter(REGISTRY_KEY)); } public static void refreshMetadataAndInstance(ApplicationModel applicationModel) { diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/StandardMetadataServiceURLBuilder.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/StandardMetadataServiceURLBuilder.java index 20f55a6edb0..2aae71f30e1 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/StandardMetadataServiceURLBuilder.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/StandardMetadataServiceURLBuilder.java @@ -107,7 +107,6 @@ private URL generateWithMetadata(String serviceName, String host, Map + String registryClusterName = registry.getUrl().getParameter(RegistryConstants.REGISTRY_CLUSTER_KEY, registry.getUrl().getParameter(PROTOCOL_KEY)); + MetricsEventBus.post(RegistryEvent.toSubscribeEvent(applicationModel,registryClusterName), () -> { super.subscribe(url); return null; @@ -644,6 +650,18 @@ private boolean isValidCategory(URL url) { return false; } + @Override + protected Map getDirectoryMeta() { + String registryKey = Optional.ofNullable(getRegistry()) + .map(Registry::getUrl) + .map(url -> url.getParameter(RegistryConstants.REGISTRY_CLUSTER_KEY, url.getProtocol())) + .orElse("unknown"); + Map metas = new HashMap<>(); + metas.put(REGISTRY_KEY, registryKey); + metas.put(REGISTER_MODE_KEY, INTERFACE_REGISTER_MODE); + return metas; + } + private boolean isNotCompatibleFor26x(URL url) { return StringUtils.isEmpty(url.getParameter(COMPATIBLE_CONFIG_KEY)); } diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java index b69376e784d..9db1323951d 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java @@ -18,6 +18,7 @@ import org.apache.dubbo.common.URL; import org.apache.dubbo.common.config.configcenter.DynamicConfiguration; +import org.apache.dubbo.common.constants.RegistryConstants; import org.apache.dubbo.common.deploy.ApplicationDeployer; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; @@ -29,6 +30,8 @@ import org.apache.dubbo.common.utils.NamedThreadFactory; import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.common.utils.UrlUtils; +import org.apache.dubbo.metrics.event.MetricsEventBus; +import org.apache.dubbo.metrics.registry.event.RegistryEvent; import org.apache.dubbo.registry.NotifyListener; import org.apache.dubbo.registry.Registry; import org.apache.dubbo.registry.RegistryFactory; @@ -61,9 +64,11 @@ import org.apache.dubbo.rpc.support.ProtocolUtils; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -224,7 +229,16 @@ private static void register(Registry registry, URL registeredProviderUrl) { ApplicationDeployer deployer = registeredProviderUrl.getOrDefaultApplicationModel().getDeployer(); try { deployer.increaseServiceRefreshCount(); - registry.register(registeredProviderUrl); + String registryName = Optional.ofNullable(registry.getUrl()) + .map(u -> u.getParameter(RegistryConstants.REGISTRY_CLUSTER_KEY, + UrlUtils.isServiceDiscoveryURL(u) ? u.getParameter(REGISTRY_KEY) : u.getProtocol())) + .filter(StringUtils::isNotEmpty) + .orElse("unknown"); + MetricsEventBus.post(RegistryEvent.toRsEvent(registeredProviderUrl.getApplicationModel(), registeredProviderUrl.getServiceKey(), 1, Collections.singletonList(registryName)), + () -> { + registry.register(registeredProviderUrl); + return null; + }); } finally { deployer.decreaseServiceRefreshCount(); } diff --git a/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceDiscoveryFactory.java b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceDiscoveryFactory.java index 56e1c26a427..c6a350a3c06 100644 --- a/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceDiscoveryFactory.java +++ b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceDiscoveryFactory.java @@ -17,11 +17,25 @@ package org.apache.dubbo.registry.nacos; import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.registry.client.AbstractServiceDiscoveryFactory; import org.apache.dubbo.registry.client.ServiceDiscovery; +import static org.apache.dubbo.common.constants.CommonConstants.CONFIG_NAMESPACE_KEY; + public class NacosServiceDiscoveryFactory extends AbstractServiceDiscoveryFactory { + @Override + protected String createRegistryCacheKey(URL url) { + String namespace = url.getParameter(CONFIG_NAMESPACE_KEY); + url = URL.valueOf(url.toServiceStringWithoutResolving()); + if (StringUtils.isNotEmpty(namespace)) { + url = url.addParameter(CONFIG_NAMESPACE_KEY, namespace); + } + + return url.toFullString(); + } + @Override protected ServiceDiscovery createDiscovery(URL registryURL) { return new NacosServiceDiscovery(applicationModel, registryURL); diff --git a/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/ZookeeperRegistry.java b/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/ZookeeperRegistry.java index 8087914b33b..b35ca177970 100644 --- a/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/ZookeeperRegistry.java +++ b/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/ZookeeperRegistry.java @@ -158,7 +158,7 @@ private void checkDestroyed() { public void doRegister(URL url) { try { checkDestroyed(); - zkClient.create(toUrlPath(url), url.getParameter(DYNAMIC_KEY, true), false); + zkClient.create(toUrlPath(url), url.getParameter(DYNAMIC_KEY, true), true); } catch (Throwable e) { throw new RpcException("Failed to register " + url + " to zookeeper " + getUrl() + ", cause: " + e.getMessage(), e); } diff --git a/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/ZookeeperServiceDiscovery.java b/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/ZookeeperServiceDiscovery.java index 1dd2ea8896c..34ee84363a8 100644 --- a/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/ZookeeperServiceDiscovery.java +++ b/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/ZookeeperServiceDiscovery.java @@ -34,6 +34,7 @@ import org.apache.dubbo.common.function.ThrowableFunction; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.utils.CollectionUtils; import org.apache.dubbo.registry.client.AbstractServiceDiscovery; import org.apache.dubbo.registry.client.ServiceDiscovery; import org.apache.dubbo.registry.client.ServiceInstance; @@ -179,6 +180,18 @@ public void removeServiceInstancesChangedListener(ServiceInstancesChangedListene }); } + @Override + public boolean isAvailable() { + //Fix the issue of timeout for all calls to the isAvailable method after the zookeeper is disconnected + return !isDestroy() && isConnected() && CollectionUtils.isNotEmpty(getServices()); + } + + private boolean isConnected() { + if (curatorFramework == null || curatorFramework.getZookeeperClient() == null) { + return false; + } + return curatorFramework.getZookeeperClient().isConnected(); + } private void doInServiceRegistry(ThrowableConsumer consumer) { ThrowableConsumer.execute(serviceDiscovery, s -> consumer.accept(s)); diff --git a/dubbo-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperClient.java b/dubbo-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperClient.java index 59352862196..dc4a5d3fab3 100644 --- a/dubbo-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperClient.java +++ b/dubbo-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperClient.java @@ -51,6 +51,7 @@ import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; @@ -481,13 +482,14 @@ public void process(WatchedEvent event) throws Exception { } if (childListener != null) { - Runnable task = () -> { - try { - childListener.childChanged(path, client.getChildren().usingWatcher(CuratorWatcherImpl.this).forPath(path)); - } catch (Exception e) { - logger.warn(REGISTRY_ZOOKEEPER_EXCEPTION, "", "", "client get children error", e); - } - }; + Runnable task = () -> Optional.ofNullable(childListener) + .ifPresent(c -> { + try { + c.childChanged(path, client.getChildren().usingWatcher(CuratorWatcherImpl.this).forPath(path)); + } catch (Exception e) { + logger.warn(REGISTRY_ZOOKEEPER_EXCEPTION, "", "", "client get children error", e); + } + }); initExecutorIfNecessary(); if (!closed && CURATOR_WATCHER_EXECUTOR_SERVICE != null) { CURATOR_WATCHER_EXECUTOR_SERVICE.execute(task); diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/RpcExceptionFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/RpcExceptionFilter.java new file mode 100644 index 00000000000..3531dab50ea --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/RpcExceptionFilter.java @@ -0,0 +1,60 @@ +/* + * 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.rpc.filter; + +import org.apache.dubbo.common.constants.CommonConstants; +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.rpc.Filter; +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.Result; +import org.apache.dubbo.rpc.RpcException; + + +/** + * RpcExceptionFilter + *

+ * Functions: + *

    + *
  1. The RpcException will be rethrown on consumer side.
  2. + *
+ */ +@Activate(group = CommonConstants.CONSUMER) +public class RpcExceptionFilter implements Filter, Filter.Listener { + + @Override + public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { + return invoker.invoke(invocation); + } + + @Override + public void onResponse(Result appResponse, Invoker invoker, Invocation invocation) { + if (appResponse.hasException()) { + Throwable exception = appResponse.getException(); + // directly throw if it's RpcException + if ((exception instanceof RpcException)) { + throw (RpcException) exception; + } + } + } + + @Override + public void onError(Throwable e, Invoker invoker, Invocation invocation) { + + } +} + diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/TpsLimitFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/TpsLimitFilter.java index e06444d693c..b3eaae5d57f 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/TpsLimitFilter.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/TpsLimitFilter.java @@ -19,6 +19,7 @@ import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.rpc.AsyncRpcResult; import org.apache.dubbo.rpc.Filter; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; @@ -36,7 +37,7 @@ * as it limit checker. If a provider service method is configured with tps(optionally with tps.interval),then * if invocation count exceed the configured tps value (default is -1 which means unlimited) then invocation will get * RpcException. - * */ + */ @Activate(group = CommonConstants.PROVIDER, value = TPS_LIMIT_RATE_KEY) public class TpsLimitFilter implements Filter { @@ -46,12 +47,9 @@ public class TpsLimitFilter implements Filter { public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { if (!tpsLimiter.isAllowable(invoker.getUrl(), invocation)) { - throw new RpcException( - "Failed to invoke service " + - invoker.getInterface().getName() + - "." + - RpcUtils.getMethodName(invocation) + - " because exceed max service tps."); + return AsyncRpcResult.newDefaultAsyncResult(new RpcException("Failed to invoke service " + + invoker.getInterface().getName() + "." + RpcUtils.getMethodName(invocation) + " because exceed max service tps.") + , invocation); } return invoker.invoke(invocation); diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter b/dubbo-rpc/dubbo-rpc-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter index dcc7bd45ec6..d246ac82e5f 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter +++ b/dubbo-rpc/dubbo-rpc-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter @@ -15,3 +15,4 @@ tps=org.apache.dubbo.rpc.filter.TpsLimitFilter profiler-server=org.apache.dubbo.rpc.filter.ProfilerServerFilter adaptiveLoadBalance=org.apache.dubbo.rpc.filter.AdaptiveLoadBalanceFilter active-limit=org.apache.dubbo.rpc.filter.ActiveLimitFilter +rpc-exception=org.apache.dubbo.rpc.filter.RpcExceptionFilter diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/tps/TpsLimitFilterTest.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/tps/TpsLimitFilterTest.java index 18ec0031e2f..a91aa25eaef 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/tps/TpsLimitFilterTest.java +++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/tps/TpsLimitFilterTest.java @@ -19,11 +19,11 @@ import org.apache.dubbo.common.URL; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcException; import org.apache.dubbo.rpc.filter.TpsLimitFilter; import org.apache.dubbo.rpc.support.MockInvocation; import org.apache.dubbo.rpc.support.MyInvoker; - import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -54,12 +54,12 @@ void testFail() throws Exception { Invoker invoker = new MyInvoker(url); Invocation invocation = new MockInvocation(); for (int i = 0; i < 10; i++) { - try { - filter.invoke(invoker, invocation); - } catch (Exception e) { - assertTrue(i >= 5); - throw e; + Result re = filter.invoke(invoker, invocation); + if (i >= 5) { + assertTrue(re.hasException()); + throw re.getException(); } + } }); diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/PathAndInvokerMapper.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/PathAndInvokerMapper.java index a9fc5c2d2d5..d04b6529580 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/PathAndInvokerMapper.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/PathAndInvokerMapper.java @@ -57,7 +57,8 @@ public void addPathAndInvoker(Map metadataMap, /** - * get rest method metadata by path matcher + * get rest method metadata by path matcher + * * @param pathMatcher * @return */ @@ -100,13 +101,17 @@ public void addPathMatcherToPathMap(PathMatcher pathMatcher, if (pathMatcherPairMap.containsKey(pathMatcher)) { - InvokerAndRestMethodMetadataPair beforeMetadata = pathMatcherPairMap.get(pathMatcher); + // cover the old service metadata when current interface is old interface & current method desc equals old`s method desc,else ,throw double check exception - throw new DoublePathCheckException( - "dubbo rest double path check error, current path is: " + pathMatcher - + " ,and service method is: " + invokerRestMethodMetadataPair.getRestMethodMetadata().getReflectMethod() - + "before service method is: " + beforeMetadata.getRestMethodMetadata().getReflectMethod() - ); + InvokerAndRestMethodMetadataPair beforeMetadata = pathMatcherPairMap.get(pathMatcher); + // true when reExport + if (!invokerRestMethodMetadataPair.compareServiceMethod(beforeMetadata)){ + throw new DoublePathCheckException( + "dubbo rest double path check error, current path is: " + pathMatcher + + " ,and service method is: " + invokerRestMethodMetadataPair.getRestMethodMetadata().getReflectMethod() + + "before service method is: " + beforeMetadata.getRestMethodMetadata().getReflectMethod() + ); + } } pathMatcherPairMap.put(pathMatcher, invokerRestMethodMetadataPair); diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/pair/InvokerAndRestMethodMetadataPair.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/pair/InvokerAndRestMethodMetadataPair.java index 0075275e490..70380c986b2 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/pair/InvokerAndRestMethodMetadataPair.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/pair/InvokerAndRestMethodMetadataPair.java @@ -19,8 +19,11 @@ import org.apache.dubbo.metadata.rest.RestMethodMetadata; import org.apache.dubbo.rpc.Invoker; +import java.lang.reflect.Method; +import java.util.Arrays; + /** - * for invoker & restMethodMetadata pair + * for invoker & restMethodMetadata pair */ public class InvokerAndRestMethodMetadataPair { @@ -45,5 +48,36 @@ public static InvokerAndRestMethodMetadataPair pair(Invoker invoker, RestMethodM return new InvokerAndRestMethodMetadataPair(invoker, restMethodMetadata); } + /** + * same interface & same method desc + * + * @param beforeMetadata + * @return + */ + public boolean compareServiceMethod(InvokerAndRestMethodMetadataPair beforeMetadata) { + + Class currentServiceInterface = this.invoker.getInterface(); + Class beforeServiceInterface = beforeMetadata.getInvoker().getInterface(); + + if (!currentServiceInterface.equals(beforeServiceInterface)) { + return false; + } + + + Method beforeServiceMethod = beforeMetadata.getRestMethodMetadata().getReflectMethod(); + + Method currentReflectMethod = this.restMethodMetadata.getReflectMethod(); + + if (beforeServiceMethod.getName().equals(currentReflectMethod.getName()) // method name + // method param types + && Arrays.toString(beforeServiceMethod.getParameterTypes()).equals(Arrays.toString(currentReflectMethod.getParameterTypes()))) { + return true; + } + + return false; + + + } + } diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/JaxrsRestProtocolTest.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/JaxrsRestProtocolTest.java index eed6639cd14..21bb14b9113 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/JaxrsRestProtocolTest.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/JaxrsRestProtocolTest.java @@ -460,14 +460,19 @@ void testDoubleCheckException() { Map pathContainPathVariableToServiceMap = serviceRestMetadata.getPathUnContainPathVariableToServiceMap(); + Invoker invokerNew = proxy.getInvoker(new TestInterface() { + }, TestInterface.class, exportUrl); pathAndInvokerMapper.addPathAndInvoker(pathContainPathVariableToServiceMap, invoker); - pathAndInvokerMapper.addPathAndInvoker(pathContainPathVariableToServiceMap, invoker); + pathAndInvokerMapper.addPathAndInvoker(pathContainPathVariableToServiceMap, invokerNew); }); } + public static interface TestInterface{} + + @Test void testMapParam() { DemoService server = new DemoServiceImpl(); @@ -722,6 +727,22 @@ void testCollectionResult() { exporter.unexport(); } + @Test + void testReExport() { + DemoService server = new DemoServiceImpl(); + + URL url = this.registerProvider(exportUrl, server, DemoService.class); + + URL nettyUrl = url.addParameter(SERVER_KEY, "netty"); + + Exporter exporter = protocol.export(proxy.getInvoker(server, DemoService.class, nettyUrl)); + nettyUrl = url.addParameter("SERVER_KEY", "netty"); + exporter = protocol.export(proxy.getInvoker(server, DemoService.class, nettyUrl)); + + + exporter.unexport(); + } + private URL registerProvider(URL url, Object impl, Class interfaceClass) { ServiceDescriptor serviceDescriptor = repository.registerService(interfaceClass); ProviderModel providerModel = new ProviderModel( diff --git a/dubbo-spring-boot/dubbo-spring-boot-starters/observability/pom.xml b/dubbo-spring-boot/dubbo-spring-boot-starters/observability/pom.xml index af7d700bdd8..5a522da1a4d 100644 --- a/dubbo-spring-boot/dubbo-spring-boot-starters/observability/pom.xml +++ b/dubbo-spring-boot/dubbo-spring-boot-starters/observability/pom.xml @@ -38,8 +38,8 @@
- 1.11.1 - 1.1.2 + 1.11.2 + 1.1.3 1.28.0 2.16.4 0.16.0 diff --git a/dubbo-spring-boot/pom.xml b/dubbo-spring-boot/pom.xml index eb750294d3e..02d056afe07 100644 --- a/dubbo-spring-boot/pom.xml +++ b/dubbo-spring-boot/pom.xml @@ -40,7 +40,7 @@
- 2.7.13 + 2.7.14 ${revision} 2.20.0