导语 :Prometheus是一个开源的完整监控解决方案,本文将从指标抓取到查询及可视化展示,以及最后的监控告警,对Prometheus做一个基本的认识。
Prometheus是古希腊神话里泰坦族的一名神明,名字的意思是“先见之明”,下图中是Prometheus被宙斯惩罚,饱受肝脏日食夜长之苦。
下面就是我们CRUD Boy所了解的Prometheus,下面是其官网封面图引导语:
From metrics to insight
,从指标到洞察力,通过指标去洞察你的系统,为我们的系统提供指标收集和监控的开源解决方案。
也就是说,Prometheus是一个数据监控的解决方案,让我们能随时掌握系统运行的状态,快速定位问题和排除故障。

Prometheus发展速度很快,12年开发完成,16年加入CNCF,成为继K8s 之后第二个CNCF托管的项目,目前Github 42k的🌟,而且社区很活跃,维护频率很高,基本稳定在1个月1个小版本的迭代速度。

Prometheus提供了从指标暴露,到指标抓取、存储和可视化,以及最后的监控告警等一系列组件。

每一个被Prometheus监控的服务都是一个Job,Prometheus为这些Job 提供了官方的SDK ,利用这个SDK可以自定义并导出自己的业务指标,也可以使用Prometheus官方提供的各种常用组件和中间件的Exporter(比如常用的MySQL,Consul等等)。
对于短时间执行的脚本任务或者不好直接 Pull指标的服务,Prometheus提供了PushGateWay网关给这些任务将服务指标主动推Push到网关,Prometheus再从这个网关里Pull指标。
上面提到了Push和Pull,其实这是两种指标抓取模型。

被监控服务一般通过主动暴露
metrics
端口或者通过
Exporter
的方式暴露指标,监控服务依赖服务发现模块发现被监控服务,从而去定期的抓取指标。

对于
Prometheus中的指标抓取,采用的是Pull模型,默认是一分钟去拉取一次指标,通过
Prometheus.yaml配置文件中的
scrape_interval配置项配置,
Prometheus对外都是用的Pull模型,一个是
Pull Exporter的暴露的指标,一个是
Pull PushGateway暴露的指标。
指标抓取后会存储在内置的时序数据库中,
Prometheus也提供了PromQL 查询语言给我们做指标的查询,我们可以在
Prometheus的WebUI上通过
PromQL,可视化查询我们的指标,也可以很方便的接入第三方的可视化工具,例如
grafana。
prometheus提供了
alertmanageer基于promql来做系统的监控告警,当promql查询出来的指标超过我们定义的阈值时,
prometheus会发送一条告警信息到
alertmanager,manager会将告警下发到配置好的邮箱或者微信。
Prometheus的从被监控服务的注册到指标抓取到指标查询的流程分为五个步骤:

被监控服务在
Prometheus中是一个Job存在,被监控服务的所有实例在
Prometheus中是一个target的存在,所以被监控服务的注册就是在
Prometheus中注册一个Job和其所有的target,这个注册分为:
静态注册和动态注册。
静态注册: 静态的将服务的IP和抓取指标的端口号配置在
Prometheus yaml文件的
scrape_configs配置下:
以上就是注册了一个名为
prometheus
的服务,这个服务下有一个实例,暴露的抓取地址是
localhost:9090
。
动态注册: 动态注册就是在
Prometheus yaml文件的
scrape_configs配置下配置服务发现的地址和服务名,
Prometheus会去该地址,根据你提供的服务名动态发现实例列表,在
Prometheus中,支持consul,DNS,文件,K8s等多种服务发现机制。基于consul的服务发现:
我们consul的地址就是:
localhost:8500
,服务名是
node_exporter
,在这个服务下有一个
exporter
实例:
localhost:9600
。

注意:如果是动态注册,最好加上这两配置,静态注册指标拉取的路径会默认的帮我们指定为
metrics_path:/metrics,所以如果暴露的指标抓取路径不同或者是动态的服务注册,最好加上这两个配置。
不然会报错
“INVALID“ is not a valid start token,演示下,百度了一下,这里可能是数据格式不统一导致。
最后可以在webUI中查看发现的实例:

目前,
Prometheus
支持多达二十多种服务发现协议:

在更新完
Prometheus的配置文件后,我们需要更新我们的配置到程序内存里,这里的更新方式有两种,第一种简单粗暴,就是重启
Prometheus,第二种是动态更新的方式。如何实现动态的更新Prometheus配置。
第一步:首先要保证启动
Prometheus的时候带上启动参数:
--web.enable-lifecycle
第二步:去更新我们的
Prometheus
配置:
第三步:更新完配置后,我们可以通过Post请求的方式,动态更新配置:
原理:
Prometheus在web模块中,注册了一个
handler:
通过
h.reload
这个
handler
方法实现:这个
handler
就是往一个
channle
中发送一个信号:

在main函数中会去监听这个channel,只要有监听到信号,就会做配置的reload,重新将新配置加载到内存中。

