【问题标题】:java measure method invocation ratejava测量方法调用率
【发布时间】:2018-07-04 19:47:23
【问题描述】:

我想计算和打印方法调用率,假设我有以下方法在每条消费消息(来自 Kafka)上调用:

public class Consumer {
  public void run() {
   while (true) {
     ConsumerRecords<String> recs = consumer.poll();
     for(ConsumerRecord record: recs) {
       parseMessageToDB(record.getValue());
     }
   }
 }

  public void parseMessageToDB(String message) {
    // message parsing logic..
  }
}

我的目标是计算每秒 #parseMessageToDB 方法调用次数,以了解我的应用程序可以使用来自 Kafka 的事件的速度。

我尝试使用 Guava 中的 RateLimiter,但它没有返回当前的调用率。

现在我得到了以下解决方案,我只需计算 15 秒内消耗的消息数,并在记录后将其重置为零。

这个计算不是很准确,因为我依赖计时器间隔,并且有可能从另一个 15 秒窗口获取(或重置)值,但这至少给了我一些图片:

public class Consumer {

    private final Timer timer = new Timer();
    private final AtomicLong parsedEvents = new AtomicLong();
    private static final int CONSUMER_TIMER_RATE_SEC = 15;

    public Consumer () {
      timer.schedule(new TimerTask() {
        @Override
        public void run() {
        logEventsParsingRate();
        }
      }, 0, CONSUMER_TIMER_RATE_SEC*1000);

    }

    public void run() {
       while (true) {
         ConsumerRecords<String> recs = consumer.poll();
         for(ConsumerRecord record: recs) {
            parseMessageToDB(record.getValue());
         }
        parsedEvents.addAndGet(recs.count());
       }
     }

   private void logEventsParsingRate() {
     logger.info("Consumer events consuming rate per sec: " + 
       handledEvents.getAndSet(0)/CONSUMER_TIMER_RATE_SEC);
   }

}

所以我仍在寻找其他更准确的解决方案。

【问题讨论】:

  • 是决定速度还是限制速度?因为您要求第一个,而您的代码示例更多地执行后者。从问题来看:请参阅 Marks 答案:Metrics 可能是您正在寻找的。​​span>

标签: java rate rate-limiting


【解决方案1】:

有一些计量库可以提供速率测量功能。

这里有两个:

Dropwizard metrics

Micrometer

两者的工作方式与某些下降相似 - 在内存中保存一个包含所有必需信息的对象。

通常,这些框架与指标持久性服务器(如 Prometheus、Influx DB、Graphite 等)以及一些允许轻松查看和分析值的 UI 工具(如 Grafana)结合使用。

但即使在“stadalone”模式下,他们也可以将收集到的信息报告给日志文件或 JMX,例如

例如,在 Dropwizard 中,有一个“Meter”原语可以这样使用:

// somewhere globally defined
private final MetricRegistry metrics = new MetricRegistry();
private final Meter requests = metrics.meter("requests");

// the method to be metered
public void run() {
    requests.mark();
    // do stuff
}

【讨论】:

    猜你喜欢
    • 2012-03-15
    • 1970-01-01
    • 1970-01-01
    • 2013-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多