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