Java Is io.prometheus.client.Gauge可用于螺纹安全计数器

Java Is io.prometheus.client.Gauge可用于螺纹安全计数器,java,spring-boot,prometheus,spring-boot-actuator,prometheus-java,Java,Spring Boot,Prometheus,Spring Boot Actuator,Prometheus Java,我正在使用io.prometheus.client.Gauge实现线程安全计数器,以计算在一个时间范围内处理的事件数。现在有几个线程正在处理这些事件。当计数器完成处理时,所有计数器都可以更新。我的问题是量规计数器本质上是线程安全的吗?下面是我的实现 private Map<String, Gauge> gaugeMap = new ConcurrentHashMap<>(); // This method will be called to re

我正在使用io.prometheus.client.Gauge实现线程安全计数器,以计算在一个时间范围内处理的事件数。现在有几个线程正在处理这些事件。当计数器完成处理时,所有计数器都可以更新。我的问题是量规计数器本质上是线程安全的吗?下面是我的实现

    private Map<String, Gauge> gaugeMap = new ConcurrentHashMap<>();
    
    // This method will be called to register the Gauge
    private void registerCounter(String metricName) {
        Gauge gauge = Gauge.build()
                .name(metricName)
                .help(metricName)
                .register(meterRegistry.getPrometheusRegistry());
        gaugeMap.put(metricName, gauge);
    }
    
    public void incrementCounter(String metricName) {
        if (isCounterPresent(metricName)) {
            gaugeMap.get(metricName).inc();
        }
    }
   public void incrementCounter(String metricName, long value) {
        if (isCounterPresent(metricName)) {
            gaugeMap.get(metricName).inc(value);
        }
    }
以下是我的客户代码

现在我的问题是,当多个线程递增同一计数器时,它会给我正确的值吗?

Prometheus JVM客户端声明:

量规上的默认inc、dec和set方法负责螺纹安全

Prometheus JVM客户端声明:

量规上的默认inc、dec和set方法负责螺纹安全


仪表是线程安全的,并使用CAS操作来支持非阻塞状态更新。所有的公制收集器都是。最后,它们必须由端点在单独的线程中公开。因此,读取和写入的状态应该是一致的。 需要记住的一点是,竞争越激烈,CAS操作的效率越低。因此,请确保不要将它公开给同时尝试更新它的数十个线程

其次,使用仪表作为计数器不是一个好主意,因为有一种特殊类型的计数器。一些普罗米修斯函数是专门实现和优化的,用于计数器-速率、irate等。
因此,如果您需要收集并公开多个线程处理的事件数,建议使用计数器。

仪表是线程安全的,并使用CAS操作来支持非阻塞状态更新。所有的公制收集器都是。最后,它们必须由端点在单独的线程中公开。因此,读取和写入的状态应该是一致的。 需要记住的一点是,竞争越激烈,CAS操作的效率越低。因此,请确保不要将它公开给同时尝试更新它的数十个线程

其次,使用仪表作为计数器不是一个好主意,因为有一种特殊类型的计数器。一些普罗米修斯函数是专门实现和优化的,用于计数器-速率、irate等。
因此,如果您需要收集并公开多个线程处理的事件数,建议使用计数器。

gaugeMap.putmetricName,gauge;是的,但情况并非如此,因为registerCounter是从@PostConstruct调用的,因此它将仅在应用程序启动时由strat-up线程调用。一旦应用程序启动,就根本没有注册调用。gaugeMap.putmetricName,gauge;是的,但情况并非如此,因为registerCounter是从@PostConstruct调用的,因此它将仅在应用程序启动时由strat-up线程调用。一旦应用程序启动,就根本没有注册呼叫。
// on application startup I am calling registerCounter for all metrics
@PostConstruct
private void registerMetrics(List<String> metricList) {
    // for each of metricList --> call registerCounter(String metricName)
}


Thread1
-------------------
// process N events
// call incrementCounter("metric-1", N);

Thread2
-------------------
// process N events
// call incrementCounter("metric-1", N);

Thread3
-------------------
// process N events
// call incrementCounter("metric-1", N);