Prometheus+ Grafana监控实战


一、 Prometheus

Prometheus是由SoundCloud开发的开源监控报警系统和时序列数据库(TSDB)。Prometheus使用Go语言开发,是Google BorgMon监控系统的开源版本。

2016年由Google发起Linux基金会旗下的原生云基金会(Cloud Native Computing Foundation), 将Prometheus纳入其下第二大开源项目。

1.1 Prometheus的特点

  • go语言实现
  • 多维度数据模型
  • 灵活的查询语言
  • 不依赖分布式存储,单个服务器节点是自主的
  • 通过基于HTTP的pull方式采集时序数据
  • 可以通过中间网关进行时序列数据推送
  • 通过服务发现或者静态配置来发现目标服务对象
  • 黑盒 白盒支持
  • 支持多种多样的图表和界面展示,比如Grafana等

1.2 安装配置Prometheus

prometheus下载地址 https://prometheus.io/download/ 。
根据自己的操作系统下载合适版本的文件,下载完毕将压缩包解压:

直接执行prometheus.exe,prometheus服务就跑起来了。或者在根据不同的配置文件来启动Prometheus,Prometheus的配置文件是YAML格式,当我们运行prometheus二进制文件(windows是prometheus.exe可执行文件)时,我们通过参数可指定一个配置文件。

./prometheus --config.file=prometheus.yml

这是我的配置

# my global config
global:
  scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
  # scrape_timeout is set to the global default (10s).

# Alertmanager configuration
alerting:
  alertmanagers:
    - static_configs:
        - targets:
          # - alertmanager:9093

# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
  # - "first_rules.yml"
  # - "second_rules.yml"

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
  # The job name is added as a label `job=` to any timeseries scraped from this config.
  - job_name: "prometheus"

    # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.

    static_configs:
      - targets: ["localhost:9090"]
      
  - job_name: "test"

    # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.
    metrics_path: '/actuator/prometheus'

    static_configs:
      - targets: ["localhost:8080"]

启动成功后,通过浏览器进入http://localhost:9090/ ,可以得到,

执行up命令,可以得到监控的实例

Prometheus 通过默认 http://localhost:9090/metrics* HTTP接口暴露了自己的性能指标数据,当然也就可以配置抓取目标 targets 为自己了。
通过浏览器进入http://localhost:9090/metrics , 可以看到性能指标数据:

二、 Grafana

prometheus自带的图形功能比较弱,这里使用Grafana读取prometheus数据做可视化。

2.1 Grafana介绍

Grafana是一个跨平台的开源的度量分析和可视化工具,可以通过将采集的数据查询然后可视化的展示,并及时通知。它主要有以下六大特点:

  • 展示方式:快速灵活的客户端图表,面板插件有许多不同方式的可视化指标和日志,官方库中具有丰富的仪表盘插件,比如热图、折线图、图表等多种展示方式;

  • 数据源:Graphite,InfluxDB,OpenTSDB,Prometheus,Elasticsearch,CloudWatch和KairosDB等;

  • 通知提醒:以可视方式定义最重要指标的警报规则,Grafana将不断计算并发送通知,在数据达到阈值时通过Slack、PagerDuty等获得通知;

  • 混合展示:在同一图表中混合使用不同的数据源,可以基于每个查询指定数据源,甚至自定义数据源;

  • 注释:使用来自不同数据源的丰富事件注释图表,将鼠标悬停在事件上会显示完整的事件元数据和标记;

  • 过滤器:Ad-hoc过滤器允许动态创建新的键/值过滤器,这些过滤器会自动应用于使用该数据源的所有查询。

2.2 Grafana安装

根据自己的系统版本和配置,到官网下载对应的包 https://grafana.com/grafana/download,
官方提供了如下说明,可直接按照说明进行下载安装,安装得到下列文件:

进入目录 conf 下,然后复制一个 sample.ini 文件,重命名为 custom.ini ,最后编辑 custom.ini 配置。端口默认为3000,可以根据自己的喜好配置。

