1.背景
prometheus是一个以神名为名的工具,有"先知先觉"的寓意。prometheus是一套开源的系统监控报警框架,十分符合它的定位。它启发于 Google 的 borgmon 监控系统,由工作在 SoundCloud 的 google 前员工在 2012 年创建,作为社区开源项目进行开发,并于 2015 年正式发布。prometheus,不是一个单一工具,它是由多个组件组合起来的工具。对刚刚开始学习的同学可以先看一下这边文章,让大家对prometheus有一个基本了解: https://www.cnblogs.com/linuxk/p/12017580.html(非常推荐)
2.基础架构
Prometheus 由多个组件组成,但是其中许多组件是可选的:
服务端:
- Prometheus Server:服务段组件,它是 Prometheus 核心组件,用于收集指标和存储时间序列数据,并提供查询接口。
- push gateway:网关组件,可以将它视为一个特殊 node_exporter 组件。主要用于临时性的 jobs。由于这类 jobs 存在时间较短,可能在 Prometheus 来 pull 之前就消失了。对此Jobs定时将指标push到pushgateway,再由Prometheus Server从Pushgateway上pull,根据业务需要可配置。
客户端:
- node_exporter:客户端收集器组件,用于暴露已有的第三方服务的 metrics(指标) 给 Prometheus。
- alertmanager:监控告警组件,从 Prometheus server 端接收到 alerts 后,会进行去除重复数据,分组,并路由到对收的接受方式,发出报警。常见的接收方式有:电子邮件,pagerduty,OpsGenie, webhook 等,根据业务需要可配置。
- Web UI:视图组件,Prometheus内置一个简单的Web控制台,可以查询指标,查看配置信息或者Service Discovery等,实际工作中,查看指标或者创建仪表盘通常使用Grafana,Prometheus作为Grafana的数据源,根据业务需要可配置。
- client Library:客户端服务(例如Go,Python,Java等),为需要监控的服务产生相应的/metrics并暴露给Prometheus Server。目前已经有很多的软件原生就支持Prometheus,提供/metrics,可以直接使用。对于像操作系统已经不提供/metrics,可以使用exporter,或者自己开发exporter来提供/metrics服务,根据业务需要可配置。
3.Prometheus获取指标方式
prometheus客户端主要由2种数据采集的方式:
pull(拉取形式):指的是客户端(被监控主机)先安装各类已有的exporters在系统上,exporters以守护进程的模式运行,并开始采集数据,exporters本身也是一个http_server,可以对http请求作出响应,并返回K/V数据,也就是metrics。prometheus通过用pull的方式(HTTP_GET)去访问每个节点上的exporter并采集回需要的数据。
push(推送的形式):指的是客户端(或服务端)安装官方的pushgateway插件,然后通过我们自行编写的各种脚本,将监控数据组织成K/V的形式(metrics形式)发送给pushgateway,而后pushgateway再推送给prometheus,这里需要注意的是pushgateway不一定要安装在被监控端,也可以安装在服务端,甚至是一台不相关的主机上,换句话来说,它只是一个中间转发的媒介。
4.执行流程
short_lived: 就是本地自定义脚本,它会定时将指标信息推送到pushgateway。感觉pushgateway就是一个特殊的node_exporter。具体使用方式:http://www.linuxe.cn/post-506.html
5.metrics指标类型
Counter: counter 是一个累积计数的指标,仅支持增加或者重置为0(只增不减 )。例如:可以用来统计服务请求的数量,任务完成数量,或者出错的数量。
Gauge: gauge是一个纯数值型的能够经常进行增加或者减少的指标。例如用来做温度的计数,内存的使用,同样也可以用来使用计算服务请求数量。
Histogram:直方图,histogram 在一段时间内进行采样,并能够对指定区间以及总数进行统计.
Summary: summary与histogram类似,用于表示一段时间内的采样数据,但它直接存储了分位数,而不是通过区间来计算。
6.埋点
spring-actuator做度量统计收集,使用Prometheus(普罗米修斯)进行数据收集,Grafana(增强ui)进行数据展示,用于监控生成环境机器的性能指标和业务数据指标。一般,我们叫这样的操作为”埋点”。SpringBoot中的依赖spring-actuator中集成的度量统计API使用的框架是Micrometer,官网是Micrometer.io。
1. 引入Prometheus metrics 包
<!-- https://mvnrepository.com/artifact/io.micrometer/micrometer-core -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
<version>1.6.6</version>
</dependency>
2. 以使用http client 为例。
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.DistributionSummary;
import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
/**
*
* @date 2021-04-29 2:59 下午
*/
public class Test3 {
private static final MeterRegistry registry = new SimpleMeterRegistry();
public static void main(String[] args) {
String[] tags = formattedTag(builderTag());
//折线图
new Test3().counter("HTTP_SUCCESS_COUNT","http请求成功次数",tags);
//折线图
new Test3().timer("RT",10000L,"http请求响应时间",tags);
//树状图
GaugeDemo gaugeDemo = new GaugeDemo();
gaugeDemo.setGaugeMetricsName("xxxx");
gaugeDemo.setMetrics(1);
new Test3().gauge("Memory_metrics_test",gaugeDemo,"内存变化指标",tags);
// 响应成功占比 : 饼状图
new Test3().summary("summary_http_success",0.98d,"响应成功占比",100,tags);
}
/**
* 使用者也可以自行继承MeterRegistry去实现自定义的MeterRegistry。SimpleMeterRegistry适合做调试的时候使用,它的简单使用方式如下
* @param name 指标key
* @param desc 基础单位
* @param tags 标签信息
* 折线图
*/
private void counter(String name,String desc,String... tags){
Counter counter = Counter.builder(name)
.description(desc)
//标签
.tags(tags)
//绑定的MeterRegistry
.register(registry);
//数值加一,原子操作
counter.increment();
}
/**
* 时间埋点
* @param name 指标key
* @param nanoSeconds 响应时间
* @param desc 描述
* @param tags 标签信息
* 折线图
*/
private void timer(String name,Long nanoSeconds,String desc,String... tags){
Timer timer = Timer.builder(name)
.description(desc)
//标签
.tags(tags)
//绑定的MeterRegistry
.register(registry);
//数值加一,原子操作
timer.record(nanoSeconds, TimeUnit.NANOSECONDS);
}
/**
* 数值埋点是个 Gauge, 可以用在查看某个场景单位时间内的变化的情形。
* 树状图
* @param name 指标key
* @param gaugeDemo 指标对象
* @param desc 指标描述信息
* @param tags 标签信息
*/
private void gauge(String name,GaugeDemo gaugeDemo,String desc,String... tags){
Gauge gauge = Gauge.builder(name,gaugeDemo,GaugeDemo::getMetrics)
.description(desc)
//标签
.tags(tags)
//绑定的MeterRegistry
.register(registry);
}
/**
* Summary(摘要)主要用于跟踪事件的分布,在Micrometer中,对应的类是DistributionSummary(分发摘要)。它的使用方式和Timer十分相似,但是它的记录值并不依赖于时间单位。
* 饼状图
* 例如: 某个指标的百分比
* @param name 指标key
* @param desc 描述信息
* @param scale 将记录到分布摘要的值乘以比例因子。 可配置
* @param tags 标签信息
* @param value 计算值
*/
private void summary(String name,double value,String desc ,double scale,String... tags ){
DistributionSummary summary = DistributionSummary
.builder(name)
.description(desc)
.tags(tags)
.scale(scale)
.register(registry);
summary.record(value);
}
private static class GaugeDemo{
/**
* 指标名
*/
private String gaugeMetricsName;
/**
* 度量指标
*/
private Integer metrics;
public String getGaugeMetricsName() {
return gaugeMetricsName;
}
public void setGaugeMetricsName(String gaugeMetricsName) {
this.gaugeMetricsName = gaugeMetricsName;
}
public Integer getMetrics() {
return metrics;
}
public void setMetrics(Integer metrics) {
this.metrics = metrics;
}
}
private static String[] formattedTag(Map<String,String> tag){
String[] result = new String[tag.size() * 2];
int i = 0;
for (Map.Entry<String, String> entry : tag.entrySet()){
result[i] = entry.getKey();
i++;
result[i] = entry.getValue();
i++;
}
return result;
}
private static Map<String,String> builderTag(){
/**
* 1、Tag的值必须不为null。
*
* 2、Micrometer中,Tag必须成对出现,也就是Tag必须设置为偶数个,实际上它们以Key=Value的形式存在
*/
HashMap<String, String> tags = new HashMap<>();
tags.put("url","wwww.baidu.com");
tags.put("code","200");
tags.put("method","POST");
return tags;
}
}
当然,还有其他类型,有其他扩展类型。就不一一举例了。
效果显示
我们的项目是基于spring cloud组件来处理的,我们可以通过访问这个地址就可以看到我们上报给prometheus的信息
http://服务ip:服务端口/actuator/prometheus
将会得到如下信息:
-- 描述信息: 请求响应时间 指标
# HELP fusion_http_response_time_seconds response.time
-- 统计的类型
# TYPE fusion_http_response_time_seconds summary
-- 指标key: RT ,{} 这个括号中的就是你写入的 tag 信息, 最后面一个是指标
RT{bizCode="0",endpoint="[GET]/actuator/health",method="GET",mode="servlet",status="200",type="",} 58331.0
7.Prometheus本地存储
TSDB
Prometheus本地储存使用它自己写的TSDB(时序数据库)
时序数据库全称为时间序列数据库。时间序列数据库主要用于指处理带时间标签(按照时间的顺序变化,即时间序列化)的数据,带时间标签的数据也称为时间序列数据。主要用于存储周期性的采集各种实时监控信息。
目录结构
./data
├── 01BKGV7JBM69T2G1BGBGM6KB12
│ └── meta.json
├── 01BKGTZQ1SYQJTR4PB43C8PD98
│ ├── chunks
│ │ └── 000001 │ ├── tombstones │ ├── index │ └── meta.json ├── 01BKGTZQ1HHWHV8FBJXW1Y3W0K │ └── meta.json ├── 01BKGV7JC0RY8A6MACW02A2PJD │ ├── chunks │ │ └── 000001 │ ├── tombstones │ ├── index │ └── meta.json └── wal ├── 00000002 └── checkpoint.00000
储存原理(write)
8.其他监控工具对比
引用
https://www.sohu.com/a/342733264_198222
https://www.cnblogs.com/linuxk/p/12017580.html
http://www.linuxe.cn/post-506.html
https://www.freesion.com/article/5362527244/
https://www.jianshu.com/p/a80cc630fa73