Java-Metrics指标度量工具

本文介绍了一个用于Java服务监控的强大工具Metrics。通过实例演示了如何利用Metrics监控服务的多个关键指标,包括Gauges、Counters、Meters、Histograms和Timers等。此外,还介绍了如何将Metrics与其他监控工具如Ganglia、Graphite集成。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

微服务架构时代,服务运行状况通过服务埋点设计越来越多。熔断器,服务网格,API网关 怎么洞悉他们运行状态,仅通过传统外部Agent采集,实现复杂,双方对接开发成本高,可能远远满足不了要求,java-metrics可以有效满足这些场景.

介绍

Metrics是一个给JAVA服务的各项指标提供度量工具的包,在JAVA代码中嵌入Metrics代码,可以方便的对业务代码的各个指标进行监控,同时,Metrics能够很好的跟Ganglia、Graphite,influxdb 优秀监控工具整合使用,方便的提供图形化接口。基本使用方式直接将core包(目前稳定版本3.0.1)导入pom文件即可,配置如下:

<dependency>
  <groupId>com.codahale.metrics</groupId>
  <artifactId>metrics-core</artifactId>
  <version>3.0.1</version>
</dependency>

基本功能

core包主要提供如下核心功能:

  • Metrics Registries类似一个metrics容器,维护一个Map,可以是一个服务 或者一个静态实例。
  • 支持五种metric类型:Gauges、Counters、Meters、Histograms和Timers。
  • 支持多种指标数据输出:JMX、Console,CSV文件和SLF4J loggers 等输出方式;
  • 支持自定义扩展输出,同时也可以和Ganglia,Graphite 结合使用

Metrics类型(5种):

1. Gauges

Gauges是一个最简单的计量,一般用来统计瞬时状态的数据信息

GaugesExample.java

package example;

import java.util.Queue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;

import com.codahale.metrics.ConsoleReporter;
import com.codahale.metrics.Gauge;
import com.codahale.metrics.MetricRegistry;

/**
 * User: guoenzhou
 * 测试Gauges,实时统计pending状态的job个数
 */
public class GaugesExample {
    /**
     * 实例化一个registry,最核心的一个模块,相当于一个应用程序的metrics系统的容器,维护一个Map
     */
    private static final MetricRegistry metrics = new MetricRegistry();

    private static Queue<String> queue = new LinkedBlockingDeque<String>();

    /**
     * ConsoleReporter 在控制台上打印输出  
     */
    private static ConsoleReporter reporter = ConsoleReporter.forRegistry(metrics).build();
    

    public static void main(String[] args) throws InterruptedException {
    	reporter.start(10, TimeUnit.SECONDS);

        //实例化一个Gauge
        Gauge<Integer> gauge = new Gauge<Integer>() {
            public Integer getValue() {
                return queue.size();
            }
        };

        //注册到容器中
        metrics.register(MetricRegistry.name(GaugesExample.class, "pending.job", "size"), gauge);

   
        //模拟数据
        for (int i=0; i<1000; i++){
            queue.add("a");
            Thread.sleep(1000);
        }

    }
    
    
}

通过以上步骤将会向MetricsRegistry容器中注册一个指标名字为 example.GaugesExample.pending.job.size 的metrics,实时获取队列长度的指标。

输出:

-- Gauges ----------------------------------------------------------------------
example.TestGauges.pending-job.size
             value = 340


18-1-2 15:03:17 ================================================================

-- Gauges ----------------------------------------------------------------------
example.TestGauges.pending-job.size
             value = 350


18-1-2 15:03:27 ================================================================

-- Gauges ----------------------------------------------------------------------
example.TestGauges.pending-job.size
             value = 360

2. Counter

Counter是Gauge的一个特例,维护一个计数器,可以通过inc()和dec()方法对计数器做修改。

package example;

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.TimeUnit;

import com.codahale.metrics.ConsoleReporter;
import com.codahale.metrics.Counter;
import com.codahale.metrics.MetricRegistry;

public class TestCounter {

    /**
     * 实例化一个registry,最核心的一个模块,相当于一个应用程序的metrics系统的容器,维护一个Map
     */
    private static final MetricRegistry metrics = new MetricRegistry();