# The http port  to use
http_port = 3000

最后点击 bin 目录下的 grafana-server.exe 程序,打开服务,启动时 windows 权限会提示,杀毒软件也会阻止,需同意允许。
http://localhost:3000

2.3 Grafana实验

创一个prometheus的数据源

创建dashboad, prometheus_http_request_duration_seconds_bucket

三、micrometer

Micrometer是基于JVM的应用程序的metrics 工具库。它为最流行的监控系统的仪器客户端提供了一个简单的外观,使您无需锁定供应商即可测试基于JVM的应用程序代码。它旨在为您的指标收集活动增加很少或没有开销,同时最大限度地提高指标工作的可移植性。

Micrometer 为 Java 平台上的性能数据收集提供了一个通用的 API,它提供了多种度量指标类型(Timers、Guauges、Counters等),同时支持接入不同的监控系统,例如 Influxdb、Graphite、Prometheus 等。我们可以通过 Micrometer 收集 Java 性能数据,配合 Prometheus 监控系统实时获取数据,并最终在 Grafana 上展示出来,从而很容易实现应用的监控。

https://micrometer.io/官网
在springboot项目中引入micrometer依赖

        
            org.springframework.boot
            spring-boot-starter-actuator
                


        
            io.micrometer
            micrometer-core
            1.2.1
        

        
        
            io.github.mweirauch
            micrometer-jvm-extras
            0.2.2
        

配置



spring.application.name=test
management.endpoints.web.exposure.include=*
management.endpoints.web.exposure.exclude = env, beans
management.metrics.tags.application=${spring.application.name}

management.endpoint.shutdown.enabled=true
management.metrics.export.simple.enabled=false

info.author=xingzhouQAQ
info.mobile=Xiaomi

初始化监控数据

package com.imooc.springboot.prometheus.metrics;

import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.binder.MeterBinder;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class MetricsBinder implements MeterBinder {
    public Counter counter1;
    public Counter counter2;
    public Map map;

    public MetricsBinder() {
        map = new ConcurrentHashMap<>();
    }

    @Override
    public void bindTo(MeterRegistry meterRegistry) {
        this.counter1 = Counter.
                builder("PrometheusApplication.demo.counter").
                tags(new String[]{"name", "counter1"}).
                description("This is the first counter").
                register(meterRegistry);

        this.counter2 = Counter.
                builder("PrometheusApplication.demo.counter").
                tags(new String[]{"name", "counter2"}).
                description("This is the second counter").
                register(meterRegistry);

        Gauge.builder("PrometheusApplication.demo.gauge", map, x -> x.get("x"))
                .tags("name", "gauge1")
                .description("This is a gauge")
                .register(meterRegistry);
    }
}

开启定时任务

package com.imooc.springboot.prometheus.metrics;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class ScheduledTask {
    @Autowired
    MetricsBinder metricsBinder;

    private int count1;
    private int count2;


    @Scheduled(fixedRate = 1000)
    public void increment1() {
        count1++;
        metricsBinder.counter1.increment();
        metricsBinder.map.put("x", Double.valueOf(count1));
        System.out.println("increment 1 count: " + count1);
    }

    @Scheduled(fixedRate = 10000)
    public void increment2() {
        count2++;
        metricsBinder.counter2.increment();
        metricsBinder.map.put("x", Double.valueOf(count2));
        System.out.println("increment 2 count: " + count2);
    }
}

使能定时任务

package com.imooc.springboot.prometheus;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class PrometheusApplication {

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

}

启动springboot项目,可以在控制台看到

在浏览器输入http://localhost:8080/actuator, 可以看到分级目录:

访问链接 http://localhost:8080/actuator/prometheus,得到prometheus的数据源

通过grafana进行展示,可以得到:

参考:https://www.imooc.com/learn/1231 龙猪GG 《使用Prometheus实践基于Spring Boot监控告警体系》