spring boot 源码解析45-RichGaugeReader,RichGaugeRepository

前言

本文我们介绍的是RichGaugeReader,RichGaugeRepository相关的实现.其类图如下:

类图

解析

RichGauge

RichGauge–>存储最大值,最小值,平均值的对象.平均值的计算取决于权重(alpha)的设置.如果没有设置,其平均值就是1个算术平均数.如果该值给定了,就会按照NIST的文档计算指数平均数指标

指数平均数指标=EMA(today)=α * Price(today) + ( 1 - α ) * EMA(yesterday)

相关链接如下:

EMA

  1. 该类的字段如下:

    // 统计指标的后缀
    public static final String COUNT = ".count";
    
    // 最大值的后缀
    public static final String MAX = ".max";
    
    // 最小值的后缀
    public static final String MIN = ".min";
    
    // 平均值的后缀
    public static final String AVG = ".avg";
    
    // alpha 的后缀
    public static final String ALPHA = ".alpha";
    
    // 指标值的后缀
    public static final String VAL = ".val";
    
    // 指标名称
    private final String name;
    
    // 值
    private double value;
    
    // 如果alpha设置了.则是1个算术平均数,否则是指数平均数指标
    private double average;
    
    // 最大值
    private double max;
    
    // 最小值
    private double min;
    
    // 次数统计
    private long count;
    
    // 权重因子
    private double alpha;
  2. 构造器如下:

    public RichGauge(String name) {
        this(name, 0.0);
        this.count = 0;
    }
    
    public RichGauge(String name, double value) {
        Assert.notNull(name, "The gauge name cannot be null or empty");
        this.name = name;
        this.value = value;
        this.average = this.value;
        this.min = this.value;
        this.max = this.value;
        this.alpha = -1.0;
        this.count = 1;
    }
    
    public RichGauge(String name, double value, double alpha, double mean, double max,
            double min, long count) {
        this.name = name;
        this.value = value;
        this.alpha = alpha;
        this.average = mean;
        this.max = max;
        this.min = min;
        this.count = count;
    }
  3. 其声明了2个主要的方法:

    1. set,代码如下:

      RichGauge set(double value) {
          // 1. 如果count等于0,相等于是第一次访问,则设置最大值,最小值为给定的值
          if (this.count == 0) {
              this.max = value;
              this.min = value;
          }
          // 2. 如果value比当前的最大值大,则进行替换
          else if (value > this.max) {
              this.max = value;
          }
          // 3. 如果value比当前的最大值小,则进行替换
          else if (value < this.min) {
              this.min = value;
          }
      
          // 4. 如果alpha指定了并且count大于0,则计算指数平均数指标,否则计算算数平均数
          if (this.alpha > 0.0 && this.count > 0) {
              this.average = this.alpha * this.value + (1 - this.alpha) * this.average;
          }
          else {
              double sum = this.average * this.count;
              sum += value;
              this.average = sum / (this.count + 1);
          }
          // 5. 累加计数器,并修改value值为给定的
          this.count++;
          this.value = value;
          return this;
      }
    2. reset–>重置,代码如下:

      RichGauge reset() {
          this.value = 0.0;
          this.max = 0.0;
          this.min = 0.0;
          this.average = 0.0;
          this.count = 0;
          return this;
      }

RichGaugeReader

RichGaugeReader–> 1个基本的对于RichGauge的读 操作的集合.声明的方法如下:

// 通过名字查找
RichGauge findOne(String name);

// 获取所有
Iterable<RichGauge> findAll();

// 返回数量
long count();

MultiMetricRichGaugeReader