    /**
     * 在控制台上打印输出
     */
    private static ConsoleReporter reporter = ConsoleReporter.forRegistry(metrics).build();

    /**
     * 实例化一个counter,同样可以通过如下方式进行实例化再注册进去
     * pendingJobs = new Counter();
     * ;
     */
    private static Counter pendingJobs = metrics.counter(MetricRegistry.name(TestCounter.class, "pedding。jobs"));



    private static Queue<String> queue = new LinkedList<String>();

    public static void add(String str) {
        pendingJobs.inc();
        queue.offer(str);
    }

    public static String take() {
        pendingJobs.dec();
        return queue.poll();
    }

    public static void main(String[]args) throws InterruptedException {
        reporter.start(3, TimeUnit.SECONDS);
        while(true){
            add("1");
            Thread.sleep(1000);
        }
    }
}

ConsoleReporter打印输出

18-1-2 14:11:02 ================================================================

-- Counters --------------------------------------------------------------------
example.TestCounter.pedding。jobs
             count = 4


18-1-2 14:11:05 ================================================================

-- Counters --------------------------------------------------------------------
example.TestCounter.pedding。jobs
             count = 7

3. Meters

Meters用来度量某个时间段的平均处理次数(request per second),每1、5、15分钟的TPS。比如一个service的请求数,通过metrics.meter()实例化一个Meter之后,然后通过meter.mark()方法就能将本次请求记录下来

package example;
import java.util.concurrent.TimeUnit;
import com.codahale.metrics.ConsoleReporter;
import com.codahale.metrics.Meter;
import com.codahale.metrics.MetricRegistry;
public class TestMeters {
    /**
     * 实例化一个registry,最核心的一个模块,相当于一个应用程序的metrics系统的容器,维护一个Map
     */
    private static final MetricRegistry metrics = new MetricRegistry();

    /**
     * 在控制台上打印输出
     */
    private static ConsoleReporter reporter = ConsoleReporter.forRegistry(metrics).build();

    /**
     * 实例化一个Meter
     */
    private static final Meter requests = metrics.meter(MetricRegistry.name(TestMeters.class, "request"));

    public static void handleRequest() {
        requests.mark();
    }

    public static void main(String[] args) throws InterruptedException {
        reporter.start(5, TimeUnit.SECONDS);
        while(true){
            handleRequest();
            Thread.sleep(100);
        }
    }

}

输出

18-1-2 14:51:25 ================================================================

-- Meters ----------------------------------------------------------------------
example.TestMeters.request
             count = 51
         mean rate = 10.15 events/second
     1-minute rate = 10.00 events/second
     5-minute rate = 10.00 events/second
    15-minute rate = 10.00 events/second


18-1-2 14:51:30 ================================================================

-- Meters ----------------------------------------------------------------------
example.TestMeters.request
             count = 100
         mean rate = 9.99 events/second
     1-minute rate = 10.00 events/second
     5-minute rate = 10.00 events/second
    15-minute rate = 10.00 events/second

4. Histograms

Histograms主要使用来统计数据的分布情况,最大值、最小值、平均值、中位数,百分比(75%、90%、95%、98%、99%和99.9%)。 场景:统计API请求响应时间

package example;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import com.codahale.metrics.ConsoleReporter;
import com.codahale.metrics.Histogram;
import com.codahale.metrics.MetricRegistry;

/**
 * 测试Histograms
 */
public class TestHistograms {
    /**
     * 实例化一个registry,最核心的一个模块,相当于一个应用程序的metrics系统的容器,维护一个Map
     */
    private static final MetricRegistry metrics = new MetricRegistry();

    /**
     * 在控制台上打印输出
     */
    private static ConsoleReporter reporter = ConsoleReporter.forRegistry(metrics).build();

    /**
     * 实例化一个Histograms
     */
    private static final Histogram responseTimeMetric= metrics.histogram(MetricRegistry.name(TestHistograms.class, "responsetime"));

    public static void handleRequest(double random) {
        responseTimeMetric.update((int) (random*100));
    }

