Metrics源码阅读(02)之Metrics

Metrics类,看这个名字,就知道很重要了,都和项目名一致了,出身就高贵。当然得赶紧研究一下:

一、类定义:

/**
 * A set of factory methods for creating centrally registered metric instances.
 */
public class Metrics {

普通的类定义,普通的class类。注意注释信息,一个Set用来装工厂方法创建的中心注册的metric实例。

二、成员常量:

有两个成员常量:

(1)DEFAULT_REGISTRY,是一个MetricRegistry类引用。

private static final MetricsRegistry DEFAULT_REGISTRY = new MetricsRegistry();

(2)一个线程类成员常量, SHUTDOWN_HOOK

    private static final Thread SHUTDOWN_HOOK = new Thread() {
        public void run() {
            JmxReporter.shutdownDefault();
        }
    };

重点关注,run()方法,这里是调用JmxReporter类的静态方法shutdownDefault(),先记下,后面研究。

三、静态代码块:

    static {
        JmxReporter.startDefault(DEFAULT_REGISTRY);
        Runtime.getRuntime().addShutdownHook(SHUTDOWN_HOOK);
    }

注意成员常量SHUTDOWN_HOOK的run()方法,以及成员常量DEFAULT_REGISTRY。这个静态代码块,用到了这两个成员常量。

并且,Runtime.getRuntime().addShutdownHoook()是用来在jvm关闭时增加了一个钩子。

四、构造函数:

private Metrics() { /* unused */ }

声明为private, 也就是说Metrics不允许被实例化。(反射除外啊)

五、公开方法:

22个静态方法,也符合类设定,毕竟都不允许实例化了嘛。我将这22个静态方法,按照特点,分成以下5组,

(1)Gauge组

    public static <T> Gauge<T> newGauge(Class<?> klass,
                                        String name,
                                        Gauge<T> metric) {
        return DEFAULT_REGISTRY.newGauge(klass, name, metric);
    }
   public static <T> Gauge<T> newGauge(Class<?> klass,
                                        String name,
                                        String scope,
                                        Gauge<T> metric) {
        return DEFAULT_REGISTRY.newGauge(klass, name, scope, metric);
    }
    public static <T> Gauge<T> newGauge(MetricName metricName,
                                        Gauge<T> metric) {
        return DEFAULT_REGISTRY.newGauge(metricName, metric);
    }

将这三个函数分到一组,因为他们都返回Gauge类型引用。三个函数属于函数重载,参数都不相同,共同点是最后一个参数都是一个Gauge类型。并且都是委托成员常量DEFAULT_REGISTRY的同名同参方法去执行。感觉MetricsRegistry是一个影子类。

(2)Counter组

    public static Counter newCounter(Class<?> klass, String name) {
        return DEFAULT_REGISTRY.newCounter(klass, name);
    }
    public static Counter newCounter(Class<?> klass,
                                     String name,
                                     String scope) {
        return DEFAULT_REGISTRY.newCounter(klass, name, scope);
    }
    public static Counter newCounter(MetricName metricName) {
        return DEFAULT_REGISTRY.newCounter(metricName);
    }

也是三个,不同于Gauge, Counter没有用到泛型,并且输入参数没有自己的这种类型参数。同样也是调用DEFAULT_REGISTY的同名同参方法。

(3)Histogram组,这个是一个大组,有5个方法,原理与Counter类似,方法内部也类似,这里就不再罗列。

(4)Timer组,这是最大的一个组,足足有8个方法,原理与前面几组类似,都是调用DEFAULT_REGISTY的同名同参方法主执行,Timer顾名思义,时间有关的,也因此参数中引入了java.util.concurrent.TimeUnit枚举类。这里仅列一个方法,示例一下:

    public static Timer newTimer(MetricName metricName,
                                 TimeUnit durationUnit,
                                 TimeUnit rateUnit) {
        return DEFAULT_REGISTRY.newTimer(metricName, durationUnit, rateUnit);
    }

(5)其他方法,总共有两个,一个是直接返回成员常量DEFAULT_REGISTY,还有一个方法,我列出来,看一下:

    public static void shutdown() {
        DEFAULT_REGISTRY.shutdown();
        JmxReporter.shutdownDefault();
        Runtime.getRuntime().removeShutdownHook(SHUTDOWN_HOOK);
    }

是不是和static静态代码块很相似。但是方式确实完全不同,静态代码块像是隐式关闭,这个更像是一种显示关闭操作。

【总结】:Metris类很重要,同时这个类中,引入了Gauge、Counter、Histogram、Timer这四个类。

【思考】:这四个类代表着什么呢?它们是不是Metrics的核心类呢?

猜你喜欢

转载自blog.csdn.net/guohengcook/article/details/81293118