Merge branch '3.2' into 3.3

This commit is contained in:
crazyhzm 2023-05-24 22:24:10 +08:00
commit 34eb252178
28 changed files with 269 additions and 92 deletions

View File

@ -359,11 +359,11 @@ public class PojoUtils {
Map<String, Type> mapGeneric = new HashMap<>(8);
mapGeneric.putAll(mapParent);
TypeVariable<? extends Class<?>>[] typeParameters = type.getTypeParameters();
if(genericType instanceof ParameterizedType && typeParameters.length > 0) {
ParameterizedType parameterizedType = (ParameterizedType)genericType;
if (genericType instanceof ParameterizedType && typeParameters.length > 0) {
ParameterizedType parameterizedType = (ParameterizedType) genericType;
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
for (int i = 0; i < typeParameters.length; i++) {
if(!(actualTypeArguments[i] instanceof TypeVariable)) {
if (!(actualTypeArguments[i] instanceof TypeVariable)) {
mapGeneric.put(typeParameters[i].getTypeName(), actualTypeArguments[i]);
}
}
@ -534,26 +534,23 @@ public class PojoUtils {
Object value = entry.getValue();
if (value != null) {
Method method = getSetterMethod(dest.getClass(), name, value.getClass());
Field field = getField(dest.getClass(), name);
Field field = getAndCacheField(dest.getClass(), name);
if (method != null) {
if (!method.isAccessible()) {
method.setAccessible(true);
}
Type containType = mapGeneric.get(field.getGenericType().getTypeName());
if(containType != null) {
if (containType != null) {
//is generic
if(containType instanceof ParameterizedType) {
value = realize1(value, (Class<?>) ((ParameterizedType)containType).getRawType(), containType, mapGeneric, history);
}
else if (containType instanceof Class){
if (containType instanceof ParameterizedType) {
value = realize1(value, (Class<?>) ((ParameterizedType) containType).getRawType(), containType, mapGeneric, history);
} else if (containType instanceof Class) {
value = realize1(value, (Class<?>) containType, containType, mapGeneric, history);
}
else {
} else {
Type ptype = method.getGenericParameterTypes()[0];
value = realize1(value, method.getParameterTypes()[0], ptype, mapGeneric, history);
}
}
else {
} else {
Type ptype = method.getGenericParameterTypes()[0];
value = realize1(value, method.getParameterTypes()[0], ptype, mapGeneric, history);
}
@ -626,7 +623,7 @@ public class PojoUtils {
try {
Constructor<?> messagedConstructor = cls.getDeclaredConstructor(String.class);
return messagedConstructor.newInstance(message);
} catch (Throwable t) {
} catch (Exception t) {
return newInstance(cls);
}
}
@ -634,7 +631,7 @@ public class PojoUtils {
private static Object newInstance(Class<?> cls) {
try {
return cls.getDeclaredConstructor().newInstance();
} catch (Throwable t) {
} catch (Exception t) {
Constructor<?>[] constructors = cls.getDeclaredConstructors();
/*
From Javadoc java.lang.Class#getDeclaredConstructors
@ -653,7 +650,7 @@ public class PojoUtils {
constructor.setAccessible(true);
Object[] parameters = Arrays.stream(constructor.getParameterTypes()).map(PojoUtils::getDefaultValue).toArray();
return constructor.newInstance(parameters);
} catch (Throwable e) {
} catch (Exception e) {
lastError = e;
}
}
@ -704,12 +701,24 @@ public class PojoUtils {
return method;
}
private static Field getField(Class<?> cls, String fieldName) {
Field result = null;
private static Field getAndCacheField(Class<?> cls, String fieldName) {
Field result;
if (CLASS_FIELD_CACHE.containsKey(cls) && CLASS_FIELD_CACHE.get(cls).containsKey(fieldName)) {
return CLASS_FIELD_CACHE.get(cls).get(fieldName);
}
for(Class<?> acls = cls; acls != null; acls = acls.getSuperclass()) {
result = getField(cls, fieldName);
if (result != null) {
ConcurrentMap<String, Field> fields = CLASS_FIELD_CACHE.computeIfAbsent(cls, k -> new ConcurrentHashMap<>());
fields.putIfAbsent(fieldName, result);
}
return result;
}
private static Field getField(Class<?> cls, String fieldName) {
Field result = null;
for (Class<?> acls = cls; acls != null; acls = acls.getSuperclass()) {
try {
result = acls.getDeclaredField(fieldName);
if (!Modifier.isPublic(result.getModifiers())) {
@ -718,7 +727,7 @@ public class PojoUtils {
} catch (NoSuchFieldException e) {
}
}
if(result == null) {
if (result == null && cls != null) {
for (Field field : cls.getFields()) {
if (fieldName.equals(field.getName()) && ReflectUtils.isPublicInstanceField(field)) {
result = field;
@ -726,11 +735,6 @@ public class PojoUtils {
}
}
}
if (result != null) {
ConcurrentMap<String, Field> fields = CLASS_FIELD_CACHE.computeIfAbsent(cls, k -> new ConcurrentHashMap<>());
fields.putIfAbsent(fieldName, result);
}
return result;
}

View File

@ -271,6 +271,15 @@ public class SerializeSecurityConfigurator implements ScopeClassLoaderListener<M
addToAllow(clazz.getName());
if (ClassUtils.isSimpleType(clazz) || clazz.isPrimitive() || clazz.isArray()) {
return;
}
String className = clazz.getName();
if (className.startsWith("java.") || className.startsWith("javax.") || className.startsWith("com.sun.") ||
className.startsWith("sun.") || className.startsWith("jdk.")) {
return;
}
Class<?>[] interfaces = clazz.getInterfaces();
for (Class<?> interfaceClass : interfaces) {
checkClass(markedClass, interfaceClass);

View File

@ -17,6 +17,45 @@
package com.alibaba.dubbo.rpc.cluster.loadbalance;
import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.cluster.LoadBalance;
import java.util.List;
@Deprecated
public abstract class AbstractLoadBalance extends org.apache.dubbo.rpc.cluster.loadbalance.AbstractLoadBalance {
public abstract class AbstractLoadBalance extends org.apache.dubbo.rpc.cluster.loadbalance.AbstractLoadBalance implements LoadBalance {
@Override
public <T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) {
if (invokers == null || invokers.size() == 0)
return null;
if (invokers.size() == 1)
return invokers.get(0);
return doSelect(invokers, url, invocation);
}
protected abstract <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation);
protected int getWeight(Invoker<?> invoker, Invocation invocation) {
int weight = invoker.getUrl().getMethodParameter(invocation.getMethodName(), Constants.WEIGHT_KEY, Constants.DEFAULT_WEIGHT);
if (weight > 0) {
long timestamp = invoker.getUrl().getParameter(Constants.TIMESTAMP_KEY, 0L);
if (timestamp > 0L) {
int uptime = (int) (System.currentTimeMillis() - timestamp);
int warmup = invoker.getUrl().getParameter(Constants.WARMUP_KEY, Constants.DEFAULT_WARMUP);
if (uptime > 0 && uptime < warmup) {
weight = calculateWarmupWeight(uptime, warmup, weight);
}
}
}
return weight;
}
static int calculateWarmupWeight(int uptime, int warmup, int weight) {
int ww = (int) ( (float) uptime / ( (float) warmup / (float) weight ) );
return ww < 1 ? 1 : (ww > weight ? weight : ww);
}
}

View File

@ -27,7 +27,7 @@
<description>The spring config module of dubbo project</description>
<properties>
<skip_maven_deploy>false</skip_maven_deploy>
<spring-boot.version>2.7.11</spring-boot.version>
<spring-boot.version>2.7.12</spring-boot.version>
<!-- Uncomment spring_version property to check Spring 4.x compatibility -->
<!-- <spring_version>4.3.30.RELEASE</spring_version> -->
</properties>

View File

@ -30,7 +30,7 @@
<properties>
<skip_maven_deploy>true</skip_maven_deploy>
<spring-boot-maven-plugin.version>2.7.11</spring-boot-maven-plugin.version>
<spring-boot-maven-plugin.version>2.7.12</spring-boot-maven-plugin.version>
</properties>
<modules>

View File

@ -36,7 +36,7 @@
<properties>
<skip_maven_deploy>true</skip_maven_deploy>
<spring-boot-maven-plugin.version>2.7.11</spring-boot-maven-plugin.version>
<spring-boot-maven-plugin.version>2.7.12</spring-boot-maven-plugin.version>
</properties>
<artifactId>dubbo-demo-api</artifactId>

View File

@ -31,7 +31,7 @@
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<slf4j-log4j12.version>1.7.33</slf4j-log4j12.version>
<spring-boot.version>2.7.11</spring-boot.version>
<spring-boot.version>2.7.12</spring-boot.version>
<skip_maven_deploy>true</skip_maven_deploy>
</properties>

View File

@ -31,7 +31,7 @@
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<slf4j-log4j12.version>1.7.33</slf4j-log4j12.version>
<spring-boot.version>2.7.11</spring-boot.version>
<spring-boot.version>2.7.12</spring-boot.version>
<skip_maven_deploy>true</skip_maven_deploy>
</properties>

View File

@ -36,8 +36,8 @@
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<skip_maven_deploy>true</skip_maven_deploy>
<spring-boot.version>2.7.11</spring-boot.version>
<spring-boot-maven-plugin.version>2.7.11</spring-boot-maven-plugin.version>
<spring-boot.version>2.7.12</spring-boot.version>
<spring-boot-maven-plugin.version>2.7.12</spring-boot-maven-plugin.version>
<micrometer-core.version>1.11.0</micrometer-core.version>
</properties>
<dependencyManagement>

View File

@ -32,7 +32,7 @@
<properties>
<skip_maven_deploy>true</skip_maven_deploy>
<spring-boot-maven-plugin.version>2.7.11</spring-boot-maven-plugin.version>
<spring-boot-maven-plugin.version>2.7.12</spring-boot-maven-plugin.version>
</properties>
<modules>

View File

@ -102,7 +102,7 @@
<httpclient_version>4.5.14</httpclient_version>
<httpcore_version>4.4.16</httpcore_version>
<fastjson_version>1.2.83</fastjson_version>
<fastjson2_version>2.0.31</fastjson2_version>
<fastjson2_version>2.0.32</fastjson2_version>
<zookeeper_version>3.4.14</zookeeper_version>
<curator_version>4.3.0</curator_version>
<curator_test_version>2.12.0</curator_test_version>
@ -114,7 +114,7 @@
<cxf_version>3.5.5</cxf_version>
<thrift_version>0.18.1</thrift_version>
<hessian_version>4.0.66</hessian_version>
<protobuf-java_version>3.23.0</protobuf-java_version>
<protobuf-java_version>3.23.1</protobuf-java_version>
<javax_annotation-api_version>1.3.2</javax_annotation-api_version>
<servlet_version>3.1.0</servlet_version>
<jetty_version>9.4.51.v20230217</jetty_version>
@ -124,7 +124,7 @@
<hibernate_validator_new_version>7.0.5.Final</hibernate_validator_new_version>
<jel_version>3.0.1-b12</jel_version>
<jcache_version>1.1.1</jcache_version>
<kryo_version>4.0.2</kryo_version>
<kryo_version>4.0.3</kryo_version>
<kryo_serializers_version>0.45</kryo_serializers_version>
<fst_version>2.57</fst_version>
<avro_version>1.11.1</avro_version>
@ -177,14 +177,14 @@
<test_container_version>1.18.1</test_container_version>
<etcd_launcher_version>0.7.5</etcd_launcher_version>
<hessian_lite_version>3.2.13</hessian_lite_version>
<swagger_version>1.6.10</swagger_version>
<swagger_version>1.6.11</swagger_version>
<snappy_java_version>1.1.9.1</snappy_java_version>
<bouncycastle-bcprov_version>1.70</bouncycastle-bcprov_version>
<metrics_version>2.0.6</metrics_version>
<sofa_registry_version>5.4.3</sofa_registry_version>
<gson_version>2.10.1</gson_version>
<jackson_version>2.15.0</jackson_version>
<jackson_version>2.15.1</jackson_version>
<jsonrpc_version>1.6</jsonrpc_version>
<mortbay_jetty_version>6.1.26</mortbay_jetty_version>
<portlet_version>2.0</portlet_version>

View File

@ -17,9 +17,13 @@
package org.apache.dubbo.metrics.data;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.metrics.exception.MetricsNeverHappenException;
import org.apache.dubbo.metrics.model.MethodMetric;
import org.apache.dubbo.metrics.model.MetricsCategory;
import org.apache.dubbo.metrics.model.MetricsSupport;
import org.apache.dubbo.metrics.model.key.MetricsKeyWrapper;
import org.apache.dubbo.metrics.model.sample.CounterMetricSample;
import org.apache.dubbo.metrics.model.sample.GaugeMetricSample;
@ -41,9 +45,12 @@ import java.util.concurrent.atomic.AtomicLong;
*/
public class MethodStatComposite extends AbstractMetricsExport {
private static final Logger logger = LoggerFactory.getLogger(MethodStatComposite.class);
public MethodStatComposite(ApplicationModel applicationModel) {
super(applicationModel);
}
private final Map<MetricsKeyWrapper, Map<MethodMetric, AtomicLong>> methodNumStats = new ConcurrentHashMap<>();
public void initWrapper(List<MetricsKeyWrapper> metricsKeyWrappers) {
@ -58,6 +65,7 @@ public class MethodStatComposite extends AbstractMetricsExport {
return;
}
methodNumStats.get(wrapper).computeIfAbsent(new MethodMetric(getApplicationModel(), invocation), k -> new AtomicLong(0L)).getAndAdd(size);
MetricsSupport.fillZero(methodNumStats);
}
public List<MetricSample> export(MetricsCategory category) {
@ -65,11 +73,13 @@ public class MethodStatComposite extends AbstractMetricsExport {
for (MetricsKeyWrapper wrapper : methodNumStats.keySet()) {
Map<MethodMetric, AtomicLong> stringAtomicLongMap = methodNumStats.get(wrapper);
for (MethodMetric methodMetric : stringAtomicLongMap.keySet()) {
if (methodMetric.getSampleType() == MetricSample.Type.GAUGE) {
if (wrapper.getSampleType() == MetricSample.Type.COUNTER) {
list.add(new CounterMetricSample<>(wrapper,
methodMetric.getTags(), category, stringAtomicLongMap.get(methodMetric)));
} else {
methodMetric.getTags(), category, stringAtomicLongMap.get(methodMetric)));
} else if (wrapper.getSampleType() == MetricSample.Type.GAUGE) {
list.add(new GaugeMetricSample<>(wrapper, methodMetric.getTags(), category, stringAtomicLongMap, value -> value.get(methodMetric).get()));
} else {
throw new MetricsNeverHappenException("Unsupported metricSample type: " + wrapper.getSampleType());
}
}

View File

@ -19,6 +19,7 @@ package org.apache.dubbo.metrics.data;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.metrics.model.MetricsCategory;
import org.apache.dubbo.metrics.model.MetricsSupport;
import org.apache.dubbo.metrics.model.ServiceKeyMetric;
import org.apache.dubbo.metrics.model.key.MetricsKeyWrapper;
import org.apache.dubbo.metrics.model.sample.GaugeMetricSample;
@ -57,6 +58,7 @@ public class ServiceStatComposite extends AbstractMetricsExport {
return;
}
serviceWrapperNumStats.get(wrapper).computeIfAbsent(new ServiceKeyMetric(getApplicationModel(), serviceKey), k -> new AtomicLong(0L)).getAndAdd(size);
MetricsSupport.fillZero(serviceWrapperNumStats);
}
public void setServiceKey(MetricsKeyWrapper wrapper, String serviceKey, int num) {
@ -64,6 +66,7 @@ public class ServiceStatComposite extends AbstractMetricsExport {
return;
}
serviceWrapperNumStats.get(wrapper).computeIfAbsent(new ServiceKeyMetric(getApplicationModel(), serviceKey), k -> new AtomicLong(0L)).set(num);
MetricsSupport.fillZero(serviceWrapperNumStats);
}
public List<MetricSample> export(MetricsCategory category) {

View File

@ -18,6 +18,7 @@
package org.apache.dubbo.metrics.model;
import org.apache.dubbo.common.Version;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.metrics.collector.MethodMetricsCollector;
import org.apache.dubbo.metrics.collector.ServiceMetricsCollector;
import org.apache.dubbo.metrics.event.MetricsEvent;
@ -35,6 +36,9 @@ import org.apache.dubbo.rpc.model.ApplicationModel;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_CHAR_SEPARATOR;
import static org.apache.dubbo.common.constants.CommonConstants.PATH_SEPARATOR;
@ -158,9 +162,9 @@ public class MetricsSupport {
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) {
&& isGenericCall(((RpcInvocation) invocation).getParameterTypesDesc(), methodName)
&& invocation.getArguments() != null
&& invocation.getArguments().length == 3) {
methodName = ((String) invocation.getArguments()[0]).trim();
}
return methodName;
@ -224,4 +228,21 @@ public class MetricsSupport {
collector.increment(event.getAttachmentValue(INVOCATION), new MetricsKeyWrapper(metricsKey, placeType), SELF_INCREMENT_SIZE);
collector.addRt(event.getAttachmentValue(INVOCATION), placeType.getType(), event.getTimePair().calc());
}
/**
* Generate a complete indicator item for an interface/method
*/
public static <T> void fillZero(Map<MetricsKeyWrapper, Map<T, AtomicLong>> data) {
if (CollectionUtils.isEmptyMap(data)) {
return;
}
Set<T> allKeyMetrics = data.values().stream().flatMap(map -> map.keySet().stream()).collect(Collectors.toSet());
data.forEach((keyWrapper, mapVal) ->
{
for (T key : allKeyMetrics) {
mapVal.computeIfAbsent(key, k -> new AtomicLong(0));
}
});
}
}

View File

@ -17,7 +17,8 @@
package org.apache.dubbo.metrics.model.key;
import io.micrometer.common.lang.Nullable;
import org.apache.dubbo.common.lang.Nullable;
/**
* The overall event set, including the event processing functions in three stages

View File

@ -23,18 +23,27 @@ import org.apache.dubbo.metrics.listener.AbstractMetricsKeyListener;
import java.util.function.BiFunction;
import java.util.function.Function;
/**
* The behavior wrapper class of MetricsKey,
* which saves the complete content of the key {@link MetricsPlaceValue},
* the corresponding collector {@link CombMetricsCollector},
* and the event listener (generate function) at the key level {@link AbstractMetricsKeyListener}
*/
public class MetricsCat {
private MetricsPlaceValue placeType;
private final Function<CombMetricsCollector, AbstractMetricsKeyListener> eventFunc;
/**
* @param metricsKey The key corresponding to the listening event, not necessarily the export key(export key may be dynamic)
* @param biFunc Binary function, corresponding to MetricsKey with less content, corresponding to post event
*/
public MetricsCat(MetricsKey metricsKey, BiFunction<MetricsKey, CombMetricsCollector, AbstractMetricsKeyListener> biFunc) {
this.eventFunc = collector -> biFunc.apply(metricsKey, collector);
}
/**
* @param metricsKey The key that the current category listens tonot necessarily the export key(export key may be dynamic)
* @param tpFunc Build the func that outputs the MetricsListener by listen metricsKey
* @param tpFunc Ternary function, corresponding to finish and error events, because an additional record rt is required, and the type type of metricsKey is required
*/
public MetricsCat(MetricsKey metricsKey, TpFunction<MetricsKey, MetricsPlaceValue, CombMetricsCollector, AbstractMetricsKeyListener> tpFunc) {
this.eventFunc = collector -> tpFunc.apply(metricsKey, placeType, collector);

View File

@ -134,12 +134,6 @@ public enum MetricsKey {
return String.format(name, type);
}
public final MetricsKey formatName(String type) {
this.name = String.format(name, type);
return this;
}
public final String getDescription() {
return this.description;
}

View File

@ -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.metrics.model.sample.MetricSample;
import org.apache.dubbo.rpc.model.ApplicationModel;
import java.util.Map;
@ -39,6 +40,11 @@ public class MetricsKeyWrapper {
*/
private final MetricsPlaceValue placeType;
/**
* Exported sample type
*/
private MetricSample.Type sampleType = MetricSample.Type.COUNTER;
/**
* When the MetricsPlaceType is null, it is equivalent to a single MetricsKey.
* Use the decorator mode to share a container with MetricsKey
@ -48,6 +54,15 @@ public class MetricsKeyWrapper {
this.placeType = placeType;
}
public MetricsKeyWrapper setSampleType(MetricSample.Type sampleType) {
this.sampleType = sampleType;
return this;
}
public MetricSample.Type getSampleType() {
return sampleType;
}
public MetricsPlaceValue getPlaceType() {
return placeType;
}

View File

@ -0,0 +1,59 @@
/*
* 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;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.metrics.model.MetricsSupport;
import org.apache.dubbo.metrics.model.ServiceKeyMetric;
import org.apache.dubbo.metrics.model.key.MetricsKeyWrapper;
import org.apache.dubbo.metrics.model.key.MetricsLevel;
import org.apache.dubbo.metrics.model.key.MetricsPlaceValue;
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.Test;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import static org.apache.dubbo.metrics.model.key.MetricsKey.METRIC_REQUESTS;
public class MetricsSupportTest {
@Test
void testFillZero() {
ApplicationModel applicationModel = FrameworkModel.defaultModel().newApplication();
ApplicationConfig config = new ApplicationConfig();
config.setName("MockMetrics");
applicationModel.getApplicationConfigManager().setApplication(config);
Map<MetricsKeyWrapper, Map<ServiceKeyMetric, AtomicLong>> data = new HashMap<>();
MetricsKeyWrapper key1 = new MetricsKeyWrapper(METRIC_REQUESTS, MetricsPlaceValue.of(CommonConstants.PROVIDER, MetricsLevel.METHOD));
MetricsKeyWrapper key2 = new MetricsKeyWrapper(METRIC_REQUESTS, MetricsPlaceValue.of(CommonConstants.CONSUMER, MetricsLevel.METHOD));
ServiceKeyMetric sm1 = new ServiceKeyMetric(applicationModel, "a.b.c");
ServiceKeyMetric sm2 = new ServiceKeyMetric(applicationModel, "a.b.d");
data.computeIfAbsent(key1, k -> new HashMap<>()).put(sm1, new AtomicLong(1));
data.computeIfAbsent(key1, k -> new HashMap<>()).put(sm2, new AtomicLong(1));
data.put(key2, new HashMap<>());
Assertions.assertEquals(2, data.values().stream().mapToLong(map -> map.values().size()).sum());
MetricsSupport.fillZero(data);
Assertions.assertEquals(4, data.values().stream().mapToLong(map -> map.values().size()).sum());
}
}

View File

@ -21,6 +21,7 @@ import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.metrics.model.key.MetricsKeyWrapper;
import org.apache.dubbo.metrics.model.key.MetricsLevel;
import org.apache.dubbo.metrics.model.key.MetricsPlaceValue;
import org.apache.dubbo.metrics.model.sample.MetricSample;
import java.util.Arrays;
import java.util.List;
@ -46,8 +47,9 @@ public interface DefaultConstants {
List<MetricsKeyWrapper> METHOD_LEVEL_KEYS = Arrays.asList(
new MetricsKeyWrapper(METRIC_REQUESTS, MetricsPlaceValue.of(CommonConstants.PROVIDER, MetricsLevel.METHOD)),
new MetricsKeyWrapper(METRIC_REQUESTS, MetricsPlaceValue.of(CommonConstants.CONSUMER, MetricsLevel.METHOD)),
new MetricsKeyWrapper(METRIC_REQUESTS_PROCESSING, MetricsPlaceValue.of(CommonConstants.PROVIDER, MetricsLevel.METHOD)),
new MetricsKeyWrapper(METRIC_REQUESTS_PROCESSING, MetricsPlaceValue.of(CommonConstants.CONSUMER, MetricsLevel.METHOD)),
// METRIC_REQUESTS_PROCESSING use GAUGE
new MetricsKeyWrapper(METRIC_REQUESTS_PROCESSING, MetricsPlaceValue.of(CommonConstants.PROVIDER, MetricsLevel.METHOD)).setSampleType(MetricSample.Type.GAUGE),
new MetricsKeyWrapper(METRIC_REQUESTS_PROCESSING, MetricsPlaceValue.of(CommonConstants.CONSUMER, MetricsLevel.METHOD)).setSampleType(MetricSample.Type.GAUGE),
new MetricsKeyWrapper(METRIC_REQUESTS_SUCCEED, MetricsPlaceValue.of(CommonConstants.PROVIDER, MetricsLevel.METHOD)),
new MetricsKeyWrapper(METRIC_REQUESTS_SUCCEED, MetricsPlaceValue.of(CommonConstants.CONSUMER, MetricsLevel.METHOD)),
new MetricsKeyWrapper(METRIC_REQUEST_BUSINESS_FAILED, MetricsPlaceValue.of(CommonConstants.PROVIDER, MetricsLevel.METHOD)),

View File

@ -29,12 +29,8 @@ import org.apache.dubbo.metrics.model.key.MetricsCat;
import org.apache.dubbo.metrics.model.key.MetricsKey;
import org.apache.dubbo.metrics.model.key.MetricsLevel;
import org.apache.dubbo.metrics.model.key.MetricsPlaceValue;
import org.apache.dubbo.metrics.model.sample.MetricSample;
import org.apache.dubbo.rpc.Invocation;
import static org.apache.dubbo.metrics.DefaultConstants.METRIC_THROWABLE;
import static org.apache.dubbo.metrics.MetricsConstants.INVOCATION;
import static org.apache.dubbo.metrics.MetricsConstants.INVOCATION_METRICS_COUNTER;
import static org.apache.dubbo.metrics.model.key.MetricsKey.METRIC_REQUESTS_SERVICE_UNAVAILABLE_FAILED;
@SuppressWarnings({"unchecked", "rawtypes"})
@ -71,17 +67,13 @@ public final class DefaultSubDispatcher extends SimpleMetricsEventMulticaster {
{
MetricsPlaceValue dynamicPlaceType = MetricsPlaceValue.of(event.getAttachmentValue(MetricsConstants.INVOCATION_SIDE), MetricsLevel.METHOD);
MetricsSupport.increment(key, dynamicPlaceType, (MethodMetricsCollector) collector, event);
// METRIC_REQUESTS_PROCESSING use GAUGE
Invocation invocation = event.getAttachmentValue(INVOCATION);
invocation.put(INVOCATION_METRICS_COUNTER, MetricSample.Type.GAUGE);
MetricsSupport.increment(MetricsKey.METRIC_REQUESTS_PROCESSING, dynamicPlaceType, (MethodMetricsCollector) collector, event);
})),
new MetricsCat(MetricsKey.METRIC_REQUESTS_SUCCEED, (key, placeType, collector) -> AbstractMetricsKeyListener.onFinish(key,
event ->
{
MetricsPlaceValue dynamicPlaceType = MetricsPlaceValue.of(event.getAttachmentValue(MetricsConstants.INVOCATION_SIDE), MetricsLevel.METHOD);
MetricsSupport.dec(MetricsKey.METRIC_REQUESTS_PROCESSING, dynamicPlaceType, (MethodMetricsCollector) collector, event);
MetricsSupport.dec(MetricsKey.METRIC_REQUESTS_PROCESSING, dynamicPlaceType, collector, event);
Object throwableObj = event.getAttachmentValue(METRIC_THROWABLE);
MetricsKey targetKey;
@ -99,7 +91,7 @@ public final class DefaultSubDispatcher extends SimpleMetricsEventMulticaster {
// Dynamic metricsKey && dynamicPlaceType
MetricsPlaceValue dynamicPlaceType = MetricsPlaceValue.of(event.getAttachmentValue(MetricsConstants.INVOCATION_SIDE), MetricsLevel.METHOD);
MetricsSupport.increment(MetricsKey.METRIC_REQUESTS_TOTAL_FAILED, dynamicPlaceType, (MethodMetricsCollector) collector, event);
MetricsSupport.dec(MetricsKey.METRIC_REQUESTS_PROCESSING, dynamicPlaceType, (MethodMetricsCollector) collector, event);
MetricsSupport.dec(MetricsKey.METRIC_REQUESTS_PROCESSING, dynamicPlaceType, collector, event);
MetricsSupport.incrAndAddRt(targetKey, dynamicPlaceType, (MethodMetricsCollector) collector, event);
}
)));

View File

@ -20,6 +20,7 @@ package org.apache.dubbo.metrics.collector;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.metrics.DefaultConstants;
import org.apache.dubbo.metrics.TestMetricsInvoker;
import org.apache.dubbo.metrics.event.MetricsDispatcher;
import org.apache.dubbo.metrics.event.RequestBeforeEvent;
@ -148,8 +149,8 @@ class DefaultCollectorTest {
// push finish rt +1
List<MetricSample> metricSamples = collector.collect();
//num(total+success+processing) + rt(5) = 8
Assertions.assertEquals(8, metricSamples.size());
//all METHOD_LEVEL_KEYS + rt(5) = 27
Assertions.assertEquals(DefaultConstants.METHOD_LEVEL_KEYS.size() + 5, metricSamples.size());
List<String> metricsNames = metricSamples.stream().map(MetricSample::getName).collect(Collectors.toList());
// No error will contain total+success+processing
String REQUESTS = new MetricsKeyWrapper(METRIC_REQUESTS, MetricsPlaceValue.of(side, MetricsLevel.SERVICE)).targetKey();
@ -191,7 +192,7 @@ class DefaultCollectorTest {
metricSamples = collector.collect();
// num(total+success+error+total_error+processing) + rt(5) = 5
Assertions.assertEquals(10, metricSamples.size());
Assertions.assertEquals(DefaultConstants.METHOD_LEVEL_KEYS.size() + 5, metricSamples.size());
String TIMEOUT = new MetricsKeyWrapper(METRIC_REQUESTS_TIMEOUT, MetricsPlaceValue.of(side, MetricsLevel.SERVICE)).targetKey();
String TOTAL_FAILED = new MetricsKeyWrapper(METRIC_REQUESTS_TOTAL_FAILED, MetricsPlaceValue.of(side, MetricsLevel.SERVICE)).targetKey();

View File

@ -25,6 +25,9 @@ import org.apache.dubbo.metrics.collector.DefaultMetricsCollector;
import org.apache.dubbo.metrics.event.MetricsEventBus;
import org.apache.dubbo.metrics.event.RequestEvent;
import org.apache.dubbo.metrics.model.key.MetricsKey;
import org.apache.dubbo.metrics.model.key.MetricsKeyWrapper;
import org.apache.dubbo.metrics.model.key.MetricsLevel;
import org.apache.dubbo.metrics.model.key.MetricsPlaceValue;
import org.apache.dubbo.metrics.model.sample.CounterMetricSample;
import org.apache.dubbo.metrics.model.sample.MetricSample;
import org.apache.dubbo.rpc.AppResponse;
@ -125,7 +128,7 @@ class MetricsFilterTest {
Map<String, MetricSample> metricsMap = getMetricsMap();
Assertions.assertTrue(metricsMap.containsKey(MetricsKey.METRIC_REQUESTS_FAILED.getNameByType(side)));
Assertions.assertFalse(metricsMap.containsKey(MetricsKey.METRIC_REQUESTS_SUCCEED.getNameByType(side)));
Assertions.assertTrue(metricsMap.containsKey(MetricsKey.METRIC_REQUESTS_SUCCEED.getNameByType(side)));
MetricSample sample = metricsMap.get(MetricsKey.METRIC_REQUESTS_FAILED.getNameByType(side));
Map<String, String> tags = sample.getTags();
@ -152,7 +155,7 @@ class MetricsFilterTest {
Map<String, MetricSample> metricsMap = getMetricsMap();
Assertions.assertTrue(metricsMap.containsKey(MetricsKey.METRIC_REQUEST_BUSINESS_FAILED.getNameByType(side)));
Assertions.assertFalse(metricsMap.containsKey(MetricsKey.METRIC_REQUESTS_SUCCEED.getNameByType(side)));
Assertions.assertTrue(metricsMap.containsKey(MetricsKey.METRIC_REQUESTS_SUCCEED.getNameByType(side)));
MetricSample sample = metricsMap.get(MetricsKey.METRIC_REQUEST_BUSINESS_FAILED.getNameByType(side));
@ -229,7 +232,7 @@ class MetricsFilterTest {
filter.onResponse(result, invoker, invocation);
Map<String, MetricSample> metricsMap = getMetricsMap();
Assertions.assertFalse(metricsMap.containsKey(MetricsKey.METRIC_REQUEST_BUSINESS_FAILED.getNameByType(side)));
Assertions.assertTrue(metricsMap.containsKey(MetricsKey.METRIC_REQUEST_BUSINESS_FAILED.getNameByType(side)));
Assertions.assertTrue(metricsMap.containsKey(MetricsKey.METRIC_REQUESTS_SUCCEED.getNameByType(side)));
MetricSample sample = metricsMap.get(MetricsKey.METRIC_REQUESTS_SUCCEED.getNameByType(side));
@ -266,12 +269,13 @@ class MetricsFilterTest {
@Test
public void testErrors() {
testFilterError(RpcException.SERIALIZATION_EXCEPTION, MetricsKey.METRIC_REQUESTS_CODEC_FAILED.formatName(side));
testFilterError(RpcException.NETWORK_EXCEPTION, MetricsKey.METRIC_REQUESTS_NETWORK_FAILED.formatName(side));
testFilterError(RpcException.SERIALIZATION_EXCEPTION, MetricsKey.METRIC_REQUESTS_CODEC_FAILED);
testFilterError(RpcException.NETWORK_EXCEPTION, MetricsKey.METRIC_REQUESTS_NETWORK_FAILED);
}
private void testFilterError(int errorCode, MetricsKey metricsKey) {
String targetKey = new MetricsKeyWrapper(metricsKey, MetricsPlaceValue.of(side, MetricsLevel.METHOD)).targetKey();
setup();
collector.setCollectEnabled(true);
given(invoker.invoke(invocation)).willThrow(new RpcException(errorCode));
@ -288,14 +292,14 @@ class MetricsFilterTest {
}
}
Map<String, MetricSample> metricsMap = getMetricsMap();
Assertions.assertTrue(metricsMap.containsKey(metricsKey.getName()));
Assertions.assertTrue(metricsMap.containsKey(targetKey));
MetricSample sample = metricsMap.get(metricsKey.getName());
MetricSample sample = metricsMap.get(targetKey);
Assertions.assertSame(((CounterMetricSample) sample).getValue().longValue(), count);
Assertions.assertSame(((CounterMetricSample<?>) sample).getValue().longValue(), count);
Assertions.assertTrue(metricsMap.containsKey(metricsKey.getName()));
Assertions.assertTrue(metricsMap.containsKey(targetKey));
Map<String, String> tags = sample.getTags();
Assertions.assertEquals(tags.get(TAG_INTERFACE_KEY), INTERFACE_NAME);

View File

@ -50,6 +50,9 @@ public final class MetadataSubDispatcher extends SimpleMetricsEventMulticaster {
}
/**
* A closer aggregation of MetricsCat, a summary collection of certain types of events
*/
interface CategorySet {
CategoryOverall APPLICATION_PUSH = new CategoryOverall(OP_TYPE_PUSH, MCat.APPLICATION_PUSH_POST, MCat.APPLICATION_PUSH_FINISH, MCat.APPLICATION_PUSH_ERROR);
CategoryOverall APPLICATION_SUBSCRIBE = new CategoryOverall(OP_TYPE_SUBSCRIBE, MCat.APPLICATION_SUBSCRIBE_POST, MCat.APPLICATION_SUBSCRIBE_FINISH, MCat.APPLICATION_SUBSCRIBE_ERROR);
@ -58,6 +61,10 @@ public final class MetadataSubDispatcher extends SimpleMetricsEventMulticaster {
List<CategoryOverall> ALL = Arrays.asList(APPLICATION_PUSH, APPLICATION_SUBSCRIBE, SERVICE_SUBSCRIBE);
}
/**
* {@link MetricsCat} MetricsCat collection, for better classification processing
* Except for a few custom functions, most of them can build standard event listening functions through the static methods of MetricsApplicationListener
*/
interface MCat {
// MetricsPushListener
MetricsCat APPLICATION_PUSH_POST = new MetricsCat(MetricsKey.METADATA_PUSH_METRIC_NUM, MetricsApplicationListener::onPostEventBuild);

View File

@ -211,7 +211,7 @@ class MetadataMetricsCollectorTest {
List<MetricSample> metricSamples = collector.collect();
// App(6) + service success(1)
Assertions.assertEquals(MetadataMetricsConstants.APP_LEVEL_KEYS.size() + 1, metricSamples.size());
Assertions.assertEquals(MetadataMetricsConstants.APP_LEVEL_KEYS.size() + MetadataMetricsConstants.SERVICE_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;
@ -221,7 +221,7 @@ class MetadataMetricsCollectorTest {
// push finish rt +1
List<MetricSample> metricSamples = collector.collect();
// App(6) + service total/success(2) + rt(5) = 7
Assertions.assertEquals(MetadataMetricsConstants.APP_LEVEL_KEYS.size() + 2 + 5, metricSamples.size());
Assertions.assertEquals(MetadataMetricsConstants.APP_LEVEL_KEYS.size() + MetadataMetricsConstants.SERVICE_LEVEL_KEYS.size() + 5, metricSamples.size());
long c1 = metadataEvent.getTimePair().calc();
metadataEvent = MetadataEvent.toServiceSubscribeEvent(applicationModel, serviceKey);

View File

@ -58,6 +58,9 @@ public final class RegistrySubDispatcher extends SimpleMetricsEventMulticaster {
});
}
/**
* A closer aggregation of MetricsCat, a summary collection of certain types of events
*/
interface CategorySet {
CategoryOverall APPLICATION_REGISTER = new CategoryOverall(OP_TYPE_REGISTER, MCat.APPLICATION_REGISTER_POST, MCat.APPLICATION_REGISTER_FINISH, MCat.APPLICATION_REGISTER_ERROR);
CategoryOverall APPLICATION_SUBSCRIBE = new CategoryOverall(OP_TYPE_SUBSCRIBE, MCat.APPLICATION_SUBSCRIBE_POST, MCat.APPLICATION_SUBSCRIBE_FINISH, MCat.APPLICATION_SUBSCRIBE_ERROR);
@ -70,6 +73,10 @@ public final class RegistrySubDispatcher extends SimpleMetricsEventMulticaster {
}
/**
* {@link MetricsCat} MetricsCat collection, for better classification processing
* Except for a few custom functions, most of them can build standard event listening functions through the static methods of MetricsApplicationListener
*/
interface MCat {
// MetricsRegisterListener
MetricsCat APPLICATION_REGISTER_POST = new MetricsCat(MetricsKey.REGISTER_METRIC_REQUESTS, MetricsApplicationListener::onPostEventBuild);

View File

@ -140,9 +140,9 @@ class RegistryMetricsCollectorTest {
List<MetricSample> metricSamples = collector.collect();
// push success +1
Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 1, metricSamples.size());
Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + RegistryMetricsConstants.SERVICE_LEVEL_KEYS.size(), 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());
Assertions.assertEquals(RegistryMetricsConstants.SERVICE_LEVEL_KEYS.size(), metricSamples.stream().filter(metricSample -> serviceName.equals(metricSample.getTags().get("interface"))).count());
return null;
}
);
@ -150,7 +150,7 @@ class RegistryMetricsCollectorTest {
// push finish rt +1
List<MetricSample> metricSamples = collector.collect();
// App(7) + rt(5) + service(total/success) = 14
Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 5 + 2, metricSamples.size());
Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 5 + RegistryMetricsConstants.SERVICE_LEVEL_KEYS.size(), metricSamples.size());
long c1 = registryEvent.getTimePair().calc();
registryEvent = RegistryEvent.toRsEvent(applicationModel, serviceName, 2);
@ -171,7 +171,7 @@ class RegistryMetricsCollectorTest {
metricSamples = collector.collect();
// App(7) + rt(5) + service(total/success/failed) = 15
Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 5 + 3, metricSamples.size());
Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 5 + RegistryMetricsConstants.SERVICE_LEVEL_KEYS.size(), metricSamples.size());
// calc rt
for (MetricSample sample : metricSamples) {
@ -201,10 +201,10 @@ class RegistryMetricsCollectorTest {
List<MetricSample> metricSamples = collector.collect();
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());
// App(default=7) + (service success +1)
Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + RegistryMetricsConstants.SERVICE_LEVEL_KEYS.size(), 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());
Assertions.assertEquals(RegistryMetricsConstants.SERVICE_LEVEL_KEYS.size(), metricSamples.stream().filter(metricSample -> serviceName.equals(metricSample.getTags().get("interface"))).count());
return null;
}
);
@ -212,7 +212,7 @@ class RegistryMetricsCollectorTest {
// push finish rt +1
List<MetricSample> metricSamples = collector.collect();
// App(7) + rt(5) + service(total/success) = 14
Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 5 + 2, metricSamples.size());
Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 5 + RegistryMetricsConstants.SERVICE_LEVEL_KEYS.size(), metricSamples.size());
long c1 = subscribeEvent.getTimePair().calc();
subscribeEvent = RegistryEvent.toSsEvent(applicationModel, serviceName);
@ -233,7 +233,7 @@ class RegistryMetricsCollectorTest {
metricSamples = collector.collect();
// App(7) + rt(5) + service(total/success/failed) = 15
Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 5 + 3, metricSamples.size());
Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 5 + RegistryMetricsConstants.SERVICE_LEVEL_KEYS.size(), metricSamples.size());
// calc rt
for (MetricSample sample : metricSamples) {
@ -254,6 +254,7 @@ class RegistryMetricsCollectorTest {
@Test
public void testNotify() {
Map<String, Integer> lastNumMap = new HashMap<>();
MetricsEventBus.post(RegistryEvent.toNotifyEvent(applicationModel),
() -> {
try {
@ -261,7 +262,6 @@ class RegistryMetricsCollectorTest {
} catch (InterruptedException e) {
e.printStackTrace();
}
Map<String, Integer> lastNumMap = new HashMap<>();
// 1 different services
lastNumMap.put("demo.service1", 3);
lastNumMap.put("demo.service2", 4);
@ -271,7 +271,7 @@ class RegistryMetricsCollectorTest {
);
List<MetricSample> metricSamples = collector.collect();
// App(7) + num(service*3) + rt(5) = 9
Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 3 + 5, metricSamples.size());
Assertions.assertEquals((RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 3 + 5)*3, metricSamples.size());
}
}

View File

@ -40,7 +40,7 @@
</modules>
<properties>
<spring-boot.version>2.7.11</spring-boot.version>
<spring-boot.version>2.7.12</spring-boot.version>
<dubbo.version>${revision}</dubbo.version>
<!-- Fix the bug of log4j refer:https://github.com/apache/logging-log4j2/pull/608 -->
<log4j2_version>2.20.0</log4j2_version>