    public static void main(String[] args) throws InterruptedException {
    	//ConsoleReporter启动 每5秒report输出一次
        reporter.start(5, TimeUnit.SECONDS);
        Random rand = new Random();
        do {
        	 handleRequest(rand.nextDouble());
             Thread.sleep(100);
        } while(true);
    }

}

输出

18-1-2 14:36:35 ================================================================

-- Histograms ------------------------------------------------------------------
example.TestHistograms.random
             count = 51
               min = 0
               max = 99
              mean = 52.34
            stddev = 31.46
            median = 49.00
              75% <= 83.00
              95% <= 98.00
              98% <= 99.00
              99% <= 99.00
            99.9% <= 99.00

5. Timers

Timers主要是用来统计某一块代码段的执行时间以及其分布情况,具体是基于Histograms和Meters来实现的。

Report类型

ConsoleReporter

前面例子中已经涉及

JmxReporter

JmxReporter 是将指标值输出到JDK Mbeans 中,可以通过JDK自带的jvisualvm.exe 查看.

package example.reporter;

import java.util.LinkedList;
import java.util.Queue;

import com.codahale.metrics.Gauge;
import com.codahale.metrics.JmxReporter;
import com.codahale.metrics.MetricRegistry;

import example.TestGauges;

public class TestJmxReporter {
	
    /**
     * 实例化一个registry,最核心的一个模块,相当于一个应用程序的metrics系统的容器,维护一个Map
     */
    private static final MetricRegistry metrics = new MetricRegistry();
    
    private static Queue<String> queue = new LinkedList<String>();

    /**
     * 在控制台上打印输出
     */
    private static JmxReporter reporter = JmxReporter.forRegistry(metrics).build();
	
	
	
	public static void main(String[] args) throws InterruptedException {
		reporter.start();

        //实例化一个Gauge
        Gauge<Integer> gauge = new Gauge<Integer>() {
            public Integer getValue() {
                return queue.size();
            }
        };
        
        

        //注册到容器中
        metrics.register(MetricRegistry.name(TestGauges.class, "pending.job", "size"), gauge);
        

   
        //模拟数据
        for (int i=0; i<1000; i++){
            queue.add("a");
            Thread.sleep(1000);
        }

	}

}

输出查看 输入图片说明

SLF4JReporter

final Slf4jReporter reporter = Slf4jReporter.forRegistry(registry)
                                            .outputTo(LoggerFactory.getLogger("com.example.metrics"))
                                            .convertRatesTo(TimeUnit.SECONDS)
                                            .convertDurationsTo(TimeUnit.MILLISECONDS)
                                            .build();
reporter.start(1, TimeUnit.MINUTES);

GraphiteReporter

该metrics-graphite模块提供GraphiteReporter,它允许您的应用程序不断将度量标准值传输到Graphite服务器

Metrics模块

  • metrics-json提供了json格式的序列化。 以及为其它库提供度量的能力
  • metrics-ehcache
  • metrics-httpclient
  • metrics-jdbi
  • metrics-jersey
  • metrics-jetty
  • metrics-log4j
  • metrics-logback
  • metrics-jvm
  • Metrics Servlets

第三方库

  • metrics-librato 提供Librato Metrics报表
  • Metrics Spring Integration 提供了Spring的集成
  • sematext-metrics-reporter 提供了SPM报表.
  • wicket-metrics提供Wicket应用.
  • metrics-guice 提供Guice集成.
  • metrics-scala 提供了为Scala优化的API.

metrics源码解析

//TODO

场景应用

Metrics与Spring集成

Metrics和graphite监控

Metrics+InfluxDB+Grafana 监控

Metrics+openFalcon 监控

//TODO

Java服务端监控平台设计

参考资料

官方文档:http://metrics.dropwizard.io/3.2.3/ 代码库:https://github.com/dropwizard/metrics

更详细参考资料:

https://www.cnblogs.com/nexiyi/p/metrics_sample_1.html

http://www.cnblogs.com/nexiyi/p/metrics_sample_2.html

http://colobu.com/2014/08/08/Metrics-and-Spring-Integration/

Metrics与Spring集成

metrics 与spring集成 http://blog.youkuaiyun.com/zyt425916200/article/details/54392047

转载于:https://my.oschina.net/guoenzhou/blog/1600549

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值