您的位置:首页 > 编程语言 > Java开发

spring boot 源码解析38-GaugeService详解

2018-01-25 10:38 961 查看

前言

本文来分析GaugeService的实现,其类图如下:



解析

GaugeService

GaugeService–> 1个可以用来提交1个被命名的duble值为了存储和分析的服务.任意的统计和分析需要留给其他人去做,但是最终还是需要被该接口的实现所控制.举例说明:这个值可能是通过1个定时任务提交的,并且保存在后端的直方图中以进行比较。或者 可以是一个传感器值的简单测量(比如温度读数)以原始形式传递给监测系统.

其只声明了1个方法,如下:

// 设置给定的测量值
void submit(String metricName, double value);


DefaultGaugeService

DefaultGaugeService实现了GaugeService接口.该类是JDK1.8之前默认装配的

其字段,构造器如下:

// 此时注入的是InMemoryMetricRepository
private final MetricWriter writer;

// key-->metricName,value-->加入前缀后的metricName
private final ConcurrentHashMap<String, String> names = new ConcurrentHashMap<String, String>();

public DefaultGaugeService(MetricWriter writer) {
this.writer = writer;
}


submit 实现如下:

public void submit(String metricName, double value) {
this.writer.set(new Metric<Double>(wrap(metricName), value));
}


尝试为传入的metricName加上前缀.代码如下:

private String wrap(String metricName) {
// 1. 如果缓存中有的话,则直接返回对应的值
String cached = this.names.get(metricName);
if (cached != null) {
return cached;
}
// 2. 如果传入的metricName是gauge或者histogram或者timer开头的则直接返回
if (metricName.startsWith("gauge") || metricName.startsWith("histogram")
|| metricName.startsWith("timer")) {
return metricName;
}
// 3. 为metricName 加上gauge.的前缀,放入到names缓存中,然后进行返回
String name = "gauge." + metricName;
this.names.put(metricName, name);
return name;
}


如果缓存中有的话,则直接返回对应的值

如果传入的metricName是gauge或者histogram或者timer开头的则直接返回

为metricName 加上gauge.的前缀,放入到names缓存中,然后进行返回

实例化Metric

加入到InMemoryMetricRepository中.

GaugeBuffer

GaugeBuffer实现了Buffer接口,代码如下:

public class GaugeBuffer extends Buffer<Double> {

private volatile double value;

public GaugeBuffer(long timestamp) {
super(timestamp);
this.value = 0;
}

@Override
public Double getValue() {
return this.value;
}

public void setValue(double value) {
this.value = value;
}

}


GaugeBuffers

GaugeBuffers继承自Buffers,泛型参数为GaugeBuffer.该类是1.8以后默认装配的.

createBuffer,直接实例化了1个GaugeBuffer,时间戳为当前时间,值为0.实现如下:

protected GaugeBuffer createBuffer() {
return new GaugeBuffer(0L);
}


此外,还声明了1个set方法–> 对给定名字的GaugeBuffer设置值.代码如下:

public void set(final String name, final double value) {
doWith(name, new Consumer<GaugeBuffer>() {
@Override
public void accept(GaugeBuffer buffer) {
buffer.setTimestamp(System.currentTimeMillis());
buffer.setValue(value);
}
});
}


从父类中的buffers获得给定名字所对应的GaugeBuffer,如果不存在,则创建1个

将GaugeBuffer中的时间戳设为当前时间,并设置给定的值

使用案例

新建GaugeController.代码如下:

package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.metrics.GaugeService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class GaugeController {

@Autowired
private GaugeService gaugeService;

@RequestMapping("/test-gauge")
public String testGauge() {
long start = System.currentTimeMillis();

try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}

gaugeService.submit("test-gauge.use", System.currentTimeMillis()-start);
return "操作成功";
}
}


我们访问如下链接后 http://127.0.0.1:8080/test-gauge 后,访问 http://127.0.0.1:8080/metrics,即可发现gauge.test-gauge.use对应的统计次数约为5005.如下:

auge.test-gauge.use: 5005
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring 源码 存储