更新千分尺是否会阻塞调用线程?
Will updating a micrometer gauge ever block the calling thread?
更新千分尺是否会阻塞调用线程(例如执行 I/O)?
我相信答案是“不,I/O 发生在一个单独的指标收集线程中”,但想知道这方面的例外情况,边缘情况,..
谢谢
塔里克
这取决于你所说的调用线程是什么意思。
如果你指的是注册仪表的用户线程,答案是否定的,此时你提供给仪表的方法甚至都没有被调用。
如果您指的是将“传送”指标的线程,那将被阻止。这通常是一个单独的线程(因为大多数注册表都是基于推送的)但是在 Prometheus(基于拉)的情况下,仪表将阻塞 Prometheus 端点和为其服务的线程。
出于这个原因,在 Micrometer 中,您可以拥有一个中间“状态”对象,您可以从单独的线程(阻塞)定期更新并从仪表(非-阻塞),例如:
AtomicInteger currentValue = registry.gauge("test.gauge", new AtomicInteger(0));
并且您可以从另一个线程修改 currentValue
,请参阅 docs
您可以对任意对象执行此操作,例如:
State state = registry.gauge("test.gauge", Collections.emptyList(), new State(), State::getValue);
其中 getValue
不阻塞只是给你最新的值,而在另一个线程上你可以更新封装在 State
对象中的值。
以下几行显示您注册到仪表中的方法正在阻塞:
public class GaugeSample {
public static void main(String[] args) throws InterruptedException {
PrometheusMeterRegistry registry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
System.out.println("registering the gauge...");
Gauge.builder("test.gauge", GaugeSample::getValue)
.register(registry);
System.out.println("scraping...");
System.out.println(registry.scrape());
}
private static double getValue() {
try {
Thread.sleep(5_000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
return 42;
}
}
更新千分尺是否会阻塞调用线程(例如执行 I/O)?
我相信答案是“不,I/O 发生在一个单独的指标收集线程中”,但想知道这方面的例外情况,边缘情况,..
谢谢 塔里克
这取决于你所说的调用线程是什么意思。 如果你指的是注册仪表的用户线程,答案是否定的,此时你提供给仪表的方法甚至都没有被调用。
如果您指的是将“传送”指标的线程,那将被阻止。这通常是一个单独的线程(因为大多数注册表都是基于推送的)但是在 Prometheus(基于拉)的情况下,仪表将阻塞 Prometheus 端点和为其服务的线程。
出于这个原因,在 Micrometer 中,您可以拥有一个中间“状态”对象,您可以从单独的线程(阻塞)定期更新并从仪表(非-阻塞),例如:
AtomicInteger currentValue = registry.gauge("test.gauge", new AtomicInteger(0));
并且您可以从另一个线程修改 currentValue
,请参阅 docs
您可以对任意对象执行此操作,例如:
State state = registry.gauge("test.gauge", Collections.emptyList(), new State(), State::getValue);
其中 getValue
不阻塞只是给你最新的值,而在另一个线程上你可以更新封装在 State
对象中的值。
以下几行显示您注册到仪表中的方法正在阻塞:
public class GaugeSample {
public static void main(String[] args) throws InterruptedException {
PrometheusMeterRegistry registry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
System.out.println("registering the gauge...");
Gauge.builder("test.gauge", GaugeSample::getValue)
.register(registry);
System.out.println("scraping...");
System.out.println(registry.scrape());
}
private static double getValue() {
try {
Thread.sleep(5_000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
return 42;
}
}