【发布时间】:2020-09-21 06:52:57
【问题描述】:
我正在使用io.prometheus.client.Gauge 来实现一个线程安全计数器来计算一个时间范围内处理的事件数。现在有几个线程正在处理这些事件。并且所有人都可以在完成处理后更新计数器。我的问题是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);
}
}
以下是我的客户端代码。
// 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);
现在我的问题是多个线程都在增加同一个计数器,那么它会给我正确的值吗?
【问题讨论】:
-
gaugeMap.put(metricName, gauge);computeIfAbsent,否则多个线程可能会在Map中放入相同的键 -
是的,但情况并非如此,因为
registerCounter是从@PostConstruct调用的,所以它只会在应用程序启动时被strat up 线程调用。一旦应用程序启动,就根本没有注册电话。
标签: java spring-boot prometheus spring-boot-actuator prometheus-java