如果数据不是每分钟轮询一次,SimpleMeterRegistry 会清除数据

SimpleMeterRegistry clears data if data not polled every minute

我有一个带有以下配置的简单 spring 启动应用程序(该项目在 GitHub 上可用 here):

management:
  metrics:
    export:
      simple:
        mode: step
  endpoints:
    web:
      exposure:
        include: "*"

以上配置创建 SimpleMeterRegistry 并将其指标配置为基于步骤的指标,每步 60 秒。我有一个脚本每秒向服务虚拟端点发送 50-100 个请求,还有另一个脚本每隔 X 秒从 /actuator/metrics/http.server.requests 轮询一次数据。当我 运行 后者 每 60 秒编写一次脚本时,一切都按预期工作 ,但是当脚本 运行 每 120 秒 ,对于 TOTAL_TIMECOUNT 指标,响应始终包含 zeros

谁能解释这种行为?

我已阅读文档 here。下图 可能表示只有在当前时间间隔内调用 pollAsRate 时,注册表才会尝试聚合前一个时间间隔的数据。这将解释为什么它在 120 秒间隔内不起作用。但这只是我的假设,有谁知道这里到底发生了什么?

Spring开机版本:2.1.7.RELEASE

更新

我用management.metrics.export.simple.step=10s做了一个类似的测试,当轮询间隔为10秒时它工作正常,当轮询间隔为20秒时不工作。对于 15 秒的间隔,它偶尔会起作用。所以,这肯定与步长和轮询频率有关。

MAX,TOTAL_TIME,COUNTStatistic的属性.

DistributionStatisticConfig.expiry(Duration.ofMinutes(2)) 如果 没有请求 则将某些测量设置为 0最后 2 分钟(120 秒)

public TimeWindowMax(Clock clock,...)private void rotate()之类的方法也是一样的。您可能会看到实现 here

More Detailed Answer

终于明白是怎么回事了。

/actuator/metrics 的每个请求,MetricsEndpoint 将合并度量(参见 here). That is done by collecting values for all meters with measurement.getValue(). The StepMeasurement.getValue() will not simply return the value, it will update the current and the previous intervals and counts, and roll the count (see here and here)。

StepMeasurement.getValue

public double getValue() {
  double absoluteCount = (Double)this.f.get();
  double inc = Math.max(0.0D, absoluteCount - this.lastCount.sum());
  this.lastCount.add(inc);
  this.value.getCurrent().add(inc);
  return this.value.poll();
}

StepDouble.poll

public double poll() {
    rollCount(clock.wallTime());
    return previous;
}

这与轮询间隔有何关系?如果您不轮询 /actuator/metrics 端点,则不会更新当前和之前的时间间隔,从而导致当前时间间隔不是最新的,并且会记录 "wrong" 时间间隔的指标。