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;

Reply via email to