diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterInvoker.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterInvoker.java index 445aaf236b..7ac76c2ac3 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterInvoker.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterInvoker.java @@ -18,6 +18,8 @@ package org.apache.dubbo.rpc.cluster.support.wrapper; import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.url.component.ServiceConfigURL; import org.apache.dubbo.common.utils.NetUtils; import org.apache.dubbo.rpc.Exporter; @@ -38,12 +40,14 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; +import static org.apache.dubbo.common.constants.CommonConstants.CLUSTER_KEY; import static org.apache.dubbo.rpc.Constants.GENERIC_KEY; import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL; import static org.apache.dubbo.rpc.Constants.SCOPE_KEY; import static org.apache.dubbo.rpc.Constants.SCOPE_REMOTE; import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL; import static org.apache.dubbo.rpc.cluster.Constants.PEER_KEY; +import static org.apache.dubbo.common.constants.CommonConstants.BROADCAST_CLUSTER; /** * ScopeClusterInvoker is a cluster invoker which handles the invocation logic of a single service in a specific scope. @@ -53,6 +57,10 @@ import static org.apache.dubbo.rpc.cluster.Constants.PEER_KEY; * @param the type of service interface */ public class ScopeClusterInvoker implements ClusterInvoker, ExporterChangeListener { + + private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(ScopeClusterInvoker.class); + + private final Object createLock = new Object(); private Protocol protocolSPI; private final Directory directory; @@ -119,14 +127,30 @@ public class ScopeClusterInvoker implements ClusterInvoker, ExporterChange */ @Override public Result invoke(Invocation invocation) throws RpcException { + // When broadcasting, it should be called remotely. + if (BROADCAST_CLUSTER.equalsIgnoreCase(getUrl().getParameter(CLUSTER_KEY))) { + if (logger.isDebugEnabled()) { + logger.debug("Performing broadcast call for method: " + invocation.getMethodName() + " of service: " + getUrl().getServiceKey()); + } + return invoker.invoke(invocation); + } if (peerFlag) { + if (logger.isDebugEnabled()) { + logger.debug("Performing point-to-point call for method: " + invocation.getMethodName() + " of service: " + getUrl().getServiceKey()); + } // If it's a point-to-point direct connection, invoke the original Invoker return invoker.invoke(invocation); } if (isInjvmExported()) { + if (logger.isDebugEnabled()) { + logger.debug("Performing local JVM call for method: " + invocation.getMethodName() + " of service: " + getUrl().getServiceKey()); + } // If it's exported to the local JVM, invoke the corresponding Invoker return injvmInvoker.invoke(invocation); } + if (logger.isDebugEnabled()) { + logger.debug("Performing remote call for method: " + invocation.getMethodName() + " of service: " + getUrl().getServiceKey()); + } // Otherwise, delegate the invocation to the original Invoker return invoker.invoke(invocation); } diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/filter/MetricsClusterFilterTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/filter/MetricsClusterFilterTest.java index 629e3fc6f1..a0c00adb2f 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/filter/MetricsClusterFilterTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/filter/MetricsClusterFilterTest.java @@ -80,7 +80,7 @@ class MetricsClusterFilterTest { collector = applicationModel.getBeanFactory().getOrRegisterBean(DefaultMetricsCollector.class); if(!initApplication.get()) { - collector.collectApplication(applicationModel); + collector.collectApplication(); initApplication.set(true); } filter.setApplicationModel(applicationModel); diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterInvokerTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterInvokerTest.java index 44132df55c..2d54ba72e8 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterInvokerTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterInvokerTest.java @@ -320,6 +320,24 @@ class ScopeClusterInvokerTest { Assertions.assertEquals("doSomething8", ret3.getValue()); } + @Test + void testBroadcast() { + URL url = URL.valueOf("remote://1.2.3.4/" + DemoService.class.getName()); + url = url.addParameter(REFER_KEY, + URL.encode(PATH_KEY + "=" + DemoService.class.getName())); + url = url.addParameter("cluster","broadcast"); + url = url.setScopeModel(ApplicationModel.defaultModel().getDefaultModule()); + Invoker cluster = getClusterInvoker(url); + + invokers.add(cluster); + + RpcInvocation invocation = new RpcInvocation(); + invocation.setMethodName("doSomething8"); + invocation.setParameterTypes(new Class[]{}); + Result ret = cluster.invoke(invocation); + Assertions.assertEquals("doSomething8", ret.getValue()); + } + private Invoker getClusterInvoker(URL url) { final URL durl = url.addParameter("proxy", "jdk"); invokers.clear(); 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 266cacc7a5..0cc9e06c6f 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 @@ -239,6 +239,10 @@ public interface CommonConstants { String REMOTE_METADATA_STORAGE_TYPE = "remote"; + String INTERFACE_REGISTER_MODE = "interface"; + + String DEFAULT_REGISTER_MODE = "all"; + String GENERIC_KEY = "generic"; /** diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/MetricsConstants.java b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/MetricsConstants.java index afd0bedfe5..f349e18d2f 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/MetricsConstants.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/MetricsConstants.java @@ -28,6 +28,8 @@ public interface MetricsConstants { String TAG_APPLICATION_NAME = "application.name"; + String TAG_APPLICATION_MODULE = "application.module.id"; + String TAG_INTERFACE_KEY = "interface"; String TAG_METHOD_KEY = "method"; diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/URLParam.java b/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/URLParam.java index cf6ba67510..1500787fda 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/URLParam.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/URLParam.java @@ -22,6 +22,7 @@ import org.apache.dubbo.common.url.component.param.DynamicParamTable; import org.apache.dubbo.common.utils.CollectionUtils; import org.apache.dubbo.common.utils.StringUtils; +import java.util.AbstractMap; import java.util.Arrays; import java.util.BitSet; import java.util.Collection; @@ -247,7 +248,7 @@ public class URLParam { * copy-on-write mode, urlParam reference will be changed after modify actions. * If wishes to get the result after modify, please use {@link URLParamMap#getUrlParam()} */ - public static class URLParamMap implements Map { + public static class URLParamMap extends AbstractMap { private URLParam urlParam; public URLParamMap(URLParam urlParam) { diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/AnnotationUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/AnnotationUtils.java index 447cc22625..c245f39b55 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/AnnotationUtils.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/AnnotationUtils.java @@ -418,7 +418,7 @@ public interface AnnotationUtils { static boolean isAnnotationPresent(AnnotatedElement annotatedElement, String annotationClassName) { ClassLoader classLoader = annotatedElement.getClass().getClassLoader(); Class resolvedType = resolveClass(annotationClassName, classLoader); - if (!Annotation.class.isAssignableFrom(resolvedType)) { + if (resolvedType == null || !Annotation.class.isAssignableFrom(resolvedType)) { return false; } return isAnnotationPresent(annotatedElement, (Class) resolvedType); diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ReflectionUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ReflectionUtils.java index b6b686e50b..bf5ec423e2 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ReflectionUtils.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ReflectionUtils.java @@ -147,4 +147,9 @@ public class ReflectionUtils { } } + public static boolean match(Class clazz, Class interfaceClass, Object event) { + List> eventTypes = ReflectionUtils.getClassGenerics(clazz, interfaceClass); + return eventTypes.stream().allMatch(eventType -> eventType.isInstance(event)); + } + } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractMethodConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractMethodConfig.java index d1978f62c4..ca8d15c68a 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractMethodConfig.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractMethodConfig.java @@ -23,7 +23,9 @@ import org.apache.dubbo.rpc.model.ModuleModel; import org.apache.dubbo.rpc.model.ScopeModel; import java.beans.Transient; +import java.util.HashMap; import java.util.Map; +import java.util.Optional; /** * AbstractMethodConfig @@ -240,7 +242,8 @@ public abstract class AbstractMethodConfig extends AbstractConfig { } public Map getParameters() { - return parameters; + this.parameters = Optional.ofNullable(this.parameters).orElseGet(HashMap::new); + return this.parameters; } public void setParameters(Map parameters) { diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/MetricsConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/MetricsConfig.java index 62e1882143..a7540dc63e 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/MetricsConfig.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/MetricsConfig.java @@ -19,8 +19,8 @@ package org.apache.dubbo.config; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.utils.UrlUtils; import org.apache.dubbo.config.nested.AggregationConfig; -import org.apache.dubbo.config.nested.PrometheusConfig; import org.apache.dubbo.config.nested.HistogramConfig; +import org.apache.dubbo.config.nested.PrometheusConfig; import org.apache.dubbo.config.support.Nested; import org.apache.dubbo.rpc.model.ApplicationModel; @@ -56,6 +56,11 @@ public class MetricsConfig extends AbstractConfig { */ private Boolean enableMetadata; + /** + * Export metrics service. + */ + private Boolean exportMetricsService; + /** * @deprecated After metrics config is refactored. * This parameter should no longer use and will be deleted in the future. @@ -186,6 +191,14 @@ public class MetricsConfig extends AbstractConfig { this.enableMetadata = enableMetadata; } + public Boolean getExportMetricsService() { + return exportMetricsService; + } + + public void setExportMetricsService(Boolean exportMetricsService) { + this.exportMetricsService = exportMetricsService; + } + public Boolean getEnableThreadpool() { return enableThreadpool; } diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/url/URLParamTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/url/URLParamTest.java index e881841152..3c1665cd79 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/url/URLParamTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/url/URLParamTest.java @@ -220,6 +220,7 @@ class URLParamTest { Assertions.assertFalse(urlParam1.getParameters().containsKey("aaa")); Assertions.assertFalse(urlParam1.getParameters().containsKey("version")); Assertions.assertFalse(urlParam1.getParameters().containsKey(new Object())); + Assertions.assertEquals(new HashMap<>(urlParam1.getParameters()).toString(), urlParam1.getParameters().toString()); URLParam urlParam2 = URLParam.parse("aaa=aaa&version=1.0"); URLParam.URLParamMap urlParam2Map = (URLParam.URLParamMap) urlParam2.getParameters(); @@ -284,6 +285,10 @@ class URLParamTest { set.add(urlParam4.getParameters()); Assertions.assertEquals(2,set.size()); + + URLParam urlParam5 = URLParam.parse("version=1.0"); + Assertions.assertEquals(new HashMap<>(urlParam5.getParameters()).toString(), urlParam5.getParameters().toString()); + } @Test diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Filter.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Filter.java index 4ccde294e3..fa7b3e40a3 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Filter.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Filter.java @@ -17,6 +17,8 @@ package com.alibaba.dubbo.rpc; +import org.apache.dubbo.rpc.AsyncRpcResult; + @Deprecated public interface Filter extends org.apache.dubbo.rpc.Filter { @@ -26,8 +28,18 @@ public interface Filter extends org.apache.dubbo.rpc.Filter { default org.apache.dubbo.rpc.Result invoke(org.apache.dubbo.rpc.Invoker invoker, org.apache.dubbo.rpc.Invocation invocation) throws org.apache.dubbo.rpc.RpcException { - Result.CompatibleResult result = (Result.CompatibleResult) invoke(new Invoker.CompatibleInvoker<>(invoker), - new Invocation.CompatibleInvocation(invocation)); - return result.getDelegate(); + Result invokeResult = invoke(new Invoker.CompatibleInvoker<>(invoker), + new Invocation.CompatibleInvocation(invocation)); + + if (invokeResult instanceof Result.CompatibleResult) { + return invokeResult; + } + + AsyncRpcResult asyncRpcResult = AsyncRpcResult.newDefaultAsyncResult(invocation); + asyncRpcResult.setValue(invokeResult.getValue()); + asyncRpcResult.setException(invokeResult.getException()); + asyncRpcResult.setObjectAttachments(invokeResult.getObjectAttachments()); + + return asyncRpcResult; } } diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Invoker.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Invoker.java index 124b063de6..fc38498649 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Invoker.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Invoker.java @@ -17,6 +17,8 @@ package com.alibaba.dubbo.rpc; +import org.apache.dubbo.rpc.AsyncRpcResult; + import com.alibaba.dubbo.common.URL; @Deprecated @@ -54,9 +56,22 @@ public interface Invoker extends org.apache.dubbo.rpc.Invoker { public org.apache.dubbo.rpc.Result invoke(org.apache.dubbo.rpc.Invocation invocation) throws org.apache.dubbo.rpc.RpcException { return new Result.CompatibleResult(invoker.invoke(invocation)); } - + @Override public Result invoke(Invocation invocation) throws RpcException { + if (invoker instanceof Invoker) { + Result result = ((Invoker) invoker).invoke(invocation); + if (result instanceof Result.CompatibleResult) { + return result; + } else { + AsyncRpcResult asyncRpcResult = AsyncRpcResult.newDefaultAsyncResult(invocation.getOriginal()); + asyncRpcResult.setValue(result.getValue()); + asyncRpcResult.setException(result.getException()); + asyncRpcResult.setObjectAttachments(result.getObjectAttachments()); + + return new Result.CompatibleResult(asyncRpcResult); + } + } return new Result.CompatibleResult(invoker.invoke(invocation.getOriginal())); } diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Result.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Result.java index 3a1da951c0..009ee707c2 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Result.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Result.java @@ -64,35 +64,7 @@ public interface Result extends org.apache.dubbo.rpc.Result { return null; } - abstract class AbstractResult implements Result { - - @Override - public void setValue(Object value) { - - } - - @Override - public org.apache.dubbo.rpc.Result whenCompleteWithContext(BiConsumer fn) { - return null; - } - - @Override - public CompletableFuture thenApply(Function fn) { - return null; - } - - @Override - public org.apache.dubbo.rpc.Result get() throws InterruptedException, ExecutionException { - return null; - } - - @Override - public org.apache.dubbo.rpc.Result get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { - return null; - } - } - - class CompatibleResult extends AbstractResult { + class CompatibleResult implements Result { private org.apache.dubbo.rpc.Result delegate; public CompatibleResult(org.apache.dubbo.rpc.Result result) { @@ -177,5 +149,20 @@ public interface Result extends org.apache.dubbo.rpc.Result { public void setObjectAttachment(String key, Object value) { delegate.setObjectAttachment(key, value); } + + @Override + public CompletableFuture thenApply(Function fn) { + return delegate.thenApply(fn); + } + + @Override + public org.apache.dubbo.rpc.Result get() throws InterruptedException, ExecutionException { + return delegate.get(); + } + + @Override + public org.apache.dubbo.rpc.Result get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { + return delegate.get(timeout, unit); + } } } diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/RpcResult.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/RpcResult.java new file mode 100644 index 0000000000..d62eb09418 --- /dev/null +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/RpcResult.java @@ -0,0 +1,35 @@ +/* + * 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 com.alibaba.dubbo.rpc; + +import org.apache.dubbo.rpc.AppResponse; + +@Deprecated +public class RpcResult extends AppResponse implements com.alibaba.dubbo.rpc.Result { + + public RpcResult() { + } + + public RpcResult(Object result) { + super(result); + } + + public RpcResult(Throwable exception) { + super(exception); + } + +} diff --git a/dubbo-compatible/src/test/java/org/apache/dubbo/filter/FilterTest.java b/dubbo-compatible/src/test/java/org/apache/dubbo/filter/FilterTest.java index e50d67d650..24996c2c32 100644 --- a/dubbo-compatible/src/test/java/org/apache/dubbo/filter/FilterTest.java +++ b/dubbo-compatible/src/test/java/org/apache/dubbo/filter/FilterTest.java @@ -18,11 +18,11 @@ package org.apache.dubbo.filter; import org.apache.dubbo.rpc.RpcException; +import org.apache.dubbo.rpc.RpcInvocation; import com.alibaba.dubbo.rpc.Filter; import com.alibaba.dubbo.rpc.Invocation; import com.alibaba.dubbo.rpc.Invoker; -import com.alibaba.dubbo.rpc.Result; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -46,15 +46,23 @@ class FilterTest { } @Test - void testDefault() { + void testDefault() throws Throwable { Invoker invoker = new LegacyInvoker(null); - Invocation invocation = new LegacyInvocation("bbb"); - Result res = myFilter.invoke(invoker, invocation); - System.out.println(res); + org.apache.dubbo.rpc.Invocation invocation = new RpcInvocation(null, "echo", "DemoService", "DemoService", new Class[]{String.class}, new Object[]{"bbb"}); + org.apache.dubbo.rpc.Result res = myFilter.invoke(invoker, invocation); + Assertions.assertEquals("alibaba", res.recreate()); + } + + @Test + void testRecreate() throws Throwable { + Invoker invoker = new LegacyInvoker(null); + org.apache.dubbo.rpc.Invocation invocation = new RpcInvocation(null, "echo", "DemoService", "DemoService", new Class[]{String.class}, new Object[]{"cc"}); + org.apache.dubbo.rpc.Result res = myFilter.invoke(invoker, invocation); + Assertions.assertEquals("123test", res.recreate()); } @AfterAll public static void tear() { - Assertions.assertEquals(2, MyFilter.count); + Assertions.assertEquals(3, MyFilter.count); } } diff --git a/dubbo-compatible/src/test/java/org/apache/dubbo/filter/LegacyInvoker.java b/dubbo-compatible/src/test/java/org/apache/dubbo/filter/LegacyInvoker.java index b1d19b57c3..328b842321 100644 --- a/dubbo-compatible/src/test/java/org/apache/dubbo/filter/LegacyInvoker.java +++ b/dubbo-compatible/src/test/java/org/apache/dubbo/filter/LegacyInvoker.java @@ -17,7 +17,6 @@ package org.apache.dubbo.filter; -import org.apache.dubbo.rpc.AppResponse; import org.apache.dubbo.service.DemoService; import com.alibaba.dubbo.common.URL; @@ -25,6 +24,7 @@ import com.alibaba.dubbo.rpc.Invocation; import com.alibaba.dubbo.rpc.Invoker; import com.alibaba.dubbo.rpc.Result; import com.alibaba.dubbo.rpc.RpcException; +import com.alibaba.dubbo.rpc.RpcResult; public class LegacyInvoker implements Invoker { @@ -58,13 +58,13 @@ public class LegacyInvoker implements Invoker { } public Result invoke(Invocation invocation) throws RpcException { - AppResponse result = new AppResponse(); + RpcResult result = new RpcResult(); if (!hasException) { result.setValue("alibaba"); } else { result.setException(new RuntimeException("mocked exception")); } - return new Result.CompatibleResult(result); + return result; } @Override diff --git a/dubbo-compatible/src/test/java/org/apache/dubbo/filter/MyFilter.java b/dubbo-compatible/src/test/java/org/apache/dubbo/filter/MyFilter.java index b7d7e24e70..68c5c8786b 100644 --- a/dubbo-compatible/src/test/java/org/apache/dubbo/filter/MyFilter.java +++ b/dubbo-compatible/src/test/java/org/apache/dubbo/filter/MyFilter.java @@ -22,6 +22,7 @@ import com.alibaba.dubbo.rpc.Invocation; import com.alibaba.dubbo.rpc.Invoker; import com.alibaba.dubbo.rpc.Result; import com.alibaba.dubbo.rpc.RpcException; +import com.alibaba.dubbo.rpc.RpcResult; public class MyFilter implements Filter { @@ -36,6 +37,10 @@ public class MyFilter implements Filter { throw new RpcException(new IllegalArgumentException("arg0 illegal")); } + if (invocation.getArguments()[0].equals("cc")) { + return new RpcResult("123test"); + } + Result tmp = invoker.invoke(invocation); return tmp; } diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/DubboShutdownHook.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/DubboShutdownHook.java index 3172525e72..def7a7ac74 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/DubboShutdownHook.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/DubboShutdownHook.java @@ -90,7 +90,7 @@ public class DubboShutdownHook extends Thread { boolean hasModuleBindSpring = false; // check if any modules are bound to Spring - for (ModuleModel module: applicationModel.getModuleModels()) { + for (ModuleModel module : applicationModel.getModuleModels()) { if (module.isLifeCycleManagedExternally()) { hasModuleBindSpring = true; break; @@ -104,14 +104,14 @@ public class DubboShutdownHook extends Thread { To avoid shutdown conflicts between Dubbo and Spring, wait for the modules bound to Spring to be handled by Spring until timeout. */ - logger.info("Waiting for modules managed by Spring to be shutdown."); + logger.info("Waiting for modules(" + applicationModel.getDesc() + ") managed by Spring to be shutdown."); while (!applicationModel.isDestroyed() && hasModuleBindSpring && (System.currentTimeMillis() - start) < timeout) { try { TimeUnit.MILLISECONDS.sleep(10); hasModuleBindSpring = false; if (!applicationModel.isDestroyed()) { - for (ModuleModel module: applicationModel.getModuleModels()) { + for (ModuleModel module : applicationModel.getModuleModels()) { if (module.isLifeCycleManagedExternally()) { hasModuleBindSpring = true; break; @@ -123,11 +123,15 @@ public class DubboShutdownHook extends Thread { Thread.currentThread().interrupt(); } } + if (!applicationModel.isDestroyed()) { + long usage = System.currentTimeMillis() - start; + logger.info("Dubbo wait for application(" + applicationModel.getDesc() + ") managed by Spring to be shutdown failed, " + + "time usage: " + usage + "ms"); + } } } if (!applicationModel.isDestroyed()) { - logger.info("Dubbo shuts down application " + - "after Spring fails to do in time or doesn't do it completely."); + logger.info("Dubbo shutdown hooks execute now. " + applicationModel.getDesc()); applicationModel.destroy(); } } 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 faf8123717..a7eede5af9 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 @@ -38,6 +38,7 @@ import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.threadpool.manager.ExecutorRepository; import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository; import org.apache.dubbo.common.utils.ArrayUtils; +import org.apache.dubbo.common.utils.ClassUtils; import org.apache.dubbo.common.utils.CollectionUtils; import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.config.ApplicationConfig; @@ -373,25 +374,15 @@ public class DefaultApplicationDeployer extends AbstractDeployer configOptional = configManager.getMetrics(); // TODO compatible with old usage of metrics, remove protocol check after new metrics is ready for use. - boolean importMetricsPrometheus; // Use package references instead of config checks - try { - Class.forName("io.micrometer.prometheus.PrometheusConfig"); - importMetricsPrometheus = true; - } catch (ClassNotFoundException e) { - importMetricsPrometheus = false; - } - - if (!importMetricsPrometheus) { - //use old metrics + if (!isSupportPrometheus()) { return; } - MetricsConfig metricsConfig = configOptional.orElse(new MetricsConfig(applicationModel)); if (StringUtils.isBlank(metricsConfig.getProtocol())) { metricsConfig.setProtocol(PROTOCOL_PROMETHEUS); } collector.setCollectEnabled(true); - collector.collectApplication(applicationModel); + collector.collectApplication(); collector.setThreadpoolCollectEnabled(Optional.ofNullable(metricsConfig.getEnableThreadpool()).orElse(true)); MetricsReporterFactory metricsReporterFactory = getExtensionLoader(MetricsReporterFactory.class).getAdaptiveExtension(); MetricsReporter metricsReporter = metricsReporterFactory.createMetricsReporter(metricsConfig.toUrl()); @@ -399,6 +390,18 @@ public class DefaultApplicationDeployer extends AbstractDeployer impleme try { setFailed(ex); logger.error(CONFIG_FAILED_START_MODEL, "", "", "Model start failed: " + msg, ex); - applicationDeployer.notifyModuleChanged(moduleModel, DeployState.STARTED); + applicationDeployer.notifyModuleChanged(moduleModel, DeployState.FAILED); } finally { completeStartFuture(false); } diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ExporterDeployListener.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ExporterDeployListener.java index e7237c875d..f3e34bb4c9 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ExporterDeployListener.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ExporterDeployListener.java @@ -23,6 +23,8 @@ import org.apache.dubbo.registry.client.metadata.MetadataServiceDelegation; import org.apache.dubbo.rpc.model.ApplicationModel; import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE; +import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_REGISTER_MODE; +import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_REGISTER_MODE; import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_METADATA_STORAGE_TYPE; public class ExporterDeployListener implements ApplicationDeployListener, Prioritized { @@ -56,6 +58,13 @@ public class ExporterDeployListener implements ApplicationDeployListener, Priori return type; } + private String getRegisterMode(ApplicationModel applicationModel) { + String type = applicationModel.getApplicationConfigManager().getApplicationOrElseThrow().getRegisterMode(); + if (StringUtils.isEmpty(type)) { + type = DEFAULT_REGISTER_MODE; + } + return type; + } public ConfigurableMetadataServiceExporter getMetadataServiceExporter() { return metadataServiceExporter; @@ -72,7 +81,7 @@ public class ExporterDeployListener implements ApplicationDeployListener, Priori if (metadataServiceExporter == null) { metadataServiceExporter = new ConfigurableMetadataServiceExporter(applicationModel, metadataService); // fixme, let's disable local metadata service export at this moment - if (!REMOTE_METADATA_STORAGE_TYPE.equals(getMetadataType(applicationModel))) { + if (!REMOTE_METADATA_STORAGE_TYPE.equals(getMetadataType(applicationModel)) && !INTERFACE_REGISTER_MODE.equals(getRegisterMode(applicationModel))) { metadataServiceExporter.export(); } } diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployerTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployerTest.java new file mode 100644 index 0000000000..fab3cf577b --- /dev/null +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployerTest.java @@ -0,0 +1,33 @@ +/* + * 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.config.deploy; + +import org.apache.dubbo.common.utils.Assert; +import org.apache.dubbo.rpc.model.ApplicationModel; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class DefaultApplicationDeployerTest { + + @Test + void isSupportPrometheus() { + boolean supportPrometheus = new DefaultApplicationDeployer(ApplicationModel.defaultModel()).isSupportPrometheus(); + Assert.assertTrue(supportPrometheus,"DefaultApplicationDeployer.isSupportPrometheus() should return true"); + } +} diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/DubboAnnotationUtils.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/DubboAnnotationUtils.java index 9a24b0ffc8..5575a24c75 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/DubboAnnotationUtils.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/DubboAnnotationUtils.java @@ -27,7 +27,7 @@ import org.springframework.util.Assert; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -154,7 +154,7 @@ public class DubboAnnotationUtils { */ public static Map convertParameters(String[] parameters) { if (ArrayUtils.isEmpty(parameters)) { - return Collections.emptyMap(); + return new HashMap<>(); } List compatibleParameterArray = Arrays.stream(parameters) diff --git a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd index 24b4cb2a3f..ff36236df0 100644 --- a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd +++ b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd @@ -1087,6 +1087,12 @@ + + + + + + diff --git a/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/util/KubernetesConfigUtils.java b/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/util/KubernetesConfigUtils.java index 2ea596474c..4b54b4c6b0 100644 --- a/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/util/KubernetesConfigUtils.java +++ b/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/util/KubernetesConfigUtils.java @@ -89,7 +89,7 @@ public class KubernetesConfigUtils { .withLoggingInterval(url.getParameter(LOGGING_INTERVAL, base.getLoggingInterval())) // .withTrustCerts(url.getParameter(TRUST_CERTS, base.isTrustCerts())) // - .withHttp2Disable(url.getParameter(HTTP2_DISABLE, base.isTrustCerts())) // + .withHttp2Disable(url.getParameter(HTTP2_DISABLE, base.isHttp2Disable())) // .withHttpProxy(url.getParameter(HTTP_PROXY, base.getHttpProxy())) // .withHttpsProxy(url.getParameter(HTTPS_PROXY, base.getHttpsProxy())) // diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/ApplicationMetricsCollector.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/ApplicationMetricsCollector.java index a9ac60df2e..3f2427cf8c 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/ApplicationMetricsCollector.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/ApplicationMetricsCollector.java @@ -28,9 +28,9 @@ import org.apache.dubbo.metrics.model.key.MetricsKey; */ public interface ApplicationMetricsCollector extends MetricsCollector { - void increment(String applicationName, MetricsKey metricsKey); + void increment(MetricsKey metricsKey); - void addRt(String applicationName, String registryOpType, Long responseTime); + void addRt(String registryOpType, Long responseTime); } 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 03f9478052..d8c6e07e04 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 @@ -46,36 +46,36 @@ public abstract class CombMetricsCollector extends A } @Override - public void setNum(MetricsKeyWrapper metricsKey, String applicationName, String serviceKey, int num) { - this.stats.setServiceKey(metricsKey, applicationName, serviceKey, num); + public void setNum(MetricsKeyWrapper metricsKey, String serviceKey, int num) { + this.stats.setServiceKey(metricsKey, serviceKey, num); } @Override - public void increment(String applicationName, MetricsKey metricsKey) { - this.stats.incrementApp(metricsKey, applicationName, SELF_INCREMENT_SIZE); + public void increment(MetricsKey metricsKey) { + this.stats.incrementApp(metricsKey, SELF_INCREMENT_SIZE); } - public void increment(String applicationName, String serviceKey, MetricsKeyWrapper metricsKeyWrapper, int size) { - this.stats.incrementServiceKey(metricsKeyWrapper, applicationName, serviceKey, size); + public void increment(String serviceKey, MetricsKeyWrapper metricsKeyWrapper, int size) { + this.stats.incrementServiceKey(metricsKeyWrapper, serviceKey, size); } @Override - public void addRt(String applicationName, String registryOpType, Long responseTime) { - stats.calcApplicationRt(applicationName, registryOpType, responseTime); + public void addRt(String registryOpType, Long responseTime) { + stats.calcApplicationRt(registryOpType, responseTime); } - public void addRt(String applicationName, String serviceKey, String registryOpType, Long responseTime) { - stats.calcServiceKeyRt(applicationName, serviceKey, registryOpType, responseTime); + public void addRt(String serviceKey, String registryOpType, Long responseTime) { + stats.calcServiceKeyRt(serviceKey, registryOpType, responseTime); } @Override - public void increment(String applicationName, Invocation invocation, MetricsKeyWrapper wrapper, int size) { - this.stats.incrementMethodKey(wrapper, applicationName, invocation, size); + public void increment(Invocation invocation, MetricsKeyWrapper wrapper, int size) { + this.stats.incrementMethodKey(wrapper, invocation, size); } @Override - public void addRt(String applicationName, Invocation invocation, String registryOpType, Long responseTime) { - stats.calcMethodKeyRt(applicationName, invocation, registryOpType, responseTime); + public void addRt(Invocation invocation, String registryOpType, Long responseTime) { + stats.calcMethodKeyRt(invocation, registryOpType, responseTime); } protected List export(MetricsCategory category) { diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/MethodMetricsCollector.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/MethodMetricsCollector.java index 25732f3416..836de4dcd3 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/MethodMetricsCollector.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/MethodMetricsCollector.java @@ -26,8 +26,8 @@ import org.apache.dubbo.rpc.Invocation; */ public interface MethodMetricsCollector extends MetricsCollector { - void increment(String applicationName, Invocation invocation, MetricsKeyWrapper wrapper, int size); + void increment(Invocation invocation, MetricsKeyWrapper wrapper, int size); - void addRt(String applicationName, Invocation invocation, String registryOpType, Long responseTime); + void addRt(Invocation invocation, String registryOpType, Long responseTime); } diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/ServiceMetricsCollector.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/ServiceMetricsCollector.java index af0aabc635..37cd96ce82 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/ServiceMetricsCollector.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/ServiceMetricsCollector.java @@ -26,10 +26,10 @@ import org.apache.dubbo.metrics.model.key.MetricsKeyWrapper; */ public interface ServiceMetricsCollector extends MetricsCollector { - void increment(String applicationName, String serviceKey, MetricsKeyWrapper wrapper, int size); + void increment(String serviceKey, MetricsKeyWrapper wrapper, int size); - void setNum(MetricsKeyWrapper metricsKey, String applicationName, String serviceKey, int num); + void setNum(MetricsKeyWrapper metricsKey, String serviceKey, int num); - void addRt(String applicationName, String serviceKey, String registryOpType, Long responseTime); + void addRt(String serviceKey, String registryOpType, Long responseTime); } diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/data/ApplicationStatComposite.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/data/ApplicationStatComposite.java index 72b23eb234..47a432e480 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/data/ApplicationStatComposite.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/data/ApplicationStatComposite.java @@ -23,7 +23,8 @@ 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.report.MetricsExport; +import org.apache.dubbo.metrics.report.AbstractMetricsExport; +import org.apache.dubbo.rpc.model.ApplicationModel; import java.util.ArrayList; import java.util.List; @@ -31,42 +32,49 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; -public class ApplicationStatComposite implements MetricsExport { +/** + * Application-level data container, for the initialized MetricsKey, + * different from the null value of the Map type (the key is not displayed when there is no data), + * the key is displayed and the initial data is 0 value of the AtomicLong type + */ +public class ApplicationStatComposite extends AbstractMetricsExport { - private final Map> applicationNumStats = new ConcurrentHashMap<>(); + + public ApplicationStatComposite(ApplicationModel applicationModel) { + super(applicationModel); + } + + private final Map applicationNumStats = new ConcurrentHashMap<>(); public void init(List appKeys) { if (CollectionUtils.isEmpty(appKeys)) { return; } - appKeys.forEach(appKey -> applicationNumStats.put(appKey, new ConcurrentHashMap<>())); + appKeys.forEach(appKey -> applicationNumStats.put(appKey, new AtomicLong(0L))); } - public void incrementSize(MetricsKey metricsKey, String applicationName, int size) { + public void incrementSize(MetricsKey metricsKey, int size) { if (!applicationNumStats.containsKey(metricsKey)) { return; } - applicationNumStats.get(metricsKey).computeIfAbsent(applicationName, k -> new AtomicLong(0L)).getAndAdd(size); + applicationNumStats.get(metricsKey).getAndAdd(size); } public List export(MetricsCategory category) { List list = new ArrayList<>(); for (MetricsKey type : applicationNumStats.keySet()) { - Map stringAtomicLongMap = applicationNumStats.get(type); - for (String applicationName : stringAtomicLongMap.keySet()) { - list.add(convertToSample(applicationName, type, category, stringAtomicLongMap.get(applicationName))); - } + list.add(convertToSample(type, category, applicationNumStats.get(type))); } return list; } @SuppressWarnings({"rawtypes"}) - private GaugeMetricSample convertToSample(String applicationName, MetricsKey type, MetricsCategory category, AtomicLong targetNumber) { - return new GaugeMetricSample<>(type, MetricsSupport.applicationTags(applicationName), category, targetNumber, AtomicLong::get); + private GaugeMetricSample convertToSample(MetricsKey type, MetricsCategory category, AtomicLong targetNumber) { + return new GaugeMetricSample<>(type, MetricsSupport.applicationTags(getApplicationModel()), category, targetNumber, AtomicLong::get); } - public Map> getApplicationNumStats() { + public Map getApplicationNumStats() { return applicationNumStats; } 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 7f99f5e85c..b4798b83ef 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 @@ -24,6 +24,7 @@ import org.apache.dubbo.metrics.model.key.MetricsKeyWrapper; import org.apache.dubbo.metrics.model.sample.MetricSample; import org.apache.dubbo.metrics.report.MetricsExport; import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.model.ApplicationModel; import java.util.ArrayList; import java.util.List; @@ -36,60 +37,63 @@ import java.util.List; */ public abstract class BaseStatComposite implements MetricsExport { - private final ApplicationStatComposite applicationStatComposite = new ApplicationStatComposite(); - private final ServiceStatComposite serviceStatComposite = new ServiceStatComposite(); + private ApplicationStatComposite applicationStatComposite; + private ServiceStatComposite serviceStatComposite; - private final MethodStatComposite methodStatComposite = new MethodStatComposite(); - private final RtStatComposite rtStatComposite = new RtStatComposite(); + private MethodStatComposite methodStatComposite; + private RtStatComposite rtStatComposite; - public BaseStatComposite() { - init(applicationStatComposite); - init(serviceStatComposite); - init(methodStatComposite); - init(rtStatComposite); + public BaseStatComposite(ApplicationModel applicationModel) { + init(new ApplicationStatComposite(applicationModel)); + init(new ServiceStatComposite(applicationModel)); + init(new MethodStatComposite(applicationModel)); + init(new RtStatComposite(applicationModel)); } protected void init(ApplicationStatComposite applicationStatComposite) { + this.applicationStatComposite = applicationStatComposite; } protected void init(ServiceStatComposite serviceStatComposite) { - + this.serviceStatComposite = serviceStatComposite; } protected void init(MethodStatComposite methodStatComposite) { + this.methodStatComposite = methodStatComposite; } protected void init(RtStatComposite rtStatComposite) { + this.rtStatComposite = rtStatComposite; } - public void calcApplicationRt(String applicationName, String registryOpType, Long responseTime) { - rtStatComposite.calcApplicationRt(applicationName, registryOpType, responseTime); + public void calcApplicationRt(String registryOpType, Long responseTime) { + rtStatComposite.calcApplicationRt(registryOpType, responseTime); } - public void calcServiceKeyRt(String applicationName, String serviceKey, String registryOpType, Long responseTime) { - rtStatComposite.calcServiceKeyRt(applicationName, serviceKey, registryOpType, responseTime); + public void calcServiceKeyRt(String serviceKey, String registryOpType, Long responseTime) { + rtStatComposite.calcServiceKeyRt(serviceKey, registryOpType, responseTime); } - public void calcMethodKeyRt(String applicationName, Invocation invocation, String registryOpType, Long responseTime) { - rtStatComposite.calcMethodKeyRt(applicationName, invocation, registryOpType, responseTime); + public void calcMethodKeyRt(Invocation invocation, String registryOpType, Long responseTime) { + rtStatComposite.calcMethodKeyRt(invocation, registryOpType, responseTime); } - public void setServiceKey(MetricsKeyWrapper metricsKey, String applicationName, String serviceKey, int num) { - serviceStatComposite.setServiceKey(metricsKey, applicationName, serviceKey, num); + public void setServiceKey(MetricsKeyWrapper metricsKey, String serviceKey, int num) { + serviceStatComposite.setServiceKey(metricsKey, serviceKey, num); } - public void incrementApp(MetricsKey metricsKey, String applicationName, int size) { - applicationStatComposite.incrementSize(metricsKey, applicationName, size); + public void incrementApp(MetricsKey metricsKey, int size) { + applicationStatComposite.incrementSize(metricsKey, size); } - public void incrementServiceKey(MetricsKeyWrapper metricsKeyWrapper, String applicationName, String attServiceKey, int size) { - serviceStatComposite.incrementServiceKey(metricsKeyWrapper, applicationName, attServiceKey, size); + public void incrementServiceKey(MetricsKeyWrapper metricsKeyWrapper, String attServiceKey, int size) { + serviceStatComposite.incrementServiceKey(metricsKeyWrapper, attServiceKey, size); } - public void incrementMethodKey(MetricsKeyWrapper metricsKeyWrapper, String applicationName, Invocation invocation, int size) { - methodStatComposite.incrementMethodKey(metricsKeyWrapper, applicationName, invocation, size); + public void incrementMethodKey(MetricsKeyWrapper metricsKeyWrapper, Invocation invocation, int size) { + methodStatComposite.incrementMethodKey(metricsKeyWrapper, invocation, size); } @Override diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/data/MethodStatComposite.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/data/MethodStatComposite.java index ad099221bb..7b029e8f95 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/data/MethodStatComposite.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/data/MethodStatComposite.java @@ -24,8 +24,9 @@ import org.apache.dubbo.metrics.model.key.MetricsKeyWrapper; import org.apache.dubbo.metrics.model.sample.CounterMetricSample; import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; import org.apache.dubbo.metrics.model.sample.MetricSample; -import org.apache.dubbo.metrics.report.MetricsExport; +import org.apache.dubbo.metrics.report.AbstractMetricsExport; import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.model.ApplicationModel; import java.util.ArrayList; import java.util.List; @@ -33,8 +34,16 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; -public class MethodStatComposite implements MetricsExport { +/** + * Method-level data container, + * if there is no actual call to the existing call method, + * the key will not be displayed when exporting (to be optimized) + */ +public class MethodStatComposite extends AbstractMetricsExport { + public MethodStatComposite(ApplicationModel applicationModel) { + super(applicationModel); + } private final Map> methodNumStats = new ConcurrentHashMap<>(); public void initWrapper(List metricsKeyWrappers) { @@ -44,11 +53,11 @@ public class MethodStatComposite implements MetricsExport { metricsKeyWrappers.forEach(appKey -> methodNumStats.put(appKey, new ConcurrentHashMap<>())); } - public void incrementMethodKey(MetricsKeyWrapper wrapper, String applicationName, Invocation invocation, int size) { + public void incrementMethodKey(MetricsKeyWrapper wrapper, Invocation invocation, int size) { if (!methodNumStats.containsKey(wrapper)) { return; } - methodNumStats.get(wrapper).computeIfAbsent(new MethodMetric(applicationName, invocation), k -> new AtomicLong(0L)).getAndAdd(size); + methodNumStats.get(wrapper).computeIfAbsent(new MethodMetric(getApplicationModel(), invocation), k -> new AtomicLong(0L)).getAndAdd(size); } public List export(MetricsCategory category) { 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 27ba8fe97a..b49a2864c7 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 @@ -19,16 +19,17 @@ package org.apache.dubbo.metrics.data; import org.apache.dubbo.common.utils.ConcurrentHashMapUtils; import org.apache.dubbo.metrics.model.MetricsCategory; -import org.apache.dubbo.metrics.model.key.MetricsKeyWrapper; import org.apache.dubbo.metrics.model.container.AtomicLongContainer; import org.apache.dubbo.metrics.model.container.LongAccumulatorContainer; import org.apache.dubbo.metrics.model.container.LongContainer; 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.model.sample.GaugeMetricSample; import org.apache.dubbo.metrics.model.sample.MetricSample; -import org.apache.dubbo.metrics.report.MetricsExport; +import org.apache.dubbo.metrics.report.AbstractMetricsExport; import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.model.ApplicationModel; import java.util.ArrayList; import java.util.Arrays; @@ -38,8 +39,17 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.LongAccumulator; import java.util.stream.Collectors; +/** + * The data container of the rt dimension, including application, service, and method levels, + * if there is no actual call to the existing call method, + * the key will not be displayed when exporting (to be optimized) + */ @SuppressWarnings({"rawtypes", "unchecked"}) -public class RtStatComposite implements MetricsExport { +public class RtStatComposite extends AbstractMetricsExport { + + public RtStatComposite(ApplicationModel applicationModel) { + super(applicationModel); + } private final List> rtStats = new ArrayList<>(); @@ -68,23 +78,23 @@ public class RtStatComposite implements MetricsExport { return singleRtStats; } - public void calcApplicationRt(String applicationName, String registryOpType, Long responseTime) { + public void calcApplicationRt(String registryOpType, Long responseTime) { for (LongContainer container : rtStats.stream().filter(longContainer -> longContainer.specifyType(registryOpType)).collect(Collectors.toList())) { - Number current = (Number) ConcurrentHashMapUtils.computeIfAbsent(container, applicationName, container.getInitFunc()); + Number current = (Number) ConcurrentHashMapUtils.computeIfAbsent(container, getAppName(), container.getInitFunc()); container.getConsumerFunc().accept(responseTime, current); } } - public void calcServiceKeyRt(String applicationName, String serviceKey, String registryOpType, Long responseTime) { + public void calcServiceKeyRt(String serviceKey, String registryOpType, Long responseTime) { for (LongContainer container : rtStats.stream().filter(longContainer -> longContainer.specifyType(registryOpType)).collect(Collectors.toList())) { - Number current = (Number) ConcurrentHashMapUtils.computeIfAbsent(container, applicationName + "_" + serviceKey, container.getInitFunc()); + Number current = (Number) ConcurrentHashMapUtils.computeIfAbsent(container, serviceKey, container.getInitFunc()); container.getConsumerFunc().accept(responseTime, current); } } - public void calcMethodKeyRt(String applicationName, Invocation invocation, String registryOpType, Long responseTime) { + public void calcMethodKeyRt(Invocation invocation, String registryOpType, Long responseTime) { for (LongContainer container : rtStats.stream().filter(longContainer -> longContainer.specifyType(registryOpType)).collect(Collectors.toList())) { - Number current = (Number) ConcurrentHashMapUtils.computeIfAbsent(container, applicationName + "_" + invocation.getServiceName() + "_" + invocation.getMethodName(), container.getInitFunc()); + Number current = (Number) ConcurrentHashMapUtils.computeIfAbsent(container, invocation.getServiceName() + "_" + invocation.getMethodName(), container.getInitFunc()); container.getConsumerFunc().accept(responseTime, current); } } @@ -94,7 +104,7 @@ public class RtStatComposite implements MetricsExport { for (LongContainer rtContainer : rtStats) { MetricsKeyWrapper metricsKeyWrapper = rtContainer.getMetricsKeyWrapper(); for (Map.Entry entry : rtContainer.entrySet()) { - list.add(new GaugeMetricSample<>(metricsKeyWrapper.targetKey(), metricsKeyWrapper.targetDesc(), metricsKeyWrapper.tagName(entry.getKey()), category, entry.getKey().intern(), value -> rtContainer.getValueSupplier().apply(value.intern()))); + list.add(new GaugeMetricSample<>(metricsKeyWrapper.targetKey(), metricsKeyWrapper.targetDesc(), metricsKeyWrapper.tagName(getApplicationModel(), entry.getKey()), category, entry.getKey().intern(), value -> rtContainer.getValueSupplier().apply(value.intern()))); } } return list; 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 f1bfc32b1c..ef63566636 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 @@ -23,7 +23,8 @@ import org.apache.dubbo.metrics.model.ServiceKeyMetric; import org.apache.dubbo.metrics.model.key.MetricsKeyWrapper; import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; import org.apache.dubbo.metrics.model.sample.MetricSample; -import org.apache.dubbo.metrics.report.MetricsExport; +import org.apache.dubbo.metrics.report.AbstractMetricsExport; +import org.apache.dubbo.rpc.model.ApplicationModel; import java.util.ArrayList; import java.util.List; @@ -31,7 +32,16 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; -public class ServiceStatComposite implements MetricsExport { +/** + * Service-level data container, for the initialized MetricsKey, + * different from the null value of the Map type (the key is not displayed when there is no data), + * the key is displayed and the initial data is 0 value of the AtomicLong type + */ +public class ServiceStatComposite extends AbstractMetricsExport { + + public ServiceStatComposite(ApplicationModel applicationModel) { + super(applicationModel); + } private final Map> serviceWrapperNumStats = new ConcurrentHashMap<>(); @@ -42,18 +52,18 @@ public class ServiceStatComposite implements MetricsExport { metricsKeyWrappers.forEach(appKey -> serviceWrapperNumStats.put(appKey, new ConcurrentHashMap<>())); } - public void incrementServiceKey(MetricsKeyWrapper wrapper, String applicationName, String serviceKey, int size) { + public void incrementServiceKey(MetricsKeyWrapper wrapper, String serviceKey, int size) { if (!serviceWrapperNumStats.containsKey(wrapper)) { return; } - serviceWrapperNumStats.get(wrapper).computeIfAbsent(new ServiceKeyMetric(applicationName, serviceKey), k -> new AtomicLong(0L)).getAndAdd(size); + serviceWrapperNumStats.get(wrapper).computeIfAbsent(new ServiceKeyMetric(getApplicationModel(), serviceKey), k -> new AtomicLong(0L)).getAndAdd(size); } - public void setServiceKey(MetricsKeyWrapper wrapper, String applicationName, String serviceKey, int num) { + public void setServiceKey(MetricsKeyWrapper wrapper, String serviceKey, int num) { if (!serviceWrapperNumStats.containsKey(wrapper)) { return; } - serviceWrapperNumStats.get(wrapper).computeIfAbsent(new ServiceKeyMetric(applicationName, serviceKey), k -> new AtomicLong(0L)).set(num); + serviceWrapperNumStats.get(wrapper).computeIfAbsent(new ServiceKeyMetric(getApplicationModel(), serviceKey), k -> new AtomicLong(0L)).set(num); } public List export(MetricsCategory category) { 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 5c0247ad6a..491cffbbda 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 @@ -20,16 +20,19 @@ package org.apache.dubbo.metrics.listener; import org.apache.dubbo.common.utils.ReflectionUtils; import org.apache.dubbo.metrics.event.MetricsEvent; -import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; public abstract class AbstractMetricsListener implements MetricsListener { + private final Map, Boolean> eventMatchCache = new ConcurrentHashMap<>(); + /** * Whether to support the general determination of event points depends on the event type */ public boolean isSupport(MetricsEvent event) { - List> eventTypes = ReflectionUtils.getClassGenerics(getClass(), AbstractMetricsListener.class); - return event.isAvailable() && eventTypes.stream().allMatch(clazz -> clazz.isInstance(event)); + Boolean eventMatch = eventMatchCache.computeIfAbsent(event.getClass(), clazz -> ReflectionUtils.match(getClass(), AbstractMetricsListener.class, event)); + return event.isAvailable() && eventMatch; } @Override 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 956b518c26..27835e59eb 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,7 +21,7 @@ import org.apache.dubbo.metrics.collector.CombMetricsCollector; import org.apache.dubbo.metrics.model.key.MetricsKey; import org.apache.dubbo.metrics.model.key.MetricsPlaceValue; -public class MetricsApplicationListener extends AbstractMetricsKeyListener { +public class MetricsApplicationListener extends AbstractMetricsKeyListener { public MetricsApplicationListener(MetricsKey metricsKey) { super(metricsKey); @@ -29,25 +29,25 @@ public class MetricsApplicationListener extends AbstractMetricsKeyListener { public static AbstractMetricsKeyListener onPostEventBuild(MetricsKey metricsKey, CombMetricsCollector collector) { return AbstractMetricsKeyListener.onEvent(metricsKey, - event -> collector.increment(event.appName(), metricsKey) + event -> collector.increment(metricsKey) ); } public static AbstractMetricsKeyListener onFinishEventBuild(MetricsKey metricsKey, MetricsPlaceValue placeType, CombMetricsCollector collector) { return AbstractMetricsKeyListener.onFinish(metricsKey, - event -> { - collector.increment(event.appName(), metricsKey); - collector.addRt(event.appName(), placeType.getType(), event.getTimePair().calc()); - } + event -> { + collector.increment(metricsKey); + collector.addRt(placeType.getType(), event.getTimePair().calc()); + } ); } public static AbstractMetricsKeyListener onErrorEventBuild(MetricsKey metricsKey, MetricsPlaceValue placeType, CombMetricsCollector collector) { return AbstractMetricsKeyListener.onError(metricsKey, - event -> { - collector.increment(event.appName(), metricsKey); - collector.addRt(event.appName(), placeType.getType(), event.getTimePair().calc()); - } + event -> { + collector.increment(metricsKey); + collector.addRt(placeType.getType(), event.getTimePair().calc()); + } ); } } 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 ed0da87e61..3a7cc9da7f 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 @@ -19,29 +19,33 @@ 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 static org.apache.dubbo.common.constants.MetricsConstants.TAG_HOSTNAME; -import static org.apache.dubbo.common.constants.MetricsConstants.TAG_INTERFACE_KEY; -import static org.apache.dubbo.common.constants.MetricsConstants.TAG_IP; 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 String applicationName; + private final ApplicationModel applicationModel; private static final String version = Version.getVersion(); private static final String commitId = Version.getLastCommitId(); - public ApplicationMetric(String applicationName) { - this.applicationName = applicationName; + public ApplicationMetric(ApplicationModel applicationModel) { + this.applicationModel = applicationModel; + } + + public ApplicationModel getApplicationModel() { + return applicationModel; } public String getApplicationName() { - return applicationName; + return getApplicationModel().getApplicationName(); } public String getData() { @@ -50,23 +54,12 @@ public class ApplicationMetric implements Metric { @Override public Map getTags() { - return getTagsByName(this.getApplicationName()); - } - - public static Map getTagsByName(String applicationName) { Map tags = new HashMap<>(); tags.put(TAG_IP, getLocalHost()); tags.put(TAG_HOSTNAME, getLocalHostName()); - tags.put(TAG_APPLICATION_NAME, applicationName); + tags.put(TAG_APPLICATION_NAME, getApplicationName()); tags.put(TAG_APPLICATION_VERSION_KEY, version); tags.put(MetricsKey.METADATA_GIT_COMMITID_METRIC.getName(), commitId); return tags; } - - public static Map getServiceTags(String appAndServiceName) { - String[] keys = appAndServiceName.split("_"); - Map tags = getTagsByName(keys[0]); - tags.put(TAG_INTERFACE_KEY, keys[1]); - return tags; - } } diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MethodMetric.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MethodMetric.java index 3ab9a91110..1985dae228 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MethodMetric.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MethodMetric.java @@ -19,71 +19,38 @@ package org.apache.dubbo.metrics.model; import org.apache.dubbo.metrics.model.sample.MetricSample; import org.apache.dubbo.rpc.Invocation; -import org.apache.dubbo.rpc.Invoker; -import org.apache.dubbo.rpc.RpcInvocation; +import org.apache.dubbo.rpc.model.ApplicationModel; -import java.util.HashMap; import java.util.Map; import java.util.Objects; -import java.util.Optional; -import static org.apache.dubbo.common.constants.CommonConstants.GROUP_CHAR_SEPARATOR; -import static org.apache.dubbo.common.constants.CommonConstants.PATH_SEPARATOR; -import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE; -import static org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_NAME; import static org.apache.dubbo.common.constants.MetricsConstants.TAG_GROUP_KEY; -import static org.apache.dubbo.common.constants.MetricsConstants.TAG_HOSTNAME; -import static org.apache.dubbo.common.constants.MetricsConstants.TAG_INTERFACE_KEY; -import static org.apache.dubbo.common.constants.MetricsConstants.TAG_IP; -import static org.apache.dubbo.common.constants.MetricsConstants.TAG_METHOD_KEY; import static org.apache.dubbo.common.constants.MetricsConstants.TAG_VERSION_KEY; -import static org.apache.dubbo.common.utils.NetUtils.getLocalHost; -import static org.apache.dubbo.common.utils.NetUtils.getLocalHostName; import static org.apache.dubbo.metrics.MetricsConstants.INVOCATION_METRICS_COUNTER; -import static org.apache.dubbo.rpc.support.RpcUtils.isGenericCall; /** * Metric class for method. */ -public class MethodMetric implements Metric { - private String applicationName; +public class MethodMetric extends ServiceKeyMetric { private String side; - private String interfaceName; - private String methodName; + private final String methodName; private String group; private String version; + private final MetricSample.Type sampleType; - private MetricSample.Type sampleType; - - public MethodMetric() { - } - - public MethodMetric(String applicationName, Invocation invocation) { - this.applicationName = applicationName; + public MethodMetric(ApplicationModel applicationModel, Invocation invocation) { + super(applicationModel, MetricsSupport.getInterfaceName(invocation)); + this.methodName = MetricsSupport.getMethodName(invocation); + this.side = MetricsSupport.getSide(invocation); + this.group = MetricsSupport.getGroup(invocation); + this.version = MetricsSupport.getVersion(invocation); this.sampleType = (MetricSample.Type) invocation.get(INVOCATION_METRICS_COUNTER); - init(invocation); } public MetricSample.Type getSampleType() { return sampleType; } - public String getInterfaceName() { - return interfaceName; - } - - public void setInterfaceName(String interfaceName) { - this.interfaceName = interfaceName; - } - - public String getMethodName() { - return methodName; - } - - public void setMethodName(String methodName) { - this.methodName = methodName; - } - public String getGroup() { return group; } @@ -101,52 +68,14 @@ public class MethodMetric implements Metric { } public Map getTags() { - Map tags = new HashMap<>(); - tags.put(TAG_IP, getLocalHost()); - tags.put(TAG_HOSTNAME, getLocalHostName()); - tags.put(TAG_APPLICATION_NAME, applicationName); - tags.put(TAG_INTERFACE_KEY, interfaceName); - tags.put(TAG_METHOD_KEY, methodName); + Map tags = MetricsSupport.methodTags(getApplicationModel(), getInterfaceName(), methodName); tags.put(TAG_GROUP_KEY, group); tags.put(TAG_VERSION_KEY, version); return tags; } - private void init(Invocation invocation) { - String serviceUniqueName = invocation.getTargetServiceUniqueName(); - String methodName = invocation.getMethodName(); - if (invocation instanceof RpcInvocation - && isGenericCall(((RpcInvocation) invocation).getParameterTypesDesc(), methodName) - && invocation.getArguments() != null - && invocation.getArguments().length == 3) { - methodName = ((String) invocation.getArguments()[0]).trim(); - } - String group = null; - String interfaceAndVersion; - String[] arr = serviceUniqueName.split(PATH_SEPARATOR); - if (arr.length == 2) { - group = arr[0]; - interfaceAndVersion = arr[1]; - } else { - interfaceAndVersion = arr[0]; - } - String[] ivArr = interfaceAndVersion.split(GROUP_CHAR_SEPARATOR); - String interfaceName = ivArr[0]; - String version = ivArr.length == 2 ? ivArr[1] : null; - Optional> invoker = Optional.ofNullable(invocation.getInvoker()); - this.side = invoker.isPresent() ? invoker.get().getUrl().getSide() : PROVIDER_SIDE; - this.interfaceName = interfaceName; - this.methodName = methodName; - this.group = group; - this.version = version; - } - - public String getApplicationName() { - return applicationName; - } - - public void setApplicationName(String applicationName) { - this.applicationName = applicationName; + public String getMethodName() { + return methodName; } public String getSide() { @@ -160,9 +89,9 @@ public class MethodMetric implements Metric { @Override public String toString() { return "MethodMetric{" + - "applicationName='" + applicationName + '\'' + + "applicationName='" + getApplicationName() + '\'' + ", side='" + side + '\'' + - ", interfaceName='" + interfaceName + '\'' + + ", interfaceName='" + getInterfaceName() + '\'' + ", methodName='" + methodName + '\'' + ", group='" + group + '\'' + ", version='" + version + '\'' + @@ -174,11 +103,11 @@ public class MethodMetric implements Metric { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; MethodMetric that = (MethodMetric) o; - return Objects.equals(applicationName, that.applicationName) && Objects.equals(side, that.side) && Objects.equals(interfaceName, that.interfaceName) && Objects.equals(methodName, that.methodName) && Objects.equals(group, that.group) && Objects.equals(version, that.version); + return Objects.equals(getApplicationName(), that.getApplicationName()) && Objects.equals(side, that.side) && Objects.equals(getInterfaceName(), that.getInterfaceName()) && Objects.equals(methodName, that.methodName) && Objects.equals(group, that.group) && Objects.equals(version, that.version); } @Override public int hashCode() { - return Objects.hash(applicationName, side, interfaceName, methodName, group, version); + return Objects.hash(getApplicationName(), side, getInterfaceName(), methodName, group, version); } } 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 30ff4ea9a2..dde1c958b4 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 @@ -29,6 +29,8 @@ import org.apache.dubbo.metrics.model.key.MetricsPlaceValue; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.RpcException; +import org.apache.dubbo.rpc.RpcInvocation; +import org.apache.dubbo.rpc.model.ApplicationModel; import java.util.HashMap; import java.util.Map; @@ -37,6 +39,7 @@ import java.util.Optional; import static org.apache.dubbo.common.constants.CommonConstants.GROUP_CHAR_SEPARATOR; import static org.apache.dubbo.common.constants.CommonConstants.PATH_SEPARATOR; import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE; +import static org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_MODULE; 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; @@ -48,40 +51,42 @@ import static org.apache.dubbo.common.utils.NetUtils.getLocalHostName; import static org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_KEY_SERVICE; import static org.apache.dubbo.metrics.MetricsConstants.INVOCATION; import static org.apache.dubbo.metrics.MetricsConstants.SELF_INCREMENT_SIZE; +import static org.apache.dubbo.rpc.support.RpcUtils.isGenericCall; public class MetricsSupport { private static final String version = Version.getVersion(); private static final String commitId = Version.getLastCommitId(); - public static Map applicationTags(String applicationName) { + public static Map applicationTags(ApplicationModel applicationModel) { Map tags = new HashMap<>(); tags.put(TAG_IP, getLocalHost()); tags.put(TAG_HOSTNAME, getLocalHostName()); - tags.put(TAG_APPLICATION_NAME, applicationName); + tags.put(TAG_APPLICATION_NAME, applicationModel.getApplicationName()); + tags.put(TAG_APPLICATION_MODULE, applicationModel.getInternalId()); tags.put(TAG_APPLICATION_VERSION_KEY, version); tags.put(MetricsKey.METADATA_GIT_COMMITID_METRIC.getName(), commitId); return tags; } - public static Map serviceTags(String appAndServiceName) { - String[] keys = appAndServiceName.split("_"); - if (keys.length != 2) { - throw new MetricsNeverHappenException("Error service name: " + appAndServiceName); - } - Map tags = applicationTags(keys[0]); - tags.put(TAG_INTERFACE_KEY, keys[1]); + public static Map serviceTags(ApplicationModel applicationModel, String serviceKey) { + Map tags = applicationTags(applicationModel); + tags.put(TAG_INTERFACE_KEY, serviceKey); return tags; } - public static Map methodTags(String names) { + public static Map methodTags(ApplicationModel applicationModel, String names) { String[] keys = names.split("_"); - if (keys.length != 3) { + if (keys.length != 2) { throw new MetricsNeverHappenException("Error names: " + names); } - Map tags = applicationTags(keys[0]); - tags.put(TAG_INTERFACE_KEY, keys[1]); - tags.put(TAG_METHOD_KEY, keys[2]); + 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); + tags.put(TAG_METHOD_KEY, methodName); return tags; } @@ -150,47 +155,73 @@ public class MetricsSupport { return ivArr[0]; } + public static String getMethodName(Invocation invocation) { + String methodName = invocation.getMethodName(); + if (invocation instanceof RpcInvocation + && isGenericCall(((RpcInvocation) invocation).getParameterTypesDesc(), methodName) + && invocation.getArguments() != null + && invocation.getArguments().length == 3) { + methodName = ((String) invocation.getArguments()[0]).trim(); + } + return methodName; + } + + public static String getGroup(Invocation invocation) { + String serviceUniqueName = invocation.getTargetServiceUniqueName(); + String group = null; + String[] arr = serviceUniqueName.split(PATH_SEPARATOR); + if (arr.length == 2) { + group = arr[0]; + } + return group; + } + + public static String getVersion(Invocation invocation) { + String interfaceAndVersion; + String[] arr = invocation.getTargetServiceUniqueName().split(PATH_SEPARATOR); + if (arr.length == 2) { + interfaceAndVersion = arr[1]; + } else { + interfaceAndVersion = arr[0]; + } + String[] ivArr = interfaceAndVersion.split(GROUP_CHAR_SEPARATOR); + return ivArr.length == 2 ? ivArr[1] : null; + } + /** * Incr service num */ public static void increment(MetricsKey metricsKey, MetricsPlaceValue placeType, ServiceMetricsCollector collector, MetricsEvent event) { - collector.increment(event.appName(), event.getAttachmentValue(ATTACHMENT_KEY_SERVICE), new MetricsKeyWrapper(metricsKey, placeType), SELF_INCREMENT_SIZE); - } - - /** - * Dec service num - */ - public static void dec(MetricsKey metricsKey, MetricsPlaceValue placeType, ServiceMetricsCollector collector, MetricsEvent event) { - collector.increment(event.appName(), event.getAttachmentValue(ATTACHMENT_KEY_SERVICE), new MetricsKeyWrapper(metricsKey, placeType), -SELF_INCREMENT_SIZE); + collector.increment(event.getAttachmentValue(ATTACHMENT_KEY_SERVICE), new MetricsKeyWrapper(metricsKey, placeType), SELF_INCREMENT_SIZE); } /** * Incr service num&&rt */ public static void incrAndAddRt(MetricsKey metricsKey, MetricsPlaceValue placeType, ServiceMetricsCollector collector, TimeCounterEvent event) { - collector.increment(event.appName(), event.getAttachmentValue(ATTACHMENT_KEY_SERVICE), new MetricsKeyWrapper(metricsKey, placeType), SELF_INCREMENT_SIZE); - collector.addRt(event.appName(), event.getAttachmentValue(ATTACHMENT_KEY_SERVICE), placeType.getType(), event.getTimePair().calc()); + collector.increment(event.getAttachmentValue(ATTACHMENT_KEY_SERVICE), new MetricsKeyWrapper(metricsKey, placeType), SELF_INCREMENT_SIZE); + collector.addRt(event.getAttachmentValue(ATTACHMENT_KEY_SERVICE), placeType.getType(), event.getTimePair().calc()); } /** * Incr method num */ public static void increment(MetricsKey metricsKey, MetricsPlaceValue placeType, MethodMetricsCollector collector, MetricsEvent event) { - collector.increment(event.appName(), event.getAttachmentValue(INVOCATION), new MetricsKeyWrapper(metricsKey, placeType), SELF_INCREMENT_SIZE); + collector.increment(event.getAttachmentValue(INVOCATION), new MetricsKeyWrapper(metricsKey, placeType), SELF_INCREMENT_SIZE); } /** * Dec method num */ public static void dec(MetricsKey metricsKey, MetricsPlaceValue placeType, MethodMetricsCollector collector, MetricsEvent event) { - collector.increment(event.appName(), event.getAttachmentValue(INVOCATION), new MetricsKeyWrapper(metricsKey, placeType), -SELF_INCREMENT_SIZE); + collector.increment(event.getAttachmentValue(INVOCATION), new MetricsKeyWrapper(metricsKey, placeType), -SELF_INCREMENT_SIZE); } /** * Incr method num&&rt */ public static void incrAndAddRt(MetricsKey metricsKey, MetricsPlaceValue placeType, MethodMetricsCollector collector, TimeCounterEvent event) { - collector.increment(event.appName(), event.getAttachmentValue(INVOCATION), new MetricsKeyWrapper(metricsKey, placeType), SELF_INCREMENT_SIZE); - collector.addRt(event.appName(), event.getAttachmentValue(INVOCATION), placeType.getType(), event.getTimePair().calc()); + collector.increment(event.getAttachmentValue(INVOCATION), new MetricsKeyWrapper(metricsKey, placeType), SELF_INCREMENT_SIZE); + collector.addRt(event.getAttachmentValue(INVOCATION), placeType.getType(), event.getTimePair().calc()); } } 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 94eaa30edb..b380bdb77f 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 @@ -17,36 +17,28 @@ package org.apache.dubbo.metrics.model; -import java.util.HashMap; -import java.util.Map; +import org.apache.dubbo.rpc.model.ApplicationModel; -import static org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_NAME; -import static org.apache.dubbo.common.constants.MetricsConstants.TAG_HOSTNAME; -import static org.apache.dubbo.common.constants.MetricsConstants.TAG_INTERFACE_KEY; -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; +import java.util.Map; /** * Metric class for service. */ -public class ServiceKeyMetric implements Metric { - private final String applicationName; - private final String serviceKey; +public class ServiceKeyMetric extends ApplicationMetric { + private final String interfaceName; - public ServiceKeyMetric(String applicationName, String serviceKey) { - this.applicationName = applicationName; - this.serviceKey = serviceKey; + public ServiceKeyMetric(ApplicationModel applicationModel, String serviceKey) { + super(applicationModel); + this.interfaceName = serviceKey; } @Override public Map getTags() { - Map tags = new HashMap<>(); - tags.put(TAG_IP, getLocalHost()); - tags.put(TAG_HOSTNAME, getLocalHostName()); - tags.put(TAG_APPLICATION_NAME, applicationName); - tags.put(TAG_INTERFACE_KEY, serviceKey); - return tags; + return MetricsSupport.serviceTags(getApplicationModel(), interfaceName); + } + + public String getInterfaceName() { + return interfaceName; } @Override @@ -60,24 +52,24 @@ public class ServiceKeyMetric implements Metric { ServiceKeyMetric that = (ServiceKeyMetric) o; - if (!applicationName.equals(that.applicationName)) { + if (!getApplicationName().equals(that.getApplicationName())) { return false; } - return serviceKey.equals(that.serviceKey); + return interfaceName.equals(that.interfaceName); } @Override public int hashCode() { - int result = applicationName.hashCode(); - result = 31 * result + serviceKey.hashCode(); + int result = getApplicationName().hashCode(); + result = 31 * result + interfaceName.hashCode(); return result; } @Override public String toString() { return "ServiceKeyMetric{" + - "applicationName='" + applicationName + '\'' + - ", serviceKey='" + serviceKey + '\'' + - '}'; + "applicationName='" + getApplicationName() + '\'' + + ", serviceKey='" + interfaceName + '\'' + + '}'; } } diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/MetricsKey.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/MetricsKey.java index b6158be79a..9470f6b31b 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/MetricsKey.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/MetricsKey.java @@ -55,6 +55,8 @@ public enum MetricsKey { METRIC_RT_AVG("dubbo.%s.rt.milliseconds.avg", "Average Response Time"), METRIC_RT_P99("dubbo.%s.rt.milliseconds.p99", "Response Time P99"), METRIC_RT_P95("dubbo.%s.rt.milliseconds.p95", "Response Time P95"), + METRIC_RT_P90("dubbo.%s.rt.milliseconds.p90", "Response Time P90"), + METRIC_RT_P50("dubbo.%s.rt.milliseconds.p50", "Response Time P50"), // register metrics key 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 e213be48cb..95d7a31d69 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 @@ -19,6 +19,7 @@ package org.apache.dubbo.metrics.model.key; import io.micrometer.common.lang.Nullable; import org.apache.dubbo.metrics.model.MetricsSupport; +import org.apache.dubbo.rpc.model.ApplicationModel; import java.util.Map; import java.util.Objects; @@ -89,17 +90,17 @@ public class MetricsKeyWrapper { } } - public Map tagName(String key) { + public Map tagName(ApplicationModel applicationModel, String key) { MetricsLevel level = getLevel(); switch (level) { case APP: - return MetricsSupport.applicationTags(key); + return MetricsSupport.applicationTags(applicationModel); case SERVICE: - return MetricsSupport.serviceTags(key); + return MetricsSupport.serviceTags(applicationModel, key); case METHOD: - return MetricsSupport.methodTags(key); + return MetricsSupport.methodTags(applicationModel, key); } - return MetricsSupport.applicationTags(key); + return MetricsSupport.applicationTags(applicationModel); } public static MetricsKeyWrapper wrapper(MetricsKey metricsKey) { diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/report/AbstractMetricsExport.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/report/AbstractMetricsExport.java new file mode 100644 index 0000000000..94acf74de9 --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/report/AbstractMetricsExport.java @@ -0,0 +1,40 @@ +/* + * 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.report; + +import org.apache.dubbo.rpc.model.ApplicationModel; + +/** + * Store public information such as application + */ +public abstract class AbstractMetricsExport implements MetricsExport { + + private final ApplicationModel applicationModel; + + public AbstractMetricsExport(ApplicationModel applicationModel) { + this.applicationModel = applicationModel; + } + + public ApplicationModel getApplicationModel() { + return applicationModel; + } + + public String getAppName() { + return getApplicationModel().getApplicationName(); + } +} 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 f09654f36f..765f33e71d 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 @@ -132,7 +132,7 @@ public class AggregateMetricsCollector implements MetricsCollector } private void onRTEvent(RequestEvent event) { - MethodMetric metric = new MethodMetric(applicationModel.getApplicationName(), event.getAttachmentValue(MetricsConstants.INVOCATION)); + MethodMetric metric = new MethodMetric(applicationModel, event.getAttachmentValue(MetricsConstants.INVOCATION)); long responseTime = event.getTimePair().calc(); TimeWindowQuantile quantile = ConcurrentHashMapUtils.computeIfAbsent(rt, metric, k -> new TimeWindowQuantile(DEFAULT_COMPRESSION, bucketNum, timeWindowSeconds)); quantile.add(responseTime); @@ -142,7 +142,7 @@ public class AggregateMetricsCollector implements MetricsCollector private MethodMetric calcWindowCounter(RequestEvent event, MetricsKey targetKey) { MetricsPlaceValue placeType = MetricsPlaceValue.of(event.getAttachmentValue(MetricsConstants.INVOCATION_SIDE), MetricsLevel.SERVICE); MetricsKeyWrapper metricsKeyWrapper = new MetricsKeyWrapper(targetKey, placeType); - MethodMetric metric = new MethodMetric(applicationModel.getApplicationName(), event.getAttachmentValue(MetricsConstants.INVOCATION)); + MethodMetric metric = new MethodMetric(applicationModel, event.getAttachmentValue(MetricsConstants.INVOCATION)); ConcurrentMap counter = methodTypeCounter.computeIfAbsent(metricsKeyWrapper, k -> new ConcurrentHashMap<>()); @@ -198,7 +198,11 @@ public class AggregateMetricsCollector implements MetricsCollector list.add(new GaugeMetricSample<>(MetricsKey.METRIC_RT_P99.getNameByType(k.getSide()), MetricsKey.METRIC_RT_P99.getDescription(), k.getTags(), RT, v, value -> value.quantile(0.99))); list.add(new GaugeMetricSample<>(MetricsKey.METRIC_RT_P95.getNameByType(k.getSide()), - MetricsKey.METRIC_RT_P99.getDescription(), k.getTags(), RT, v, value -> value.quantile(0.95))); + MetricsKey.METRIC_RT_P95.getDescription(), k.getTags(), RT, v, value -> value.quantile(0.95))); + list.add(new GaugeMetricSample<>(MetricsKey.METRIC_RT_P90.getNameByType(k.getSide()), + MetricsKey.METRIC_RT_P90.getDescription(), k.getTags(), RT, v, value -> value.quantile(0.90))); + list.add(new GaugeMetricSample<>(MetricsKey.METRIC_RT_P50.getNameByType(k.getSide()), + MetricsKey.METRIC_RT_P50.getDescription(), k.getTags(), RT, v, value -> value.quantile(0.50))); }); } 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 937893310c..c4c3ef9ec0 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 @@ -56,25 +56,28 @@ public class DefaultMetricsCollector extends CombMetricsCollector private volatile boolean threadpoolCollectEnabled = false; private final ThreadPoolMetricsSampler threadPoolSampler = new ThreadPoolMetricsSampler(this); private String applicationName; - private ApplicationModel applicationModel; + private final ApplicationModel applicationModel; private final List samplers = new ArrayList<>(); - public DefaultMetricsCollector() { - super(new BaseStatComposite() { + public DefaultMetricsCollector(ApplicationModel applicationModel) { + super(new BaseStatComposite(applicationModel) { @Override protected void init(MethodStatComposite methodStatComposite) { + super.init(methodStatComposite); methodStatComposite.initWrapper(DefaultConstants.METHOD_LEVEL_KEYS); } @Override protected void init(RtStatComposite rtStatComposite) { + super.init(rtStatComposite); rtStatComposite.init(MetricsPlaceValue.of(CommonConstants.PROVIDER, MetricsLevel.METHOD), - MetricsPlaceValue.of(CommonConstants.CONSUMER, MetricsLevel.METHOD)); + MetricsPlaceValue.of(CommonConstants.CONSUMER, MetricsLevel.METHOD)); } }); super.setEventMulticaster(new DefaultSubDispatcher(this)); samplers.add(applicationSampler); samplers.add(threadPoolSampler); + this.applicationModel = applicationModel; } public void addSampler(MetricsSampler sampler) { @@ -109,9 +112,8 @@ public class DefaultMetricsCollector extends CombMetricsCollector this.threadpoolCollectEnabled = threadpoolCollectEnabled; } - public void collectApplication(ApplicationModel applicationModel) { + public void collectApplication() { this.setApplicationName(applicationModel.getApplicationName()); - this.applicationModel = applicationModel; applicationSampler.inc(applicationName, MetricsEvent.Type.APPLICATION_INFO); } @@ -144,18 +146,18 @@ public class DefaultMetricsCollector extends CombMetricsCollector public List sample() { List samples = new ArrayList<>(); this.getCount(MetricsEvent.Type.APPLICATION_INFO).filter(e -> !e.isEmpty()) - .ifPresent(map -> map.forEach((k, v) -> - samples.add(new CounterMetricSample<>(APPLICATION_METRIC_INFO.getName(), - APPLICATION_METRIC_INFO.getDescription(), - k.getTags(), APPLICATION, v))) - ); + .ifPresent(map -> map.forEach((k, v) -> + samples.add(new CounterMetricSample<>(APPLICATION_METRIC_INFO.getName(), + APPLICATION_METRIC_INFO.getDescription(), + k.getTags(), APPLICATION, v))) + ); return samples; } @Override protected void countConfigure( - MetricsCountSampleConfigurer sampleConfigure) { - sampleConfigure.configureMetrics(configure -> new ApplicationMetric(sampleConfigure.getSource())); + MetricsCountSampleConfigurer sampleConfigure) { + sampleConfigure.configureMetrics(configure -> new ApplicationMetric(applicationModel)); } }; } diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/HistogramMetricsCollector.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/HistogramMetricsCollector.java index 3a17033a97..c7a152c12e 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/HistogramMetricsCollector.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/HistogramMetricsCollector.java @@ -86,7 +86,7 @@ public class HistogramMetricsCollector extends AbstractMetricsListener samples = collector.collect(); for (MetricSample sample : samples) { Map tags = sample.getTags(); @@ -201,7 +199,7 @@ class AggregateMetricsCollectorTest { when(applicationModel.getApplicationConfigManager()).thenReturn(configManager); when(applicationModel.getBeanFactory()).thenReturn(beanFactory); - when(beanFactory.getBean(DefaultMetricsCollector.class)).thenReturn(new DefaultMetricsCollector()); + when(beanFactory.getBean(DefaultMetricsCollector.class)).thenReturn(new DefaultMetricsCollector(applicationModel)); when(configManager.getMetrics()).thenReturn(Optional.of(metricsConfig)); when(metricsConfig.getAggregation()).thenReturn(aggregationConfig); when(aggregationConfig.getEnabled()).thenReturn(Boolean.TRUE); @@ -271,16 +269,16 @@ class AggregateMetricsCollectorTest { List samples = collector.collect(); GaugeMetricSample p95Sample = samples.stream() - .filter(sample -> sample.getName().endsWith("p95")) - .map(sample -> (GaugeMetricSample) sample) - .findFirst() - .orElse(null); + .filter(sample -> sample.getName().endsWith("p95")) + .map(sample -> (GaugeMetricSample) sample) + .findFirst() + .orElse(null); GaugeMetricSample p99Sample = samples.stream() - .filter(sample -> sample.getName().endsWith("p99")) - .map(sample -> (GaugeMetricSample) sample) - .findFirst() - .orElse(null); + .filter(sample -> sample.getName().endsWith("p99")) + .map(sample -> (GaugeMetricSample) sample) + .findFirst() + .orElse(null); Assertions.assertNotNull(p95Sample); Assertions.assertNotNull(p99Sample); @@ -294,6 +292,13 @@ class AggregateMetricsCollectorTest { Assertions.assertTrue(Math.abs(1 - p99 / manualP99) < 0.05); } + @Test + void testGenericCache() { + List> classGenerics = ReflectionUtils.getClassGenerics(AggregateMetricsCollector.class, MetricsListener.class); + Assertions.assertTrue(CollectionUtils.isNotEmpty(classGenerics)); + Assertions.assertEquals(RequestEvent.class, classGenerics.get(0)); + } + public static class TestRequestEvent extends RequestEvent { private long rt; 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 6451214e55..9beb258115 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 @@ -110,7 +110,7 @@ class DefaultCollectorTest { @Test void testListener() { - DefaultMetricsCollector metricsCollector = new DefaultMetricsCollector(); + DefaultMetricsCollector metricsCollector = new DefaultMetricsCollector(applicationModel); RequestEvent event = RequestEvent.toRequestEvent(applicationModel, invocation); RequestBeforeEvent beforeEvent = new RequestBeforeEvent(applicationModel, new TypeWrapper(MetricsLevel.METHOD, MetricsKey.METRIC_REQUESTS)); Assertions.assertTrue(metricsCollector.isSupport(event)); diff --git a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSamplerTest.java b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSamplerTest.java index 4b336d91f6..2c8e2f984d 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSamplerTest.java +++ b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSamplerTest.java @@ -50,7 +50,7 @@ public class ThreadPoolMetricsSamplerTest { @BeforeEach void setUp() { - DefaultMetricsCollector collector = new DefaultMetricsCollector(); + DefaultMetricsCollector collector = new DefaultMetricsCollector(applicationModel); sampler = new ThreadPoolMetricsSampler(collector); } @@ -135,12 +135,12 @@ public class ThreadPoolMetricsSamplerTest { public void setUp2() { MockitoAnnotations.openMocks(this); - collector = new DefaultMetricsCollector(); + collector = new DefaultMetricsCollector(applicationModel); sampler2 = new ThreadPoolMetricsSampler(collector); when(scopeBeanFactory.getBean(FrameworkExecutorRepository.class)).thenReturn(new FrameworkExecutorRepository()); - collector.collectApplication(applicationModel); + collector.collectApplication(); when(applicationModel.getBeanFactory()).thenReturn(scopeBeanFactory); when(applicationModel.getExtensionLoader(DataStore.class)).thenReturn(extensionLoader); when(extensionLoader.getDefaultExtension()).thenReturn(dataStore); diff --git a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java index b0d06dc16b..887b785555 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java +++ b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java @@ -77,8 +77,6 @@ class MetricsFilterTest { public void setup() { ApplicationConfig config = new ApplicationConfig(); config.setName("MockMetrics"); - //RpcContext.getContext().setAttachment("MockMetrics","MockMetrics"); - applicationModel = ApplicationModel.defaultModel(); applicationModel.getApplicationConfigManager().setApplication(config); @@ -87,7 +85,7 @@ class MetricsFilterTest { collector = applicationModel.getBeanFactory().getOrRegisterBean(DefaultMetricsCollector.class); if (!initApplication.get()) { - collector.collectApplication(applicationModel); + collector.collectApplication(); initApplication.set(true); } filter.setApplicationModel(applicationModel); diff --git a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/metrics/model/MethodMetricTest.java b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/metrics/model/MethodMetricTest.java index 6266a6860e..2b99346816 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/metrics/model/MethodMetricTest.java +++ b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/metrics/model/MethodMetricTest.java @@ -18,9 +18,11 @@ package org.apache.dubbo.metrics.metrics.model; import org.apache.dubbo.common.URL; +import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.metrics.model.MethodMetric; import org.apache.dubbo.rpc.RpcContext; import org.apache.dubbo.rpc.RpcInvocation; +import org.apache.dubbo.rpc.model.ApplicationModel; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -41,7 +43,7 @@ import static org.apache.dubbo.common.utils.NetUtils.getLocalHostName; class MethodMetricTest { - private static final String applicationName = null; + private static ApplicationModel applicationModel; private static String interfaceName; private static String methodName; private static String group; @@ -50,6 +52,12 @@ class MethodMetricTest { @BeforeAll public static void setup() { + + ApplicationConfig config = new ApplicationConfig(); + config.setName("MockMetrics"); + applicationModel = ApplicationModel.defaultModel(); + applicationModel.getApplicationConfigManager().setApplication(config); + interfaceName = "org.apache.dubbo.MockInterface"; methodName = "mockMethod"; group = "mockGroup"; @@ -64,7 +72,7 @@ class MethodMetricTest { @Test void test() { - MethodMetric metric = new MethodMetric(applicationName, invocation); + MethodMetric metric = new MethodMetric(applicationModel, invocation); Assertions.assertEquals(metric.getInterfaceName(), interfaceName); Assertions.assertEquals(metric.getMethodName(), methodName); Assertions.assertEquals(metric.getGroup(), group); @@ -73,7 +81,7 @@ class MethodMetricTest { Map tags = metric.getTags(); Assertions.assertEquals(tags.get(TAG_IP), getLocalHost()); Assertions.assertEquals(tags.get(TAG_HOSTNAME), getLocalHostName()); - Assertions.assertEquals(tags.get(TAG_APPLICATION_NAME), applicationName); + Assertions.assertEquals(tags.get(TAG_APPLICATION_NAME), applicationModel.getApplicationName()); Assertions.assertEquals(tags.get(TAG_INTERFACE_KEY), interfaceName); Assertions.assertEquals(tags.get(TAG_METHOD_KEY), methodName); diff --git a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/MetadataMetricsCollector.java b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/MetadataMetricsCollector.java index 6281efebc4..f3127f1ab4 100644 --- a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/MetadataMetricsCollector.java +++ b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/MetadataMetricsCollector.java @@ -51,19 +51,22 @@ public class MetadataMetricsCollector extends CombMetricsCollector metricSamples = collector.collect(); // push success +1 - Assertions.assertEquals(1, metricSamples.size()); - Assertions.assertTrue(metricSamples.get(0) instanceof GaugeMetricSample); - Assertions.assertEquals(metricSamples.get(0).getName(), MetricsKey.METADATA_PUSH_METRIC_NUM.getName()); + Assertions.assertEquals(MetadataMetricsConstants.APP_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; } ); // push finish rt +1 List metricSamples = collector.collect(); - //num(total+success) + rt(5) = 7 - Assertions.assertEquals(7, metricSamples.size()); + // App(6) + rt(5) = 7 + Assertions.assertEquals(MetadataMetricsConstants.APP_LEVEL_KEYS.size() + 5, metricSamples.size()); long c1 = pushEvent.getTimePair().calc(); pushEvent = MetadataEvent.toPushEvent(applicationModel); @@ -121,8 +121,8 @@ class MetadataMetricsCollectorTest { long c2 = lastTimePair.calc(); metricSamples = collector.collect(); - // num(total+success+error) + rt(5) - Assertions.assertEquals(8, metricSamples.size()); + // App(6) + rt(5) + Assertions.assertEquals(MetadataMetricsConstants.APP_LEVEL_KEYS.size() + 5, metricSamples.size()); // calc rt for (MetricSample sample : metricSamples) { @@ -150,9 +150,9 @@ class MetadataMetricsCollectorTest { List metricSamples = collector.collect(); // push success +1 - Assertions.assertEquals(1, metricSamples.size()); - Assertions.assertTrue(metricSamples.get(0) instanceof GaugeMetricSample); - Assertions.assertEquals(metricSamples.get(0).getName(), MetricsKey.METADATA_SUBSCRIBE_METRIC_NUM.getName()); + Assertions.assertEquals(MetadataMetricsConstants.APP_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; } ); @@ -160,8 +160,9 @@ class MetadataMetricsCollectorTest { // push finish rt +1 List metricSamples = collector.collect(); - //num(total+success) + rt(5) = 7 - Assertions.assertEquals(7, metricSamples.size()); + // App(6) + rt(5) = 7 + Assertions.assertEquals(MetadataMetricsConstants.APP_LEVEL_KEYS.size() + 5, metricSamples.size()); + subscribeEvent = MetadataEvent.toSubscribeEvent(applicationModel); TimePair lastTimePair = subscribeEvent.getTimePair(); MetricsEventBus.post(subscribeEvent, @@ -179,8 +180,8 @@ class MetadataMetricsCollectorTest { long c2 = lastTimePair.calc(); metricSamples = collector.collect(); - // num(total+success+error) + rt(5) - Assertions.assertEquals(8, metricSamples.size()); + // App(6) + rt(5) + Assertions.assertEquals(MetadataMetricsConstants.APP_LEVEL_KEYS.size() + 5, metricSamples.size()); // calc rt for (MetricSample sample : metricSamples) { @@ -209,19 +210,19 @@ class MetadataMetricsCollectorTest { () -> { List metricSamples = collector.collect(); - // push success +1 - Assertions.assertEquals(1, metricSamples.size()); - Assertions.assertTrue(metricSamples.get(0) instanceof GaugeMetricSample); - Assertions.assertEquals(metricSamples.get(0).getName(), MetricsKey.STORE_PROVIDER_METADATA.getName()); - Assertions.assertEquals(metricSamples.get(0).getTags().get("interface"), serviceKey); + // App(6) + service success(1) + Assertions.assertEquals(MetadataMetricsConstants.APP_LEVEL_KEYS.size() + 1, metricSamples.size()); + Assertions.assertTrue(metricSamples.stream().allMatch(metricSample -> metricSample instanceof GaugeMetricSample)); + Assertions.assertTrue(metricSamples.stream().anyMatch(metricSample -> ((GaugeMetricSample) metricSample).applyAsDouble() == 1)); return null; } ); // push finish rt +1 List metricSamples = collector.collect(); - //num(total+success) + rt(5) = 7 - Assertions.assertEquals(7, metricSamples.size()); + // App(6) + service total/success(2) + rt(5) = 7 + Assertions.assertEquals(MetadataMetricsConstants.APP_LEVEL_KEYS.size() + 2 + 5, metricSamples.size()); + long c1 = metadataEvent.getTimePair().calc(); metadataEvent = MetadataEvent.toServiceSubscribeEvent(applicationModel, serviceKey); TimePair lastTimePair = metadataEvent.getTimePair(); @@ -240,8 +241,8 @@ class MetadataMetricsCollectorTest { metricSamples = collector.collect(); - // num(total+success+error) + rt(5) - Assertions.assertEquals(8, metricSamples.size()); + // App(6) + service total/success/failed(3) + rt(5) + Assertions.assertEquals(MetadataMetricsConstants.APP_LEVEL_KEYS.size() +3 + 5, metricSamples.size()); // calc rt for (MetricSample sample : metricSamples) { diff --git a/dubbo-metrics/dubbo-metrics-metadata/src/test/java/org/apache/dubbo/metrics/metadata/MetadataStatCompositeTest.java b/dubbo-metrics/dubbo-metrics-metadata/src/test/java/org/apache/dubbo/metrics/metadata/MetadataStatCompositeTest.java index bf1a021d63..0a1cd611ff 100644 --- a/dubbo-metrics/dubbo-metrics-metadata/src/test/java/org/apache/dubbo/metrics/metadata/MetadataStatCompositeTest.java +++ b/dubbo-metrics/dubbo-metrics-metadata/src/test/java/org/apache/dubbo/metrics/metadata/MetadataStatCompositeTest.java @@ -17,43 +17,58 @@ package org.apache.dubbo.metrics.metadata; +import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.metrics.data.ApplicationStatComposite; 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.container.LongContainer; import org.apache.dubbo.metrics.model.key.MetricsKey; +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.Map; import java.util.Optional; -import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; import static org.apache.dubbo.metrics.metadata.MetadataMetricsConstants.OP_TYPE_PUSH; import static org.apache.dubbo.metrics.metadata.MetadataMetricsConstants.OP_TYPE_STORE_PROVIDER_INTERFACE; import static org.apache.dubbo.metrics.metadata.MetadataMetricsConstants.OP_TYPE_SUBSCRIBE; public class MetadataStatCompositeTest { + private ApplicationModel applicationModel; + private BaseStatComposite statComposite; - private final String applicationName = "app1"; + @BeforeEach + public void setup() { + FrameworkModel frameworkModel = FrameworkModel.defaultModel(); + applicationModel = frameworkModel.newApplication(); + ApplicationConfig application = new ApplicationConfig(); + application.setName("App1"); + applicationModel.getApplicationConfigManager().setApplication(application); + statComposite = new BaseStatComposite(applicationModel) { + @Override + protected void init(ApplicationStatComposite applicationStatComposite) { + super.init(applicationStatComposite); + applicationStatComposite.init(MetadataMetricsConstants.APP_LEVEL_KEYS); + } - private final BaseStatComposite statComposite = new BaseStatComposite() { - @Override - protected void init(ApplicationStatComposite applicationStatComposite) { - applicationStatComposite.init(MetadataMetricsConstants.APP_LEVEL_KEYS); - } + @Override + protected void init(ServiceStatComposite serviceStatComposite) { + super.init(serviceStatComposite); + serviceStatComposite.initWrapper(MetadataMetricsConstants.SERVICE_LEVEL_KEYS); + } - @Override - protected void init(ServiceStatComposite serviceStatComposite) { - serviceStatComposite.initWrapper(MetadataMetricsConstants.SERVICE_LEVEL_KEYS); - } - - @Override - protected void init(RtStatComposite rtStatComposite) { - rtStatComposite.init(OP_TYPE_PUSH, OP_TYPE_SUBSCRIBE, OP_TYPE_STORE_PROVIDER_INTERFACE); - } - }; + @Override + protected void init(RtStatComposite rtStatComposite) { + super.init(rtStatComposite); + rtStatComposite.init(OP_TYPE_PUSH, OP_TYPE_SUBSCRIBE, OP_TYPE_STORE_PROVIDER_INTERFACE); + } + }; + } @Test void testInit() { @@ -62,7 +77,7 @@ public class MetadataStatCompositeTest { //(rt)5 * (push,subscribe,service)3 Assertions.assertEquals(5 * 3, statComposite.getRtStatComposite().getRtStats().size()); statComposite.getApplicationStatComposite().getApplicationNumStats().values().forEach((v -> - Assertions.assertEquals(v, new ConcurrentHashMap<>()))); + Assertions.assertEquals(v.get(), new AtomicLong(0L).get()))); statComposite.getRtStatComposite().getRtStats().forEach(rtContainer -> { for (Map.Entry entry : rtContainer.entrySet()) { @@ -73,16 +88,16 @@ public class MetadataStatCompositeTest { @Test void testIncrement() { - statComposite.incrementApp(MetricsKey.METADATA_PUSH_METRIC_NUM, applicationName, 1); + statComposite.incrementApp(MetricsKey.METADATA_PUSH_METRIC_NUM, 1); - Assertions.assertEquals(1L, statComposite.getApplicationStatComposite().getApplicationNumStats().get(MetricsKey.METADATA_PUSH_METRIC_NUM).get(applicationName).get()); + Assertions.assertEquals(1L, statComposite.getApplicationStatComposite().getApplicationNumStats().get(MetricsKey.METADATA_PUSH_METRIC_NUM).get()); } @Test void testCalcRt() { - statComposite.calcApplicationRt(applicationName, OP_TYPE_SUBSCRIBE.getType(), 10L); + statComposite.calcApplicationRt( OP_TYPE_SUBSCRIBE.getType(), 10L); Assertions.assertTrue(statComposite.getRtStatComposite().getRtStats().stream().anyMatch(longContainer -> longContainer.specifyType(OP_TYPE_SUBSCRIBE.getType()))); Optional> subContainer = statComposite.getRtStatComposite().getRtStats().stream().filter(longContainer -> longContainer.specifyType(OP_TYPE_SUBSCRIBE.getType())).findFirst(); - subContainer.ifPresent(v -> Assertions.assertEquals(10L, v.get(applicationName).longValue())); + subContainer.ifPresent(v -> Assertions.assertEquals(10L, v.get(applicationModel.getApplicationName()).longValue())); } } diff --git a/dubbo-metrics/dubbo-metrics-prometheus/src/test/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsThreadPoolTest.java b/dubbo-metrics/dubbo-metrics-prometheus/src/test/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsThreadPoolTest.java index 05ab7b1e8a..6c73838ef1 100644 --- a/dubbo-metrics/dubbo-metrics-prometheus/src/test/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsThreadPoolTest.java +++ b/dubbo-metrics/dubbo-metrics-prometheus/src/test/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsThreadPoolTest.java @@ -15,6 +15,7 @@ * limitations under the License. */ package org.apache.dubbo.metrics.prometheus; + import com.sun.net.httpserver.HttpServer; import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.config.MetricsConfig; @@ -24,7 +25,6 @@ import org.apache.dubbo.metrics.collector.sample.ThreadRejectMetricsCountSampler import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; import org.apache.dubbo.metrics.model.sample.MetricSample; import org.apache.dubbo.rpc.model.ApplicationModel; -import org.apache.dubbo.rpc.model.FrameworkModel; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; @@ -33,6 +33,7 @@ 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.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -43,19 +44,18 @@ import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map; import java.util.stream.Collectors; + import static org.apache.dubbo.common.constants.MetricsConstants.PROTOCOL_PROMETHEUS; import static org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_NAME; -import static org.apache.dubbo.common.constants.MetricsConstants.TAG_THREAD_NAME; 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.constants.MetricsConstants.TAG_THREAD_NAME; import static org.apache.dubbo.common.utils.NetUtils.getLocalHost; import static org.apache.dubbo.common.utils.NetUtils.getLocalHostName; public class PrometheusMetricsThreadPoolTest { - private FrameworkModel frameworkModel; - private ApplicationModel applicationModel; private MetricsConfig metricsConfig; @@ -71,8 +71,7 @@ public class PrometheusMetricsThreadPoolTest { applicationModel.getApplicationConfigManager().setApplication(config); metricsConfig = new MetricsConfig(); metricsConfig.setProtocol(PROTOCOL_PROMETHEUS); - frameworkModel = FrameworkModel.defaultModel(); - metricsCollector = frameworkModel.getBeanFactory().getOrRegisterBean(DefaultMetricsCollector.class); + metricsCollector = applicationModel.getBeanFactory().getOrRegisterBean(DefaultMetricsCollector.class); } @AfterEach @@ -92,7 +91,7 @@ public class PrometheusMetricsThreadPoolTest { metricsConfig.setEnableJvm(false); metricsCollector.setCollectEnabled(true); metricsConfig.setEnableThreadpool(true); - metricsCollector.collectApplication(applicationModel); + metricsCollector.collectApplication(); PrometheusMetricsReporter reporter = new PrometheusMetricsReporter(metricsConfig.toUrl(), applicationModel); reporter.init(); exportHttpServer(reporter,port); @@ -142,7 +141,7 @@ public class PrometheusMetricsThreadPoolTest { @Test @SuppressWarnings("rawtypes") void testThreadPoolRejectMetrics() { - DefaultMetricsCollector collector = new DefaultMetricsCollector(); + DefaultMetricsCollector collector = new DefaultMetricsCollector(applicationModel); collector.setCollectEnabled(true); collector.setApplicationName(applicationModel.getApplicationName()); String threadPoolExecutorName="DubboServerHandler-20816"; 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 eddcaf1af3..b18ed313f7 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 @@ -53,19 +53,22 @@ public class RegistryMetricsCollector extends CombMetricsCollector lastNumMap = Collections.unmodifiableMap(event.getAttachmentValue(ATTACHMENT_KEY_LAST_NUM_MAP)); lastNumMap.forEach( - (k, v) -> collector.setNum(new MetricsKeyWrapper(key, OP_TYPE_NOTIFY), event.appName(), k, v)); + (k, v) -> collector.setNum(new MetricsKeyWrapper(key, OP_TYPE_NOTIFY), k, v)); } )); @@ -101,7 +101,7 @@ public final class RegistrySubDispatcher extends SimpleMetricsEventMulticaster { Map> summaryMap = event.getAttachmentValue(ATTACHMENT_DIRECTORY_MAP); summaryMap.forEach((metricsKey, map) -> map.forEach( - (k, v) -> collector.setNum(new MetricsKeyWrapper(key, OP_TYPE_DIRECTORY), event.appName(), k, v))); + (k, v) -> collector.setNum(new MetricsKeyWrapper(metricsKey, OP_TYPE_DIRECTORY), k, v))); } )); 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 2c042c9114..3dc6dad7d3 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 @@ -25,6 +25,7 @@ import org.apache.dubbo.metrics.model.key.MetricsKey; import org.apache.dubbo.metrics.model.key.MetricsKeyWrapper; 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.RegistryMetricsCollector; import org.apache.dubbo.metrics.registry.event.RegistryEvent; import org.apache.dubbo.rpc.model.ApplicationModel; @@ -76,17 +77,18 @@ class RegistryMetricsCollectorTest { MetricsEventBus.post(registryEvent, () -> { List metricSamples = collector.collect(); - // push success +1 - Assertions.assertEquals(1, metricSamples.size()); - Assertions.assertTrue(metricSamples.get(0) instanceof GaugeMetricSample); + // push success +1 -> other default 0 = RegistryMetricsConstants.APP_LEVEL_KEYS.size() + Assertions.assertEquals(RegistryMetricsConstants.APP_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; } ); // push finish rt +1 List metricSamples = collector.collect(); - //num(total+success) + rt(5) = 7 - Assertions.assertEquals(7, metricSamples.size()); + // RegistryMetricsConstants.APP_LEVEL_KEYS.size() + rt(5) = 12 + Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 5, metricSamples.size()); long c1 = registryEvent.getTimePair().calc(); @@ -108,7 +110,7 @@ class RegistryMetricsCollectorTest { metricSamples = collector.collect(); // num(total+success+error) + rt(5) - Assertions.assertEquals(8, metricSamples.size()); + Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 5, metricSamples.size()); // calc rt for (MetricSample sample : metricSamples) { @@ -138,18 +140,17 @@ class RegistryMetricsCollectorTest { List metricSamples = collector.collect(); // push success +1 - Assertions.assertEquals(1, metricSamples.size()); - Assertions.assertTrue(metricSamples.get(0) instanceof GaugeMetricSample); - Assertions.assertEquals(metricSamples.get(0).getName(), MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS.getName()); - Assertions.assertEquals(metricSamples.get(0).getTags().get("interface"), serviceName); + Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 1, metricSamples.size()); + // Service num only 1 and contains tag of interface + Assertions.assertEquals(1, metricSamples.stream().filter(metricSample -> serviceName.equals(metricSample.getTags().get("interface"))).count()); return null; } ); // push finish rt +1 List metricSamples = collector.collect(); - //num(total+success) + rt(5) = 7 - Assertions.assertEquals(7, metricSamples.size()); + // App(7) + rt(5) + service(total/success) = 14 + Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 5 + 2, metricSamples.size()); long c1 = registryEvent.getTimePair().calc(); registryEvent = RegistryEvent.toRsEvent(applicationModel, serviceName, 2); @@ -169,8 +170,8 @@ class RegistryMetricsCollectorTest { metricSamples = collector.collect(); - // num(total+success+error) + rt(5) - Assertions.assertEquals(8, metricSamples.size()); + // App(7) + rt(5) + service(total/success/failed) = 15 + Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 5 + 3, metricSamples.size()); // calc rt for (MetricSample sample : metricSamples) { @@ -198,20 +199,20 @@ class RegistryMetricsCollectorTest { MetricsEventBus.post(subscribeEvent, () -> { List metricSamples = collector.collect(); - - // push success +1 - Assertions.assertEquals(1, metricSamples.size()); - Assertions.assertTrue(metricSamples.get(0) instanceof GaugeMetricSample); - Assertions.assertEquals(metricSamples.get(0).getName(), MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM.getName()); - Assertions.assertEquals(metricSamples.get(0).getTags().get("interface"), serviceName); + Assertions.assertTrue(metricSamples.stream().allMatch(metricSample -> metricSample instanceof GaugeMetricSample)); + Assertions.assertTrue(metricSamples.stream().anyMatch(metricSample -> ((GaugeMetricSample) metricSample).applyAsDouble() == 1)); + // App(7) + (service success +1) + Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 1, metricSamples.size()); + // Service num only 1 and contains tag of interface + Assertions.assertEquals(1, metricSamples.stream().filter(metricSample -> serviceName.equals(metricSample.getTags().get("interface"))).count()); return null; } ); // push finish rt +1 List metricSamples = collector.collect(); - //num(total+success) + rt(5) = 7 - Assertions.assertEquals(7, metricSamples.size()); + // App(7) + rt(5) + service(total/success) = 14 + Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 5 + 2, metricSamples.size()); long c1 = subscribeEvent.getTimePair().calc(); subscribeEvent = RegistryEvent.toSsEvent(applicationModel, serviceName); @@ -231,8 +232,8 @@ class RegistryMetricsCollectorTest { metricSamples = collector.collect(); - // num(total+success+error) + rt(5) - Assertions.assertEquals(8, metricSamples.size()); + // App(7) + rt(5) + service(total/success/failed) = 15 + Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 5 + 3, metricSamples.size()); // calc rt for (MetricSample sample : metricSamples) { @@ -269,8 +270,8 @@ class RegistryMetricsCollectorTest { } ); List metricSamples = collector.collect(); - // num(total+service*3) + rt(5) = 9 - Assertions.assertEquals(9, metricSamples.size()); + // App(7) + num(service*3) + rt(5) = 9 + Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 3 + 5, metricSamples.size()); } } diff --git a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsSampleTest.java b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsSampleTest.java index 579a859ffe..73d5815948 100644 --- a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsSampleTest.java +++ b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsSampleTest.java @@ -87,8 +87,7 @@ class RegistryMetricsSampleTest { void testListener() { RegistryMetricsCollector collector = new RegistryMetricsCollector(applicationModel); collector.setCollectEnabled(true); - String applicationName = applicationModel.getApplicationName(); - collector.increment(applicationName, MetricsKey.REGISTER_METRIC_REQUESTS); + collector.increment(MetricsKey.REGISTER_METRIC_REQUESTS); } } 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 ebd4c599e6..193d0403a1 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.config.ApplicationConfig; import org.apache.dubbo.metrics.data.ApplicationStatComposite; import org.apache.dubbo.metrics.data.BaseStatComposite; import org.apache.dubbo.metrics.data.RtStatComposite; @@ -26,13 +27,16 @@ import org.apache.dubbo.metrics.model.container.LongContainer; 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.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.List; import java.util.Map; import java.util.Optional; -import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; import static org.apache.dubbo.metrics.model.key.MetricsKey.METRIC_RT_AVG; import static org.apache.dubbo.metrics.model.key.MetricsKey.METRIC_RT_MAX; @@ -46,24 +50,38 @@ import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE public class RegistryStatCompositeTest { + private ApplicationModel applicationModel; + private String applicationName; + private BaseStatComposite statComposite; - private final String applicationName = "app1"; - private final BaseStatComposite statComposite = new BaseStatComposite() { - @Override - protected void init(ApplicationStatComposite applicationStatComposite) { - applicationStatComposite.init(RegistryMetricsConstants.APP_LEVEL_KEYS); - } + @BeforeEach + public void setup() { + FrameworkModel frameworkModel = FrameworkModel.defaultModel(); + applicationModel = frameworkModel.newApplication(); + ApplicationConfig application = new ApplicationConfig(); + application.setName("App1"); + applicationModel.getApplicationConfigManager().setApplication(application); + applicationName = applicationModel.getApplicationName(); + statComposite = new BaseStatComposite(applicationModel) { + @Override + protected void init(ApplicationStatComposite applicationStatComposite) { + super.init(applicationStatComposite); + applicationStatComposite.init(RegistryMetricsConstants.APP_LEVEL_KEYS); + } - @Override - protected void init(ServiceStatComposite serviceStatComposite) { - serviceStatComposite.initWrapper(RegistryMetricsConstants.SERVICE_LEVEL_KEYS); - } + @Override + protected void init(ServiceStatComposite serviceStatComposite) { + super.init(serviceStatComposite); + serviceStatComposite.initWrapper(RegistryMetricsConstants.SERVICE_LEVEL_KEYS); + } - @Override - protected void init(RtStatComposite rtStatComposite) { - rtStatComposite.init(OP_TYPE_REGISTER, OP_TYPE_SUBSCRIBE, OP_TYPE_NOTIFY, OP_TYPE_REGISTER_SERVICE, OP_TYPE_SUBSCRIBE_SERVICE); - } - }; + @Override + protected void init(RtStatComposite rtStatComposite) { + super.init(rtStatComposite); + rtStatComposite.init(OP_TYPE_REGISTER, OP_TYPE_SUBSCRIBE, OP_TYPE_NOTIFY, OP_TYPE_REGISTER_SERVICE, OP_TYPE_SUBSCRIBE_SERVICE); + } + }; + } @Test void testInit() { @@ -71,7 +89,7 @@ public class RegistryStatCompositeTest { //(rt)5 * (applicationRegister,subscribe,notify,applicationRegister.service,subscribe.service) Assertions.assertEquals(5 * 5, statComposite.getRtStatComposite().getRtStats().size()); statComposite.getApplicationStatComposite().getApplicationNumStats().values().forEach((v -> - Assertions.assertEquals(v, new ConcurrentHashMap<>()))); + Assertions.assertEquals(v.get(), new AtomicLong(0L).get()))); statComposite.getRtStatComposite().getRtStats().forEach(rtContainer -> { for (Map.Entry entry : rtContainer.entrySet()) { @@ -82,13 +100,13 @@ public class RegistryStatCompositeTest { @Test void testIncrement() { - statComposite.incrementApp(REGISTER_METRIC_REQUESTS, applicationName, 1); - Assertions.assertEquals(1L, statComposite.getApplicationStatComposite().getApplicationNumStats().get(REGISTER_METRIC_REQUESTS).get(applicationName).get()); + statComposite.incrementApp(REGISTER_METRIC_REQUESTS, 1); + Assertions.assertEquals(1L, statComposite.getApplicationStatComposite().getApplicationNumStats().get(REGISTER_METRIC_REQUESTS).get()); } @Test void testCalcRt() { - statComposite.calcApplicationRt(applicationName, OP_TYPE_NOTIFY.getType(), 10L); + statComposite.calcApplicationRt(OP_TYPE_NOTIFY.getType(), 10L); Assertions.assertTrue(statComposite.getRtStatComposite().getRtStats().stream().anyMatch(longContainer -> longContainer.specifyType(OP_TYPE_NOTIFY.getType()))); Optional> subContainer = statComposite.getRtStatComposite().getRtStats().stream().filter(longContainer -> longContainer.specifyType(OP_TYPE_NOTIFY.getType())).findFirst(); subContainer.ifPresent(v -> Assertions.assertEquals(10L, v.get(applicationName).longValue())); @@ -97,29 +115,28 @@ public class RegistryStatCompositeTest { @Test @SuppressWarnings("rawtypes") void testCalcServiceKeyRt() { - String applicationName = "TestApp"; String serviceKey = "TestService"; String registryOpType = OP_TYPE_REGISTER_SERVICE.getType(); Long responseTime1 = 100L; Long responseTime2 = 200L; - statComposite.calcServiceKeyRt(applicationName, serviceKey, registryOpType, responseTime1); - statComposite.calcServiceKeyRt(applicationName, serviceKey, registryOpType, responseTime2); + statComposite.calcServiceKeyRt(serviceKey, registryOpType, responseTime1); + statComposite.calcServiceKeyRt(serviceKey, registryOpType, responseTime2); List exportedRtMetrics = statComposite.export(MetricsCategory.RT); GaugeMetricSample minSample = (GaugeMetricSample) exportedRtMetrics.stream() - .filter(sample -> sample.getTags().containsValue(applicationName)) - .filter(sample -> sample.getName().equals(METRIC_RT_MIN.getNameByType("register.service"))) - .findFirst().orElse(null); + .filter(sample -> sample.getTags().containsValue(applicationName)) + .filter(sample -> sample.getName().equals(METRIC_RT_MIN.getNameByType("register.service"))) + .findFirst().orElse(null); GaugeMetricSample maxSample = (GaugeMetricSample) exportedRtMetrics.stream() - .filter(sample -> sample.getTags().containsValue(applicationName)) - .filter(sample -> sample.getName().equals(METRIC_RT_MAX.getNameByType("register.service"))) - .findFirst().orElse(null); + .filter(sample -> sample.getTags().containsValue(applicationName)) + .filter(sample -> sample.getName().equals(METRIC_RT_MAX.getNameByType("register.service"))) + .findFirst().orElse(null); GaugeMetricSample avgSample = (GaugeMetricSample) exportedRtMetrics.stream() - .filter(sample -> sample.getTags().containsValue(applicationName)) - .filter(sample -> sample.getName().equals(METRIC_RT_AVG.getNameByType("register.service"))) - .findFirst().orElse(null); + .filter(sample -> sample.getTags().containsValue(applicationName)) + .filter(sample -> sample.getName().equals(METRIC_RT_AVG.getNameByType("register.service"))) + .findFirst().orElse(null); Assertions.assertNotNull(minSample); Assertions.assertNotNull(maxSample); diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Constants.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Constants.java index 9920ab126a..bd2ad05220 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Constants.java +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Constants.java @@ -144,8 +144,10 @@ public interface Constants { String TELNET_KEY = "telnet"; String HEARTBEAT_KEY = "heartbeat"; String HEARTBEAT_CONFIG_KEY = "dubbo.protocol.default-heartbeat"; + String CLOSE_TIMEOUT_CONFIG_KEY = "dubbo.protocol.default-close-timeout"; int DEFAULT_HEARTBEAT = 60 * 1000; String HEARTBEAT_TIMEOUT_KEY = "heartbeat.timeout"; + String CLOSE_TIMEOUT_KEY = "close.timeout"; String CONNECTIONS_KEY = "connections"; int DEFAULT_BACKLOG = 1024; diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/CloseTimerTask.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/CloseTimerTask.java index 7c2eea2289..aa4df8d053 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/CloseTimerTask.java +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/CloseTimerTask.java @@ -32,11 +32,11 @@ public class CloseTimerTask extends AbstractTimerTask { private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(CloseTimerTask.class); - private final int idleTimeout; + private final int closeTimeout; - public CloseTimerTask(ChannelProvider channelProvider, HashedWheelTimer hashedWheelTimer, Long heartbeatTimeoutTick, int idleTimeout) { - super(channelProvider, hashedWheelTimer, heartbeatTimeoutTick); - this.idleTimeout = idleTimeout; + public CloseTimerTask(ChannelProvider channelProvider, HashedWheelTimer hashedWheelTimer, Long tick, int closeTimeout) { + super(channelProvider, hashedWheelTimer, tick); + this.closeTimeout = closeTimeout; } @Override @@ -46,9 +46,9 @@ public class CloseTimerTask extends AbstractTimerTask { Long lastWrite = lastWrite(channel); Long now = now(); // check ping & pong at server - if ((lastRead != null && now - lastRead > idleTimeout) - || (lastWrite != null && now - lastWrite > idleTimeout)) { - logger.warn(PROTOCOL_FAILED_RESPONSE, "", "", "Close channel " + channel + ", because idleCheck timeout: " + idleTimeout + "ms"); + if ((lastRead != null && now - lastRead > closeTimeout) + || (lastWrite != null && now - lastWrite > closeTimeout)) { + logger.warn(PROTOCOL_FAILED_RESPONSE, "", "", "Close channel " + channel + ", because idleCheck timeout: " + closeTimeout + "ms"); channel.close(); } } catch (Throwable t) { diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeServer.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeServer.java index f27aae80e8..3dca5a9746 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeServer.java +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeServer.java @@ -49,8 +49,7 @@ import static org.apache.dubbo.common.constants.LoggerCodeConstants.TRANSPORT_FA import static org.apache.dubbo.remoting.Constants.HEARTBEAT_CHECK_TICK; import static org.apache.dubbo.remoting.Constants.LEAST_HEARTBEAT_DURATION; import static org.apache.dubbo.remoting.Constants.TICKS_PER_WHEEL; -import static org.apache.dubbo.remoting.utils.UrlUtils.getHeartbeat; -import static org.apache.dubbo.remoting.utils.UrlUtils.getIdleTimeout; +import static org.apache.dubbo.remoting.utils.UrlUtils.getCloseTimeout; /** * ExchangeServerImpl @@ -211,11 +210,9 @@ public class HeaderExchangeServer implements ExchangeServer { public void reset(URL url) { server.reset(url); try { - int currHeartbeat = getHeartbeat(getUrl()); - int currIdleTimeout = getIdleTimeout(getUrl()); - int heartbeat = getHeartbeat(url); - int idleTimeout = getIdleTimeout(url); - if (currHeartbeat != heartbeat || currIdleTimeout != idleTimeout) { + int currCloseTimeout = getCloseTimeout(getUrl()); + int closeTimeout = getCloseTimeout(url); + if (closeTimeout != currCloseTimeout) { cancelCloseTask(); startIdleCheckTask(url); } @@ -262,9 +259,9 @@ public class HeaderExchangeServer implements ExchangeServer { private void startIdleCheckTask(URL url) { if (!server.canHandleIdle()) { AbstractTimerTask.ChannelProvider cp = () -> unmodifiableCollection(HeaderExchangeServer.this.getChannels()); - int idleTimeout = getIdleTimeout(url); - long idleTimeoutTick = calculateLeastDuration(idleTimeout); - this.closeTimer = new CloseTimerTask(cp, IDLE_CHECK_TIMER.get(), idleTimeoutTick, idleTimeout); + int closeTimeout = getCloseTimeout(url); + long closeTimeoutTick = calculateLeastDuration(closeTimeout); + this.closeTimer = new CloseTimerTask(cp, IDLE_CHECK_TIMER.get(), closeTimeoutTick, closeTimeout); } } } diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/utils/UrlUtils.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/utils/UrlUtils.java index fe620b613f..e3f510c7cc 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/utils/UrlUtils.java +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/utils/UrlUtils.java @@ -36,6 +36,27 @@ import static org.apache.dubbo.remoting.Constants.SERIALIZATION_KEY; public class UrlUtils { private static final String ALLOWED_SERIALIZATION_KEY = "allowedSerialization"; + public static int getCloseTimeout(URL url) { + String configuredCloseTimeout = System.getProperty(Constants.CLOSE_TIMEOUT_CONFIG_KEY); + int defaultCloseTimeout = -1; + if (StringUtils.isNotEmpty(configuredCloseTimeout)) { + try { + defaultCloseTimeout = Integer.parseInt(configuredCloseTimeout); + } catch (NumberFormatException e) { + // use default heartbeat + } + } + if (defaultCloseTimeout < 0) { + defaultCloseTimeout = getIdleTimeout(url); + } + int closeTimeout = url.getParameter(Constants.CLOSE_TIMEOUT_KEY, defaultCloseTimeout); + int heartbeat = getHeartbeat(url); + if (closeTimeout < heartbeat * 2) { + throw new IllegalStateException("closeTimeout < heartbeatInterval * 2"); + } + return closeTimeout; + } + public static int getIdleTimeout(URL url) { int heartBeat = getHeartbeat(url); // idleTimeout should be at least more than twice heartBeat because possible retries of client. diff --git a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/utils/UrlUtilsTest.java b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/utils/UrlUtilsTest.java index 2ba6f2b506..6a957aee5e 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/utils/UrlUtilsTest.java +++ b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/utils/UrlUtilsTest.java @@ -46,4 +46,28 @@ class UrlUtilsTest { Assertions.assertEquals(200, UrlUtils.getHeartbeat(url)); System.clearProperty(Constants.HEARTBEAT_CONFIG_KEY); } + + @Test + void testGetCloseTimeout() { + URL url1 = URL.valueOf("dubbo://127.0.0.1:12345?heartbeat=10000"); + URL url2 = URL.valueOf("dubbo://127.0.0.1:12345?heartbeat=10000&heartbeat.timeout=50000"); + URL url3 = URL.valueOf("dubbo://127.0.0.1:12345?heartbeat=10000&heartbeat.timeout=10000"); + URL url4 = URL.valueOf("dubbo://127.0.0.1:12345?close.timeout=30000&heartbeat=10000&heartbeat.timeout=10000"); + URL url5 = URL.valueOf("dubbo://127.0.0.1:12345?close.timeout=40000&heartbeat=10000&heartbeat.timeout=50000"); + URL url6 = URL.valueOf("dubbo://127.0.0.1:12345?close.timeout=10000&heartbeat=10000&heartbeat.timeout=10000"); + Assertions.assertEquals(30000, UrlUtils.getCloseTimeout(url1)); + Assertions.assertEquals(50000, UrlUtils.getCloseTimeout(url2)); + Assertions.assertThrows(RuntimeException.class, () -> UrlUtils.getCloseTimeout(url3)); + Assertions.assertThrows(RuntimeException.class, () -> UrlUtils.getCloseTimeout(url4)); + Assertions.assertEquals(40000, UrlUtils.getCloseTimeout(url5)); + Assertions.assertThrows(RuntimeException.class, () -> UrlUtils.getCloseTimeout(url6)); + } + + @Test + void testConfiguredClose() { + System.setProperty(Constants.CLOSE_TIMEOUT_CONFIG_KEY, "180000"); + URL url = URL.valueOf("dubbo://127.0.0.1:12345"); + Assertions.assertEquals(180000, UrlUtils.getCloseTimeout(url)); + System.clearProperty(Constants.HEARTBEAT_CONFIG_KEY); + } } diff --git a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyChannel.java b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyChannel.java index 677a6579e6..b87c166a86 100644 --- a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyChannel.java +++ b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyChannel.java @@ -72,7 +72,7 @@ final class NettyChannel extends AbstractChannel { private final Netty4BatchWriteQueue writeQueue; - private final Codec2 codec; + private Codec2 codec; private final boolean encodeInIOThread; @@ -365,4 +365,8 @@ final class NettyChannel extends AbstractChannel { return frameworkModel.getExtensionLoader(Codec2.class).getExtension("default"); } } + + public void setCodec(Codec2 codec) { + this.codec = codec; + } } diff --git a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyConfigOperator.java b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyConfigOperator.java index dca821ea68..c708b12810 100644 --- a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyConfigOperator.java +++ b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyConfigOperator.java @@ -60,6 +60,7 @@ public class NettyConfigOperator implements ChannelOperator { } if (!(codec2 instanceof DefaultCodec)){ + ((NettyChannel) channel).setCodec(codec2); NettyCodecAdapter codec = new NettyCodecAdapter(codec2, channel.getUrl(), handler); ((NettyChannel) channel).getNioChannel().pipeline().addLast( codec.getDecoder() diff --git a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyServer.java b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyServer.java index cbb547a526..45b3ac90cf 100644 --- a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyServer.java +++ b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyServer.java @@ -136,14 +136,13 @@ public class NettyServer extends AbstractServer { .childHandler(new ChannelInitializer() { @Override protected void initChannel(SocketChannel ch) throws Exception { - // FIXME: should we use getTimeout()? - int idleTimeout = UrlUtils.getIdleTimeout(getUrl()); + int closeTimeout = UrlUtils.getCloseTimeout(getUrl()); NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec(), getUrl(), NettyServer.this); ch.pipeline().addLast("negotiation", new SslServerTlsHandler(getUrl())); ch.pipeline() .addLast("decoder", adapter.getDecoder()) .addLast("encoder", adapter.getEncoder()) - .addLast("server-idle-handler", new IdleStateHandler(0, 0, idleTimeout, MILLISECONDS)) + .addLast("server-idle-handler", new IdleStateHandler(0, 0, closeTimeout, MILLISECONDS)) .addLast("handler", nettyServerHandler); } });