Prometheus基于java开发exporter样例以及pushgateway的应用

目录

 

4种常用Metrics

Counter

Gauge

Histogram

Summary

基于SpringBoot写一个简单的exporter_demo

1.pom.xml配置如下

2.Application类注解

3.CounterDemo

4.GaugeDemo

5.HistogramDemo

6.SummaryDemo

7.关于pushgateway

参考文献


4种常用Metrics

Counter

连续增加不会减少的计数器,可以用于记录只增不减的类型,例如:网站访问人数,系统运行时间等。

对于Counter类型的指标,只包含一个inc()的方法,就是用于计数器+1.

一般而言,Counter类型的metric指标在冥冥中我们使用_total结束,如http_requests_total.

Gauge

可增可减的仪表盘,曲线图

对于这类可增可减的指标,用于反应应用的当前状态。

例如在监控主机时,主机当前空闲的内存大小,可用内存大小等等。

对于Gauge指标的对象则包含两个主要的方法inc()和dec(),用于增加和减少计数。

Histogram

主要用来统计数据的分布情况,这是一种特殊的metrics数据类型,代表的是一种近似的百分比估算数值,统计所有离散的指标数据在各个取值区段内的次数。例如:我们想统计一段时间内http请求响应小于0.005秒、小于0.01秒、小于0.025秒的数据分布情况。那么使用Histogram采集每一次http请求的时间,同时设置bucket。

Histogram会自动创建3个指标,分别为:
一、事件发生总次数: basename_count:
#实际含义: 当前一共发生了2次http请求
io_namespace_http_requests_latency_seconds_histogram_count{path="/",method="GET",code="200",} 2.0
二、所有事件产生值的大小的总和: basename_sum
#实际含义: 发生的2次http请求总的响应时间为13.107670803000001 秒
io_namespace_http_requests_latency_seconds_histogram_sum{path="/",method="GET",code="200",} 13.107670803000001
三、事件产生的值分布在bucket中的次数: basename_bucket{le="上包含"}
# 在总共2次请求当中。http请求响应时间 <=0.005 秒 的请求次数为0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="0.005",} 0.0
在总共2次请求当中。http请求响应时间 <=0.01 秒 的请求次数为0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="0.01",} 0.0
在总共2次请求当中。http请求响应时间 <=0.025 秒 的请求次数为0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="0.025",} 0.0

Summary

Summary和Histogram非常相似,都可以统计事件发生的次数或者大小,以及其分布情况,他们都提供了对时间的计数_count以及值的汇总_sum,也都提供了可以计算统计样本分布情况的功能,不同之处在于Histogram可以通过histogram_quantile函数在服务器计算分位数。而Sumamry的分位数则是直接在客户端进行定义的。因此对于分位数的计算,Summary在通过PromQL进行查询的时候有更好的性能表现,而Histogram则会消耗更多的资源,但是相对于客户端而言Histogram消耗的资源就更少。用哪个都行,根据实际场景自由调整即可。

基于SpringBoot写一个简单的exporter_demo

1.pom.xml配置如下



	4.0.0
	com.unicom
	exporter-demo
	0.0.1-SNAPSHOT
	jar

	exporter-demo
	Demo project for Spring Boot

	
		org.springframework.boot
		spring-boot-starter-parent
		1.5.11.RELEASE
		 
	

	
		UTF-8
		UTF-8
		1.8
	

	

        
        
            io.prometheus
            simpleclient_spring_boot
            0.4.0
        
        
            io.prometheus
            simpleclient_hotspot
            0.4.0
        
        
            io.prometheus
            simpleclient_servlet
            0.4.0
        
		
			io.prometheus
			simpleclient_pushgateway
			0.4.0
		
        
		
			org.springframework.boot
			spring-boot-starter-web
		

		
			org.springframework.boot
			spring-boot-starter-test
			test
		
	

	
		
			
				org.springframework.boot
				spring-boot-maven-plugin
			
		
	

4个prometheus的依赖包和两个pushgateway的依赖包。

2.Application类注解

@SpringBootApplication
@EnableScheduling
@EnablePrometheusEndpoint
@EnableSpringBootMetricsCollector
public class ExporterDemoApplication{

	public static void main(String[] args) {
		SpringApplication.run(ExporterDemoApplication.class, args);
	}
}

添加@EnableScheduling注解主要是添加了定时任务,用于动态模拟数据的变化,后面会看到应用的地方。

3.CounterDemo

定义一个Counter类型的metrics,一般而言,Counter类型的metrics指标在命名中我们使用_total结束。