MultiMetricRichGaugeReader–>个从MultiMetricRepository(分组名字是RichGauge 中的名字)中读取metric 数据的实现.其格式和RichGaugeExporter 一样,因此,该类可以用在被RichGaugeExporter已经填充过数据的地方.该类不是默认装配的

  1. 字段,构造器如下:

    private final MultiMetricRepository repository;
    
    public MultiMetricRichGaugeReader(MultiMetricRepository repository) {
        this.repository = repository;
    }
  2. 方法实现如下:

    1. findOne –>根据给定的名字获得给定的RichGauge.代码如下:

      public RichGauge findOne(String name) {
          // 1. 从MultiMetricRepository获得所有以指定名称开头的Metric
          Iterable<Metric<?>> metrics = this.repository.findAll(name);
          double value = 0;
          double average = 0.;
          double alpha = -1.;
          double min = 0.;
          double max = 0.;
          long count = 0;
          // 2. 依次遍历之
          for (Metric<?> metric : metrics) {
              // 2.1 如果是.val结尾的,则将其值赋值给value
              if (metric.getName().endsWith(RichGauge.VAL)) {
                  value = metric.getValue().doubleValue();
              }
              // 2.2 如果是.alpha结尾的,则将其值赋值给alpha
              else if (metric.getName().endsWith(RichGauge.ALPHA)) {
                  alpha = metric.getValue().doubleValue();
              }
              // 2.3 如果是.avg结尾的,则将其值赋值给average
              else if (metric.getName().endsWith(RichGauge.AVG)) {
                  average = metric.getValue().doubleValue();
              }
              // 2.4 如果是.min结尾的,则将其值赋值给min
              else if (metric.getName().endsWith(RichGauge.MIN)) {
                  min = metric.getValue().doubleValue();
              }
              // 2.5 如果是.max结尾的,则将其值赋值给max
              else if (metric.getName().endsWith(RichGauge.MAX)) {
                  max = metric.getValue().doubleValue();
              }
              // 2.6 如果是.count结尾的,则将其值赋值给count
              else if (metric.getName().endsWith(RichGauge.COUNT)) {
                  count = metric.getValue().longValue();
              }
          }
          // 3. 实例化RichGauge
          return new RichGauge(name, value, alpha, average, max, min, count);
      }
    2. findAll–> 获得所有的RichGauge,代码如下:

      public Iterable<RichGauge> findAll() {
          List<RichGauge> result = new ArrayList<RichGauge>();
          // 1. 遍历MultiMetricRepository中的group
          for (String name : this.repository.groups()) {
              // 2. 依次调用findOne方法获得对应的RichGauge,加入到结果集中
              result.add(findOne(name));
          }
          return result;
      }
    3. count–> 调用MultiMetricRepository#countGroups –> 获得group的大小.代码如下:

      public long count() {
          return this.repository.countGroups();
      }

RichGaugeRepository

RichGaugeRepository–>合并了RichGaugeReader,MetricWriter 接口.代码如下:

public interface RichGaugeRepository extends RichGaugeReader, MetricWriter {

}

InMemoryRichGaugeRepository

InMemoryRichGaugeRepository–> 使用SimpleInMemoryRepository来实现MetricWriter和RichGaugeReader.其内部持有着1个SimpleInMemoryRepository,泛型为RichGauge.

方法实现如下:

  1. increment:

    public void increment(final Delta<?> delta) {
        this.repository.update(delta.getName(), new Callback<RichGauge>() {
    
            @Override
            public RichGauge modify(RichGauge current) {
                double value = ((Number) delta.getValue()).doubleValue();
                if (current == null) {
                    return new RichGauge(delta.getName(), value);
                }
                current.set(current.getValue() + value);
                return current;
            }
    
        });
    }
    1. 从metrics中获得Delta所对应的RichGauge
    2. 如果Metric存在的话,则在原先的基础上加上传入的Delta的值
    3. 如果不存在,则直接根据传入Delta的名称,值实例化1个RichGauge,加入到repository的values中
  2. set–> 代码如下:

    public void set(Metric<?> metric) {
        final String name = metric.getName();
        final double value = metric.getValue().doubleValue();
        this.repository.update(name, new Callback<RichGauge>() {
    
            @Override
            public RichGauge modify(RichGauge current) {
                if (current == null) {
                    return new RichGauge(name, value);
                }
                current.set(value);
                return current;
            }
    
        });
    }
    1. 从metrics中获得Metric所对应的RichGauge
    2. 如果Metric存在的话,则修改其值为传入的Metric
    3. 如果不存在,则直接根据传入Metric的名称,值实例化1个RichGauge,加入到repository的values中
  3. 其他方法比较简单,罗列如下:

    public void reset(String metricName) {
        this.repository.remove(metricName);
    }
    
    @Override
    public RichGauge findOne(String metricName) {
        return this.repository.findOne(metricName);
    }
    
    @Override
    public Iterable<RichGauge> findAll() {
        return this.repository.findAll();
    }
    
    @Override
    public long count() {
        return this.repository.count();
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值