zoukankan      html  css  js  c++  java
  • Metrics-Java版的指标度量工具之二

    接上《Metrics-Java版的指标度量工具之一

    4.       Histograms

    Histograms主要使用来统计数据的分布情况,最大值、最小值、平均值、中位数,百分比(75%、90%、95%、98%、99%和99.9%)。例如,需要统计某个页面的请求响应时间分布情况,可以使用该种类型的Metrics进行统计。具体的样例代码如下:

    package com.netease.test.metrics;
    
    import com.codahale.metrics.ConsoleReporter;
    import com.codahale.metrics.Histogram;
    import com.codahale.metrics.MetricRegistry;
    
    import java.util.Random;
    import java.util.concurrent.TimeUnit;
    
    import static com.codahale.metrics.MetricRegistry.name;
    
    /**
     * User: hzwangxx
     * Date: 14-2-17
     * Time: 18:34
     * 测试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 randomNums = metrics.histogram(name(TestHistograms.class, "random"));
    
        public static void handleRequest(double random) {
            randomNums.update((int) (random*100));
        }
    
        public static void main(String[] args) throws InterruptedException {
            reporter.start(3, TimeUnit.SECONDS);
            Random rand = new Random();
            while(true){
                handleRequest(rand.nextDouble());
                Thread.sleep(100);
            }
        }
    
    }
    
    /*
    14-2-17 19:39:11 ===============================================================
    
    -- Histograms ------------------------------------------------------------------
    com.netease.test.metrics.TestHistograms.random
                 count = 30
                   min = 1
                   max = 97
                  mean = 45.93
                stddev = 29.12
                median = 39.50
                  75% <= 71.00
                  95% <= 95.90
                  98% <= 97.00
                  99% <= 97.00
                99.9% <= 97.00
    
    
    14-2-17 19:39:14 ===============================================================
    
    -- Histograms ------------------------------------------------------------------
    com.netease.test.metrics.TestHistograms.random
                 count = 60
                   min = 0
                   max = 97
                  mean = 41.17
                stddev = 28.60
                median = 34.50
                  75% <= 69.75
                  95% <= 92.90
                  98% <= 96.56
                  99% <= 97.00
                99.9% <= 97.00
    
    
    14-2-17 19:39:17 ===============================================================
    
    -- Histograms ------------------------------------------------------------------
    com.netease.test.metrics.TestHistograms.random
                 count = 90
                   min = 0
                   max = 97
                  mean = 44.67
                stddev = 28.47
                median = 43.00
                  75% <= 71.00
                  95% <= 91.90
                  98% <= 96.18
                  99% <= 97.00
                99.9% <= 97.00
    */

    5.       Timers

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

    package com.netease.test.metrics;
    
    import com.codahale.metrics.ConsoleReporter;
    import com.codahale.metrics.MetricRegistry;
    import com.codahale.metrics.Timer;
    
    import java.util.Random;
    import java.util.concurrent.TimeUnit;
    
    import static com.codahale.metrics.MetricRegistry.name;
    
    /**
     * User: hzwangxx
     * Date: 14-2-17
     * Time: 18:34
     * 测试Timers
     */
    public class TestTimers {
        /**
         * 实例化一个registry,最核心的一个模块,相当于一个应用程序的metrics系统的容器,维护一个Map
         */
        private static final MetricRegistry metrics = new MetricRegistry();
    
        /**
         * 在控制台上打印输出
         */
        private static ConsoleReporter reporter = ConsoleReporter.forRegistry(metrics).build();
    
        /**
         * 实例化一个Meter
         */
    //    private static final Timer requests = metrics.timer(name(TestTimers.class, "request"));
        private static final Timer requests = metrics.timer(name(TestTimers.class, "request"));
    
        public static void handleRequest(int sleep) {
            Timer.Context context = requests.time();
            try {
                //some operator
                Thread.sleep(sleep);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                context.stop();
            }
    
        }
    
        public static void main(String[] args) throws InterruptedException {
            reporter.start(3, TimeUnit.SECONDS);
            Random random = new Random();
            while(true){
                handleRequest(random.nextInt(1000));
            }
        }
    
    }
    
    /*
    14-2-18 9:31:54 ================================================================
    
    -- Timers ----------------------------------------------------------------------
    com.netease.test.metrics.TestTimers.request
                 count = 4
             mean rate = 1.33 calls/second
         1-minute rate = 0.00 calls/second
         5-minute rate = 0.00 calls/second
        15-minute rate = 0.00 calls/second
                   min = 483.07 milliseconds
                   max = 901.92 milliseconds
                  mean = 612.64 milliseconds
                stddev = 196.32 milliseconds
                median = 532.79 milliseconds
                  75% <= 818.31 milliseconds
                  95% <= 901.92 milliseconds
                  98% <= 901.92 milliseconds
                  99% <= 901.92 milliseconds
                99.9% <= 901.92 milliseconds
    
    
    14-2-18 9:31:57 ================================================================
    
    -- Timers ----------------------------------------------------------------------
    com.netease.test.metrics.TestTimers.request
                 count = 8
             mean rate = 1.33 calls/second
         1-minute rate = 1.40 calls/second
         5-minute rate = 1.40 calls/second
        15-minute rate = 1.40 calls/second
                   min = 41.07 milliseconds
                   max = 968.19 milliseconds
                  mean = 639.50 milliseconds
                stddev = 306.12 milliseconds
                median = 692.77 milliseconds
                  75% <= 885.96 milliseconds
                  95% <= 968.19 milliseconds
                  98% <= 968.19 milliseconds
                  99% <= 968.19 milliseconds
                99.9% <= 968.19 milliseconds
    
    
    14-2-18 9:32:00 ================================================================
    
    -- Timers ----------------------------------------------------------------------
    com.netease.test.metrics.TestTimers.request
                 count = 15
             mean rate = 1.67 calls/second
         1-minute rate = 1.40 calls/second
         5-minute rate = 1.40 calls/second
        15-minute rate = 1.40 calls/second
                   min = 41.07 milliseconds
                   max = 968.19 milliseconds
                  mean = 591.35 milliseconds
                stddev = 302.96 milliseconds
                median = 650.56 milliseconds
                  75% <= 838.07 milliseconds
                  95% <= 968.19 milliseconds
                  98% <= 968.19 milliseconds
                  99% <= 968.19 milliseconds
                99.9% <= 968.19 milliseconds
    
    */

    Health Checks

    Metrics提供了一个独立的模块:Health Checks,用于对Application、其子模块或者关联模块的运行是否正常做检测。该模块是独立metrics-core模块的,使用时则导入metrics-healthchecks包。

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

    使用起来和与上述几种类型的Metrics有点类似,但是需要重新实例化一个Metrics容器HealthCheckRegistry,待检测模块继承抽象类HealthCheck并实现check()方法即可,然后将该模块注册到HealthCheckRegistry中,判断的时候通过isHealthy()接口即可。如下示例代码:

    package com.netease.test.metrics;
    
    import com.codahale.metrics.health.HealthCheck;
    import com.codahale.metrics.health.HealthCheckRegistry;
    
    import java.util.Map;
    import java.util.Random;
    
    /**
     * User: hzwangxx
     * Date: 14-2-18
     * Time: 9:57
     */
    public class DatabaseHealthCheck extends HealthCheck{
        private final Database database;
    
        public DatabaseHealthCheck(Database database) {
            this.database = database;
        }
    
        @Override
        protected Result check() throws Exception {
            if (database.ping()) {
                return Result.healthy();
            }
            return Result.unhealthy("Can't ping database.");
        }
    
        /**
         * 模拟Database对象
         */
        static class Database {
            /**
             * 模拟database的ping方法
             * @return 随机返回boolean值
             */
            public boolean ping() {
                Random random = new Random();
                return random.nextBoolean();
            }
        }
    
        public static void main(String[] args) {
    //        MetricRegistry metrics = new MetricRegistry();
    //        ConsoleReporter reporter = ConsoleReporter.forRegistry(metrics).build();
            HealthCheckRegistry registry = new HealthCheckRegistry();
            registry.register("database1", new DatabaseHealthCheck(new Database()));
            registry.register("database2", new DatabaseHealthCheck(new Database()));
            while (true) {
                for (Map.Entry<String, Result> entry : registry.runHealthChecks().entrySet()) {
                    if (entry.getValue().isHealthy()) {
                        System.out.println(entry.getKey() + ": OK");
                    } else {
                        System.err.println(entry.getKey() + ": FAIL, error message: " + entry.getValue().getMessage());
                        final Throwable e = entry.getValue().getError();
                        if (e != null) {
                            e.printStackTrace();
                        }
                    }
                }
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
    
                }
            }
        }
    }
    
    /*
    console output:
    database1: OK
    database2: FAIL, error message: Can't ping database.
    database1: FAIL, error message: Can't ping database.
    database2: OK
    database1: OK
    database2: FAIL, error message: Can't ping database.
    database1: FAIL, error message: Can't ping database.
    database2: OK
    database1: FAIL, error message: Can't ping database.
    database2: FAIL, error message: Can't ping database.
    database1: FAIL, error message: Can't ping database.
    database2: FAIL, error message: Can't ping database.
    database1: OK
    database2: OK
    database1: OK
    database2: FAIL, error message: Can't ping database.
    database1: FAIL, error message: Can't ping database.
    database2: OK
    database1: OK
    database2: OK
    database1: FAIL, error message: Can't ping database.
    database2: OK
    database1: OK
    database2: OK
    database1: OK
    database2: OK
    database1: OK
    database2: FAIL, error message: Can't ping database.
    database1: FAIL, error message: Can't ping database.
    database2: FAIL, error message: Can't ping database.
    
     */

    其他支持

    metrics提供了对Ehcache、Apache HttpClient、JDBI、Jersey、Jetty、Log4J、Logback、JVM等的集成,可以方便地将Metrics输出到Ganglia、Graphite中,供用户图形化展示。

    参考资料

    http://metrics.codahale.com/

    https://github.com/dropwizard/metrics

    http://blog.csdn.net/scutshuxue/article/details/8350135

    http://blog.synyx.de/2013/09/yammer-metrics-made-easy-part-i/

    http://blog.synyx.de/2013/09/yammer-metrics-made-easy-part-ii/

    http://wiki.apache.org/hadoop/HADOOP-6728-MetricsV2

  • 相关阅读:
    KeilMdk .gitignore文件
    C#与C/C++之间数据类型的转换
    「邮件规则」​​​​​​​​写出我心(一百七十六)
    「当机立断」​​​​​​​写出我心(一百七十五)
    「职责范围」​​​​​​写出我心(一百七十四)
    「建立个人知识库」​​​​​写出我心(一百七十三)
    「学会利用资源」​​​​写出我心(一百七十二)
    「跨越舒适区」​​​写出我心(一百七十一)
    「凡事预则立不预则废」​​写出我心(一百七十)
    「论述」​写出我心(一百六十九)
  • 原文地址:https://www.cnblogs.com/nexiyi/p/metrics_sample_2.html
Copyright © 2011-2022 走看看