@RestController
public class CounterDemo {
    /*
     *  使用Counter.build()创建Counter类型的监控指标,并且通过name()方法定义监控指标的名称network_traffic_input
     * ,通过labelNames()定义该指标包含的标签。最后通过register()将该指标注册到Collector的defaultRegistry中
     */
    static final Counter counterDemo = Counter.build()
            .name("counterChanger2").labelNames("wy","zxjr","ocs","xxjf","unit")
            .help("Counter 实例").register();
    //指标埋点,定时器会造成普罗米修斯与本地的数据时间戳不同步,尽量不要使用这种方式,实例中的定时器是为了数据演示
    @Scheduled(cron="0/5 * * * * ?")
    @RequestMapping("/changeCounter")
    public  void changeCounter(){
      counterDemo.labels("网元","在线接入","OCS","消息计费","seconds").inc();//指标值增加
  }
}

这里每5秒会自动执行changeCounter用于模拟数据的变化。

4.GaugeDemo

@RestController
public class GaugeDemo {
    /**指标注册
     * name设置指标名
     * labelNames设置各项指标名称
     * help设置指标描述
     */
    static final Gauge gaugeDemo = Gauge.build()
            .name("gaugeDemo")
            .labelNames("label1","label2","label3","label4","label5")
            .help("gauge 实例").register();

    //指标埋点
    @Scheduled(cron="0/5 * * * * ?")
    @RequestMapping("/changeGauge")
    public  void  changeGauge() {
        gaugeDemo.labels("1","2","3","4","5").inc(); //指标值加1
        gaugeDemo.labels("1","2","3","4","5").dec(); //指标值减一
        gaugeDemo.labels("1","2","3","4","5").set(19.00); //指标值直接赋值
    }
}

可以看到Gauge类型的metrics可以对数据进行增加、减小和直接赋值。这种类型在实际应用中比较多。

5.HistogramDemo

@RestController
public class HistogramDemo
{
    /**
     * 注册
     * 注册时buckets()设置区间值,如下设置了100、200、300三个区间值
     */
    static final Histogram histogramDemo = Histogram.build()
                                                    .labelNames("label1", "label2", "label3", "label4", "label5")
                                                    .name("histogramDemo")
                                                    .buckets(100, 200, 300)
                                                    .help("Histogram 实例")
                                                    .register();
    //指标埋点
    @Scheduled(cron = "0/5 * * * * ?") 
    public void changeHistogram()
    {
        /**
         * 本次执行的指标值
         * 如下设置为150,则每次执行,小于200区间以及小于300区间加1,小于100区间不变
         */
        histogramDemo.labels("1", "2", "3", "4", "5").observe(150);
    }
}

定义了三个区间,小于100,小于200,小于300,而changeHistogram中每次我们设置数据为150,所以最后画出来的曲线只有两条。

6.SummaryDemo

@RestController
public class SummaryDemo {
    //注册
    static final Summary summaryDemo = Summary.build()
            .quantile(0.5, 0.01)   // 添加50%分位数,允许有5%的误差,相当于求中位数
            .quantile(0.9, 0.01)   // 添加90%分位数,允许有1%的误差
            .name("summaryDemo").labelNames("label1","label2","label3","label4","label5")
            .help("Summary 实例").register();
    //指标埋点
    @Scheduled(cron="0/5 * * * * ?")
    public  void  changeSummary(){
        summaryDemo.labels("1","2","3","4","5").observe(1);
    }
}

在prometheus的Graph中通过查看summaryDemo、summaryDemo_count、summaryDemo_sum查看对应结果。

7.关于pushgateway

@Component
public class PrometheusConfig
{
    public static final Counter counterDemo = Counter.build()
                                                        .name("push_way_counter")
                                                        .labelNames("wy","zxjr","ocs","xxjf","unit","instance")
                                                        .help("Counter 实例")
                                                        .register();
    //测试发送
    public static void main(String[] args)
    {
        PushGateway prometheusPush = new PushGateway("localhost:9091");
        try
        {
            for(int i=0;i<50;i++){
                counterDemo.labels("网元","在线接入","OCS","消息计费","byte","localhsot:9091").inc();
                prometheusPush.push(counterDemo,"sp-getway");
                Thread.sleep(5000);
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

这里拿counter举一个简单的例子,其他三种度量也是一样的处理方式。

关于pushgateway中转数据,根据我自己实际的验证,我发现索然说数据每次都会先发送到pushgateway,但是prometheus去取的时候还是只取当前那一时间点的数据,并不会把历史的也拿过来,这让我很困惑,如果这样,他存的在意义是什么呢?不过也不确定是否因为我使用的不太对。

参考文献

【1】关于prometheus更详细的介绍

【2】更详细的介绍2

【3】关于metrics非常好的博文

【4】关于histogram_quantile的使用及Summary和Histogram对比

你可能感兴趣的:(Java,后端)