代码之家  ›  专栏  ›  技术社区  ›  MeetJoeBlack

Java度量方法调用率

  •  0
  • MeetJoeBlack  · 技术社区  · 6 年前

    我想计算并打印方法调用率,假设我有以下方法,对每个使用的消息(来自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的事件的速度。

    我试着用 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);
       }
    
    }
    

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

    1 回复  |  直到 6 年前
        1
  •  2
  •   Mark Bramnik    6 年前

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

    这里有两个:

    Dropwizard metrics

    Micrometer

    两者的工作方式都类似于某种下降——将一个拥有所有必需信息的对象保存在内存中。

    通常,这些框架与度量持久性服务器(如prometheus、infloxdb、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
    }