vlambda博客
学习文章列表

【HDFS】--@Metric是如何生效的?

前言

在HDFS的jmx界面中,我们能够看到很多的监控指标,如下图:

在二次开发的过程中,我们需要自定义一些指标,然后暴露出来,那如何实现呢?这就需要我们了解HDFS的Metric体系。

0x00 实现自定义metric

实现自定义指标很简单,只需要使用@Metric注解即可。

【HDFS】--@Metric是如何生效的?

然后可以在jmx界面中看到这个指标。

【HDFS】--@Metric是如何生效的?

很简单对吧,接下来我们看看怎么实现的。

0x01  @Metric注解的实现

【HDFS】--@Metric是如何生效的?

我们采用自顶向下来看:

首先从FSNamesystem类出发,在启动Namenode时,会调用startCommonServices方法,在startCommonServices方法中会注册jmx相关的Bean。

【HDFS】--@Metric是如何生效的?
image.png

DefaultMetricsSystem.instance()返回一个MetricsSystemImpl对象。然后调用了register方法。

【HDFS】--@Metric是如何生效的?

register的真正实现在MetricsSystemImpl#register方法中。

【HDFS】--@Metric是如何生效的?

因为我是提前看了源码,所以这里直接告诉大家,在newSourceBuilder里会通过反射获取使用了@Metric注解的方法或者成员变量。然后放到Map里,用于最后的jmx输出。如下图所示:

【HDFS】--@Metric是如何生效的?

我们选第二个foreach进行阅读,因为前面我们就是使用@Metric修饰方法来实现自定义metric的。点进此add方法之后,代码如下:

【HDFS】--@Metric是如何生效的?

此add方法会用foreach确保方法有@Metric注解,然后再进行处理。
接下来有如下语句:
factory.newForMethod(source, method, (Metric) annotation, registry);

点进newForMethod方法之前,观察一下newForMethod的参数:
source代表FSNamesysterm,method代表被@Metric修饰的方法,
annotation代表注解,registry则是存储metrics信息的的对象。

我们点进newForMethod方法去看一下:

【HDFS】--@Metric是如何生效的?

这个方法的主要逻辑如下:

  1. 根据注解+方法构造出MetricsInfo对象,注解里的参数能够对应到MetricsInfo对象成员。

  2. new出一个MethodMetric对象,代表从@Metric修饰的方法中获得的metric

  3. 将上一步new出的MethodMetric对象放入registry的Map中保存,key是注解里提供的name参数或者方法名(注解未传name参数的时候,默认是方法名)

  4. 返回这个方法代表的metric。

这个方法中调用的getInfo方法,就是用来从@Metric传入的参数中解析metric名的。比如上面我们写的例子是这样的:
@Metric({"MyMetrics", "test customer metrics"})
那么MyMetrics就用来当做指标的name,
test customer metrics就用来当做指标的description。

同时在new  MethodMetric的时候,也会去计算指标值:

【HDFS】--@Metric是如何生效的?

进到newImpl的case DEFAULT分支,调用了newTag方法。

newTag方法里面会调用method对象的invoke方法,得到用@Metric注解修饰的方法的返回值,作为metric的value,代码如下:

到此我们也就分析完@Metric的原理了。