3

我正在尝试为应监视自定义 ThreadPoolTask​​Executor 的千分尺构建自定义仪表。问题是仪表值保持不变并且自应用程序启动以来从未更新。但是执行器统计信息(可以在调试器中看到)显示变化的值。

这是我的仪表配置课程。

@Component
public class ThreadPoolMetricProbe implements MeterBinder {

@Inject
private Executor taskExecutor;

@Override
public void bindTo(MeterRegistry meterRegistry) {
    ThreadPoolTaskExecutor exec = (ThreadPoolTaskExecutor) taskExecutor;

    long completedTaskCount = exec.getThreadPoolExecutor().getCompletedTaskCount();
    int largestPoolSize = exec.getThreadPoolExecutor().getLargestPoolSize();
    int maximumPoolSize = exec.getThreadPoolExecutor().getMaximumPoolSize();
    int poolSize = exec.getThreadPoolExecutor().getPoolSize();
    long taskCount = exec.getThreadPoolExecutor().getTaskCount();
    int activeCount = exec.getThreadPoolExecutor().getActiveCount();

    String threadNamePrefix = exec.getThreadNamePrefix();

    Gauge.builder("executorCompletedTaskCount", completedTaskCount, Double::new)
            .description(String.format("Returns the approximate total number of tasks that have completed execution of %s executor", threadNamePrefix.toLowerCase()))
            .register(meterRegistry);

    Gauge.builder("executorLargestThreadsNumber", largestPoolSize, Double::new)
            .description(String.format(" Returns the largest number of threads that have ever simultaneously been in the pool of %s executor", threadNamePrefix.toLowerCase()))
            .register(meterRegistry);

    Gauge.builder("executorMaximumAllowedThreadsNumber", maximumPoolSize, Double::new)
            .description(String.format("Returns the maximum allowed number of threads of %s executor", threadNamePrefix.toLowerCase()))
            .register(meterRegistry);

    Gauge.builder("executorCurrentNumberOfThreads", poolSize, Double::new)
            .description(String.format("Returns the current number of threads in the %s executor pool", threadNamePrefix.toLowerCase()))
            .register(meterRegistry);

    Gauge.builder("executorTotalTaskCount", taskCount, Double::new)
            .description(String.format(" Returns the approximate total number of tasks that have ever been scheduled for execution by %s executor", threadNamePrefix.toLowerCase()))
            .register(meterRegistry);

    Gauge.builder("executorActiveThreadsCount", activeCount, Double::new)
            .description(String.format("Returns the approximate number of threads that are actively executing tasks by %s executor", threadNamePrefix.toLowerCase()))
            .register(meterRegistry);


    Metrics.addRegistry(meterRegistry);

}

@Scheduled(fixedDelay = 5000)
public void measure(){
    Metrics.gauge("executorCompletedTaskCount",((ThreadPoolTaskExecutor) taskExecutor).getThreadPoolExecutor().getCompletedTaskCount());
    Metrics.gauge("executorTotalTaskCount",((ThreadPoolTaskExecutor) taskExecutor).getThreadPoolExecutor().getTaskCount());
    Metrics.gauge("executorCurrentNumberOfThreads",((ThreadPoolTaskExecutor) taskExecutor).getThreadPoolExecutor().getPoolSize());
   }
}

我在这里注册了几个仪表,并期望它们在每个请求中更新一次,或者......方法度量是最后一次尝试找到正确的方法来监控和更新值。

所以问题是:

  1. 仪表会自动更新吗?如果是 - 多久一次?
  2. 如果仪表没有自动更新 - 那么如何正确更新它们?
  3. 量规是否适合此类测量?AFAIK 我不能使用计数器,因为某些值可以递减。
  4. 创建所有仪表后,我是否需要执行 Metrics.addRegistry(meterRegistry) ?
4

2 回答 2

2

问题是该Gauge.builder()方法返回仪表本身,而 MeterRegistry meterRegistry传递给 @Override public void bindTo(MeterRegistry meterRegistry)has 方法meterRegistry.gauge() 的对象可以返回对对象值的引用:

AtomicDouble executorCompletedTaskCount = meterRegistry.gauge("executor.completed.task.count", new AtomicDouble(completedTaskCount));

然后可以在预定的方法中进行修改。

完整的代码如下所示:

@Component
public class ThreadPoolMetricProbe implements MeterBinder {

@Inject
private Executor taskExecutor;

private AtomicDouble executorCompletedTaskCount;
private AtomicDouble executorMaximumPoolSize;
private AtomicDouble executorLargestThreadsNumberEver;
private AtomicDouble executorCurrentNumberOfThreads;
private AtomicDouble executorTotalTaskCount;
private AtomicDouble executorActiveThreadsCount;

@Override
public void bindTo(MeterRegistry meterRegistry) {
    ThreadPoolTaskExecutor exec = (ThreadPoolTaskExecutor) taskExecutor;
    long completedTaskCount = exec.getThreadPoolExecutor().getCompletedTaskCount();
    int largestPoolSizeEver = exec.getThreadPoolExecutor().getLargestPoolSize();
    int maximumPoolSize = exec.getThreadPoolExecutor().getMaximumPoolSize();
    int currentNumberOfThreads = exec.getThreadPoolExecutor().getPoolSize();
    long totalTaskCountEver = exec.getThreadPoolExecutor().getTaskCount();
    int activeThreadsCount = exec.getThreadPoolExecutor().getActiveCount();

    executorCompletedTaskCount = meterRegistry.gauge("executor.completed.task.count", new AtomicDouble(completedTaskCount));
    executorMaximumPoolSize = meterRegistry.gauge("executor.maximum.pool.size", new AtomicDouble(maximumPoolSize));
    executorLargestThreadsNumberEver = meterRegistry.gauge("executor.largest.threads.number.ever", new AtomicDouble(largestPoolSizeEver));
    executorCurrentNumberOfThreads = meterRegistry.gauge("executor.current.number.of.threads", new AtomicDouble(currentNumberOfThreads));
    executorTotalTaskCount = meterRegistry.gauge("executor.total.tasks.ever.countunt", new AtomicDouble(totalTaskCountEver));
    executorActiveThreadsCount = meterRegistry.gauge("executor.active.threads.count", new AtomicDouble(activeThreadsCount));

}

@Scheduled(fixedDelay = 5000)
public void measure(){
    ThreadPoolExecutor threadPoolExecutor = ((ThreadPoolTaskExecutor) taskExecutor).getThreadPoolExecutor();
    executorCompletedTaskCount.set(threadPoolExecutor.getCompletedTaskCount());
    executorMaximumPoolSize.set(threadPoolExecutor.getMaximumPoolSize());
    executorLargestThreadsNumberEver.set(threadPoolExecutor.getLargestPoolSize());
    executorCurrentNumberOfThreads.set(threadPoolExecutor.getPoolSize());
    executorTotalTaskCount.set(threadPoolExecutor.getTaskCount());
    executorActiveThreadsCount.set(threadPoolExecutor.getActiveCount());
}

希望这是更新仪表值的正确方法。

于 2019-11-20T09:51:29.607 回答
0

尝试使用.strongReference(true).

例子:

Gauge.builder("executorTotalTaskCount", taskCount, Double::new)
    .strongReference(true)
    .description(String.format(" Returns the approximate total number of tasks that have ever been scheduled for execution by %s executor", threadNamePrefix.toLowerCase()))
    .register(meterRegistry);
于 2020-05-02T11:50:22.647 回答