This is an automated email from the ASF dual-hosted git repository.
albumenj pushed a commit to branch 3.2
in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/3.2 by this push:
new 5d070383a1 Metrics RT count optimization (#11628)
5d070383a1 is described below
commit 5d070383a1452d0b637d00e1082b22f54712f0bb
Author: Mengyang Tang <[email protected]>
AuthorDate: Sat Feb 25 17:25:04 2023 +0800
Metrics RT count optimization (#11628)
* Metrics RT count optimization
* Fix camel case naming problem
---
.../collector/sample/MethodMetricsSampler.java | 23 +----
.../collector/sample/MetricsCountSampler.java | 21 ++---
.../sample/SimpleMetricsCountSampler.java | 105 +++++++++++----------
.../collector/sample/ThreadPoolMetricsSampler.java | 9 +-
.../metrics/filter/MethodMetricsInterceptor.java | 2 +-
5 files changed, 69 insertions(+), 91 deletions(-)
diff --git
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MethodMetricsSampler.java
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MethodMetricsSampler.java
index 82f0693821..75bc637ab0 100644
---
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MethodMetricsSampler.java
+++
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MethodMetricsSampler.java
@@ -31,7 +31,6 @@ import org.apache.dubbo.rpc.Invocation;
import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Supplier;
import static org.apache.dubbo.metrics.model.MetricsCategory.REQUESTS;
@@ -39,7 +38,7 @@ import static
org.apache.dubbo.metrics.model.MetricsCategory.RT;
public class MethodMetricsSampler extends
SimpleMetricsCountSampler<Invocation, MetricsEvent.Type, MethodMetric> {
- private DefaultMetricsCollector collector;
+ private final DefaultMetricsCollector collector;
public MethodMetricsSampler(DefaultMetricsCollector collector) {
this.collector = collector;
@@ -64,7 +63,7 @@ public class MethodMetricsSampler extends
SimpleMetricsCountSampler<Invocation,
List<MetricSample> metricSamples = new ArrayList<>();
collect(metricSamples);
- collectRT(metricSamples);
+ metricSamples.addAll(collectRT((key, metric, count) ->
getGaugeMetricSample(key, metric, RT, () -> count)));
return metricSamples;
}
@@ -80,24 +79,6 @@ public class MethodMetricsSampler extends
SimpleMetricsCountSampler<Invocation,
count(list, MetricsEvent.Type.TOTAL_FAILED,
MetricsKey.METRIC_REQUESTS_TOTAL_FAILED);
}
- private void collectRT(List<MetricSample> list) {
- this.getLastRT().forEach((k, v) ->
- list.add(getGaugeMetricSample(MetricsKey.METRIC_RT_LAST, k, RT,
v::get)
- ));
- this.getMinRT().forEach((k, v) ->
- list.add(getGaugeMetricSample(MetricsKey.METRIC_RT_MIN, k, RT,
v::get)));
- this.getMaxRT().forEach((k, v) ->
- list.add(getGaugeMetricSample(MetricsKey.METRIC_RT_MAX, k, RT,
v::get)));
-
- this.getTotalRT().forEach((k, v) -> {
- list.add(getGaugeMetricSample(MetricsKey.METRIC_RT_SUM, k, RT,
v::get));
- AtomicLong avg = this.getAvgRT().get(k);
- AtomicLong count = this.getRtCount().get(k);
- avg.set(v.get() / count.get());
- list.add(getGaugeMetricSample(MetricsKey.METRIC_RT_AVG, k, RT,
avg::get));
- });
- }
-
private GaugeMetricSample getGaugeMetricSample(MetricsKey metricsKey,
MethodMetric methodMetric,
MetricsCategory
metricsCategory, Supplier<Number> get) {
return new
GaugeMetricSample(metricsKey.getNameByType(methodMetric.getSide()),
metricsKey.getDescription(),
diff --git
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsCountSampler.java
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsCountSampler.java
index 1d16155c10..06512199aa 100644
---
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsCountSampler.java
+++
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsCountSampler.java
@@ -18,13 +18,15 @@
package org.apache.dubbo.metrics.collector.sample;
import org.apache.dubbo.metrics.model.Metric;
+import org.apache.dubbo.metrics.model.MetricsKey;
+import org.apache.dubbo.metrics.model.sample.MetricSample;
+import java.util.List;
import java.util.Optional;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.atomic.LongAccumulator;
-public interface MetricsCountSampler<S, K,M extends Metric> extends
MetricsSampler {
+public interface MetricsCountSampler<S, K, M extends Metric> extends
MetricsSampler {
void inc(S source, K metricName);
@@ -38,16 +40,9 @@ public interface MetricsCountSampler<S, K,M extends Metric>
extends MetricsSampl
Optional<ConcurrentMap<M, AtomicLong>> getCount(K metricName);
- ConcurrentMap<M, AtomicLong> getLastRT();
-
- ConcurrentMap<M, LongAccumulator> getMinRT();
-
- ConcurrentMap<M, LongAccumulator> getMaxRT();
-
- ConcurrentMap<M, AtomicLong> getAvgRT();
-
- ConcurrentMap<M, AtomicLong> getTotalRT();
-
- ConcurrentMap<M, AtomicLong> getRtCount();
+ <R extends MetricSample> List<R> collectRT(MetricSampleFactory<M, R>
factory);
+ interface MetricSampleFactory<M, R extends MetricSample> {
+ R newInstance(MetricsKey key, M metric, Long count);
+ }
}
diff --git
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/SimpleMetricsCountSampler.java
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/SimpleMetricsCountSampler.java
index 1160e5ca76..898e0d9dd8 100644
---
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/SimpleMetricsCountSampler.java
+++
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/SimpleMetricsCountSampler.java
@@ -20,12 +20,17 @@ package org.apache.dubbo.metrics.collector.sample;
import org.apache.dubbo.common.utils.Assert;
import org.apache.dubbo.common.utils.ConcurrentHashMapUtils;
import org.apache.dubbo.metrics.model.Metric;
+import org.apache.dubbo.metrics.model.MetricsKey;
+import org.apache.dubbo.metrics.model.sample.MetricSample;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicLongArray;
import java.util.concurrent.atomic.LongAccumulator;
import java.util.function.Function;
@@ -38,18 +43,19 @@ import java.util.function.Function;
public abstract class SimpleMetricsCountSampler<S, K, M extends Metric>
implements MetricsCountSampler<S, K, M> {
- private final ConcurrentMap<M, AtomicLong> lastRT = new
ConcurrentHashMap<>();
- private final ConcurrentMap<M, LongAccumulator> minRT = new
ConcurrentHashMap<>();
- private final ConcurrentMap<M, LongAccumulator> maxRT = new
ConcurrentHashMap<>();
- private final ConcurrentMap<M, AtomicLong> avgRT = new
ConcurrentHashMap<>();
- private final ConcurrentMap<M, AtomicLong> totalRT = new
ConcurrentHashMap<>();
- private final ConcurrentMap<M, AtomicLong> rtCount = new
ConcurrentHashMap<>();
+ private final ConcurrentMap<M, AtomicLong> EMPTY_COUNT = new
ConcurrentHashMap<>();
- private Map<K, ConcurrentMap<M, AtomicLong>> metricCounter = new
ConcurrentHashMap<>();
+ private final ConcurrentMap<M, LongAccumulator> minRT = new
ConcurrentHashMap<>();
+ private final ConcurrentMap<M, LongAccumulator> maxRT = new
ConcurrentHashMap<>();
+
+ // lastRT, totalRT, rtCount, avgRT share a container, can utilize the
system cache line
+ private final ConcurrentMap<M, AtomicLongArray> rtArray = new
ConcurrentHashMap<>();
+
+ private final Map<K, ConcurrentMap<M, AtomicLong>> metricCounter = new
ConcurrentHashMap<>();
@Override
public void inc(S source, K metricName) {
- doExecute(source,metricName,counter->{
+ doExecute(source, metricName, counter -> {
counter.incrementAndGet();
return false;
});
@@ -57,7 +63,7 @@ public abstract class SimpleMetricsCountSampler<S, K, M
extends Metric>
@Override
public void dec(S source, K metricName) {
- doExecute(source,metricName,counter->{
+ doExecute(source, metricName, counter -> {
counter.decrementAndGet();
return false;
});
@@ -65,7 +71,7 @@ public abstract class SimpleMetricsCountSampler<S, K, M
extends Metric>
@Override
public void incOnEvent(S source, K metricName) {
- doExecute(source,metricName,counter->{
+ doExecute(source, metricName, counter -> {
counter.incrementAndGet();
return true;
});
@@ -73,7 +79,7 @@ public abstract class SimpleMetricsCountSampler<S, K, M
extends Metric>
@Override
public void decOnEvent(S source, K metricName) {
- doExecute(source,metricName,counter->{
+ doExecute(source, metricName, counter -> {
counter.decrementAndGet();
return true;
});
@@ -81,15 +87,26 @@ public abstract class SimpleMetricsCountSampler<S, K, M
extends Metric>
@Override
public void addRT(S source, Long rt) {
- MetricsCountSampleConfigurer<S,K,M> sampleConfigure = new
MetricsCountSampleConfigurer<>();
+ MetricsCountSampleConfigurer<S, K, M> sampleConfigure = new
MetricsCountSampleConfigurer<>();
sampleConfigure.setSource(source);
this.rtConfigure(sampleConfigure);
M metric = sampleConfigure.getMetric();
- AtomicLong last = ConcurrentHashMapUtils.computeIfAbsent(lastRT,
metric, k -> new AtomicLong());
- last.set(rt);
+ AtomicLongArray rtArray =
ConcurrentHashMapUtils.computeIfAbsent(this.rtArray, metric, k -> new
AtomicLongArray(4));
+
+ // set lastRT
+ rtArray.set(0, rt);
+
+ // add to totalRT
+ rtArray.addAndGet(1, rt);
+
+ // add to rtCount
+ rtArray.incrementAndGet(2);
+
+ // calc avgRT. In order to reduce the amount of calculation,
calculated when collect
+ //rtArray.set(3, Math.floorDiv(rtArray.get(1), rtArray.get(2)));
LongAccumulator min = ConcurrentHashMapUtils.computeIfAbsent(minRT,
metric, k -> new LongAccumulator(Long::min, Long.MAX_VALUE));
min.accumulate(rt);
@@ -97,65 +114,49 @@ public abstract class SimpleMetricsCountSampler<S, K, M
extends Metric>
LongAccumulator max = ConcurrentHashMapUtils.computeIfAbsent(maxRT,
metric, k -> new LongAccumulator(Long::max, Long.MIN_VALUE));
max.accumulate(rt);
- AtomicLong total = ConcurrentHashMapUtils.computeIfAbsent(totalRT,
metric, k -> new AtomicLong());
- total.addAndGet(rt);
-
- AtomicLong count = ConcurrentHashMapUtils.computeIfAbsent(rtCount,
metric, k -> new AtomicLong());
- count.incrementAndGet();
-
- ConcurrentHashMapUtils.computeIfAbsent(avgRT, metric, key -> new
AtomicLong());
-
sampleConfigure.setRt(rt);
sampleConfigure.getFireEventHandler().accept(sampleConfigure);
-
}
@Override
public Optional<ConcurrentMap<M, AtomicLong>> getCount(K metricName) {
return Optional.ofNullable(metricCounter.get(metricName) == null ?
- new ConcurrentHashMap<>() :
+ EMPTY_COUNT :
metricCounter.get(metricName));
}
@Override
- public ConcurrentMap<M, AtomicLong> getLastRT() {
- return this.lastRT;
- }
-
- @Override
- public ConcurrentMap<M, LongAccumulator> getMinRT() {
- return this.minRT;
- }
+ public <R extends MetricSample> List<R> collectRT(MetricSampleFactory<M,
R> factory) {
+ final List<R> rtMetricSamples = new ArrayList<>();
+ rtArray.forEach((k, v) -> {
+ // lastRT
+ rtMetricSamples.add(factory.newInstance(MetricsKey.METRIC_RT_LAST,
k, v.get(0)));
+ // totalRT
+ long totalRT = v.get(1);
+ long rtCount = v.get(2);
+ rtMetricSamples.add(factory.newInstance(MetricsKey.METRIC_RT_SUM,
k, totalRT));
+ // avgRT
+ rtMetricSamples.add(factory.newInstance(MetricsKey.METRIC_RT_AVG,
k, Math.floorDiv(totalRT, rtCount)));
+ });
- @Override
- public ConcurrentMap<M, LongAccumulator> getMaxRT() {
- return this.maxRT;
- }
+ this.minRT.forEach((k, v) ->
+ rtMetricSamples.add(factory.newInstance(MetricsKey.METRIC_RT_MIN,
k, v.get())));
- @Override
- public ConcurrentMap<M, AtomicLong> getAvgRT() {
- return this.avgRT;
- }
+ this.maxRT.forEach((k, v) ->
+ rtMetricSamples.add(factory.newInstance(MetricsKey.METRIC_RT_MAX,
k, v.get())));
- @Override
- public ConcurrentMap<M, AtomicLong> getTotalRT() {
- return this.totalRT;
- }
-
- @Override
- public ConcurrentMap<M, AtomicLong> getRtCount() {
- return this.rtCount;
+ return rtMetricSamples;
}
- protected void rtConfigure(MetricsCountSampleConfigurer<S,K,M> configure) {
+ protected void rtConfigure(MetricsCountSampleConfigurer<S, K, M>
configure) {
}
- protected abstract void countConfigure(MetricsCountSampleConfigurer<S,K,M>
sampleConfigure);
+ protected abstract void countConfigure(MetricsCountSampleConfigurer<S, K,
M> sampleConfigure);
- private void doExecute(S source,K metricsName,Function<AtomicLong,Boolean>
counter){
- MetricsCountSampleConfigurer<S,K,M> sampleConfigure = new
MetricsCountSampleConfigurer<>();
+ private void doExecute(S source, K metricsName, Function<AtomicLong,
Boolean> counter) {
+ MetricsCountSampleConfigurer<S, K, M> sampleConfigure = new
MetricsCountSampleConfigurer<>();
sampleConfigure.setSource(source);
sampleConfigure.setMetricsName(metricsName);
diff --git
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java
index 67cb73d3fe..17ad4bb5e3 100644
---
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java
+++
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java
@@ -35,9 +35,9 @@ import static
org.apache.dubbo.metrics.model.MetricsCategory.THREAD_POOL;
public class ThreadPoolMetricsSampler implements MetricsSampler {
- private DefaultMetricsCollector collector;
+ private final DefaultMetricsCollector collector;
private FrameworkExecutorRepository frameworkExecutorRepository;
- private Set<ThreadPoolMetric> threadPoolMetricSet = new HashSet<>();
+ private final Set<ThreadPoolMetric> threadPoolMetricSet = new HashSet<>();
public ThreadPoolMetricsSampler(DefaultMetricsCollector collector) {
this.collector = collector;
@@ -58,11 +58,12 @@ public class ThreadPoolMetricsSampler implements
MetricsSampler {
}
private void collect() {
- try{
+ try {
if (this.frameworkExecutorRepository == null) {
this.frameworkExecutorRepository =
collector.getApplicationModel().getFrameworkModel().getBeanFactory().getBean(FrameworkExecutorRepository.class);
}
- }catch(Exception ex){}
+ } catch (Exception ignored) {
+ }
if (frameworkExecutorRepository != null) {
addThread("SharedExecutor",
frameworkExecutorRepository.getSharedExecutor());
diff --git
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MethodMetricsInterceptor.java
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MethodMetricsInterceptor.java
index d327dcb789..9dd6113909 100644
---
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MethodMetricsInterceptor.java
+++
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MethodMetricsInterceptor.java
@@ -29,7 +29,7 @@ import static
org.apache.dubbo.common.constants.MetricsConstants.METRIC_FILTER_S
public class MethodMetricsInterceptor {
- private MethodMetricsSampler sampler;
+ private final MethodMetricsSampler sampler;
public MethodMetricsInterceptor(MethodMetricsSampler sampler) {
this.sampler = sampler;