Prometheus对指标的抓取采取主动Pull的方式,即周期性的请求被监控服务暴露的
metrics接口或者是
PushGateway,从而获取到
Metrics指标,默认时间是15s抓取一次,配置项如下:
抓取到的指标会被以时间序列的形式保存在内存中,并且定时刷到磁盘上,默认是两个小时回刷一次。并且为了防止
Prometheus
发生崩溃或重启时能够恢复数据,
Prometheus
也提供了类似MySQL中binlog一样的预写日志,当
Prometheus
崩溃重启时,会读这个预写日志来恢复数据。

Prometheus采集的所有指标都是以时间序列的形式进行存储,每一个时间序列有三部分组成:
指标名和指标标签集合:
metric_name{<label1=v1>,<label2=v2>....},指标名:表示这个指标是监控哪一方面的状态,比如
http_request_total表示:请求数量;指标标签,描述这个指标有哪些维度,比如
http_request_total这个指标,有请求状态码
code= 200/400/500,请求方式:
method=get/post等,实际上指标名称实际上是以标签的形式保存,这个标签是name,即:
name=。
时间戳:描述当前时间序列的时间,单位:毫秒。
样本值:当前监控指标的具体数值,比如
http_request_total的值就是请求数是多少。
可以通过查看
Prometheus的
metrics接口查看所有上报的指标:

所有的指标也都是通过如下所示的格式来标识的:

Prometheus底层存储上其实并没有对指标做类型的区分,都是以时间序列的形式存储,但是为了方便用户的使用和理解不同监控指标之间的差异,
Prometheus定义了4种不同的指标类型:计数器
counter,仪表盘
gauge,直方图
histogram,摘要
summary。

Counter类型和redis的自增命令一样,只增不减,通过Counter指标可以统计Http请求数量,请求错误数,接口调用次数等单调递增的数据。同时可以结合
increase和rate等函数统计变化速率,后续我们会提到这些内置函数。

和
Counter不同,Gauge是可增可减的,可以反映一些动态变化的数据,例如当前内存占用,CPU利用,Gc次数等动态可上升可下降的数据,在
Prometheus上通过Gauge,可以不用经过内置函数直观的反映数据的变化情况,如下图表示堆可分配的空间大小:

上面两种是数值指标,代表数据的变化情况,
Histogram和
Summary是统计类型的指标,表示数据的分布情况。
Histogram是一种直方图类型,可以观察到指标在各个不同的区间范围的分布情况,如下图所示:可以观察到请求耗时在各个桶的分布。

有一点要注意的是,
Histogram是累计直方图,即每一个桶的是只有上区间,例如下图表示小于0.1毫秒(
le=“0.1”)的请求数量是18173个,小于 0.2毫秒(
le=“0.2”)的请求是
18182 个,在
le=“0.2”这个桶中是包含了
le=“0.1”这个桶的数据,如果我们要拿到0.1毫秒到0.2毫秒的请求数量,可以通过两个桶想减得到。
在直方图中,还可以通过
histogram_quantile
函数求出百分位数,比如 P50,P90,P99等数据。
Summary也是用来做统计分析的,和
Histogram区别在于,
Summary直接存储的就是百分位数,如下所示:可以直观的观察到样本的中位数,P90和P99。
Summary
的百分位数是客户端计算好直接让
Prometheus
抓取的,不需要
Prometheus
计算,直方图是通过内置函数
histogram_quantile
在
Prometheus
服务端计算求出。
指标导出有两种方式,一种是使用
Prometheus社区提供的定制好的
Exporter对一些组件诸如MySQL,Kafka等的指标作导出,也可以利用社区提供的
Client来自定义指标导出。

自定义
Prometheus exporter:
访问:,
即可看到导出的指标,这里我们没有自定义任何的指标,但是能看到一些内置的Go的运行时指标和promhttp相关的指标,这个Client默认为我们暴露的指标,
go_
:以
go_
为前缀的指标是关于Go运行时相关的指标,比如垃圾回收时间、
goroutine
数量等,这些都是Go客户端库特有的,其他语言的客户端库可能会暴露各自语言的其他运行时指标。
promhttp_
:来自
promhttp
工具包的相关指标,用于跟踪对指标请求的处理。

添加自定义指标:

运行:

模拟下在业务中上报接口请求量:
main.go:
一开始启动时,指标counter是0:

调用:
/counter
接口后,指标数据发生了变化,这样就可以简单实现了接口请求数的统计:

对于其他指标定义方式是一样的:

上面的指标都是没有设置标签的,我们一般的指标都是带有标签的,如何设置指标的标签呢?
如果我要设置带标签的counter类型指标,只需要将原来的
NewCounter方法替换为
NewCounterVec方法即可,并且传入标签集合。


其他同理。
来自 “ 腾讯云开发者 ”, 原文作者:kevinkrcai ;原文链接:https://mp.weixin.qq.com/s/pZQDkDw5Uk9bEnNcol0CkA,如有侵权,请联系管理员删除。