ljzsdut
GitHubToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage

001 Prometheus入门概述

Prometheus是一个开源的系统监视和警报工具包,自2012成立以来,许多公司和组织采用了Prometheus。它现在是一个独立的开源项目,并独立于任何公司维护。在2016年,Prometheus加入云计算基金会作为Kubernetes之后的第二托管项目。

首先,Prometheus是一款时序(time series) 数据库;但它的功能却并非止步于TSDB,而是一款设计用于进行目标(Target)监控的关键组件;结合生态系统内的其它组件,例如Pushgateway、Altermanager和Grafana等,可构成个完整的IT监控系统;

在Prometheus术语中,它所监控的事物称为目标(Target)。每个目标单元被称为指标(metric)。它以设置好的时间间隔通过http抓取目标,以收集指标并将数据放置在其时序数据库(Time Series Database)中。你可以使用PromQL查询语言查询相关target的指标。

Prometheus特点

  • 多维数据模型(由metric名称和k/v格式的标签确定的时间序列,每个独立的标签组合都代表一个时间序列)
  • 灵活的查询语言(PromQL,支持聚合、切割、切片)
  • 不依赖分布式存储

Prometheus本身就是一个时序数据库,自己可以完成数据的存储,数据存储于本地磁盘。但是如果要长时间存储数据,可以借助influxDB等外置的存储系统。

  • 通过Pull方式采集时间序列,基于HTTP请求,从配置文件中指定的网络端点(endpoint或target或instance,通常格式为IP:PORT)上周期性获取指标数据

Prometheus采集数据是用的Pull模型,也就是拉模型,通过HTTP协议去采集指标,只要应用系统能够提供HTTP接口就可以接入监控系统,相比于私有协议或二进制协议来说开发、简单。

  • 支持通过中介网关(PushGateway)的Push时间序列的方式

对于定时任务这种短周期的指标采集,如果采用Pull模式,可能造成任务结束了,Prometheus还没有来得及采集,这个时候可以使用加一个中转层,客户端推数据到PushGateway缓存一下,由Prometheus从push gateway pull指标过来。(需要额外搭建Push Gateway,同时需要新增job去从gateway采数据)

  • 监控数据通过服务发现或者静态配置来发现
  • 支持图表和dashboard等多种方式

架构图

prometheus-topology

Prometheus生态圈中包含了多个组件,其中部分组件可选

  • Prometheus Server:收集和存储时间序列数据;
  • Client Library:客户端库,目的在于为那些期望原生提供Instrumentation功能的应用程序提供便捷的开发途径(应用内置/metrics接口);
  • Push Gateway:接收那些通常由短期作业生成的指标数据的网关,并支持由PrometheusServer进行指标拉取操作;
  • Exporters:用于暴露现有应用程序或服务(不支持Instrumentation)的指标给PrometheusServer;
  • Alertmanager:从Prometheus Server接收到“告警通知”后,通过去重、分组、路由等预处理功能后以高效向用户完成告警信息发送;
  • Data Visualization : Prometheus Web UI (Prometheus Servet内建),及Grafana等;
  • Service Discovery:动态发现待监控的Target,从而完成监控配置的重要组件,在容器化环境中尤为有用;该组件目前由Prometheus Server内建支持;

组件

Prometheus主程序

主要是负责抓取、存储、聚合、查询方面。

Prometheus就是一个用Go编写的时序数据库,时序数据库简单来说就是存储随时间变化的数据的数据库。

什么是随时间变化的数据(时序数据)呢?

时序数据,是在一段时间内通过重复测量(measurement)而获得的观测值的集合;将这些观测值绘制于图形之上,它会有一个数据轴和一个时间轴;服务器指标数据、应用程序性能监控数据、网络数据等也都是时序数据;举个简单的例子,比如,CPU使用率,典型的随时间变化的量,这一秒是50%,下一秒也许就是80%了。或者是温度,今天是20度,明天可能就是18度了。

image-20210520084159683

探针程序与Pushgateway

Prometheus支持通过三种类型的途径从目标上“抓取(Scrape)”指标数据;

image-20220115211921723

1、Exporters:*_exporter 提供数据采集的接口,一般适用于应用程序自身无法提供metric的程序,或者一些比较通用的中间件

  • Node/system metrics exporter
  • AWS CloudWatch exporter
  • Blackbox exporter
  • Collectd exporter
  • Consul exporter
  • Graphite exporter
  • HAProxy exporter
  • InfluxDB exporter
  • JMX exporter
  • Memcached exporter
  • Mesos task exporter
  • MySQL server exporter
  • SNMP exporter
  • StatsD exporter

2、Instrumentation:应用本身内置提供的支持Prometheus数据模型的采集接口。

3、Pushgateway程序:主要是实现接收由Client push过来的指标数据,将这些metric暂时缓存起了,在指定的时间间隔,由主程序Prometheus Server来抓取。 适用于部分push场景 ,例如临时性Job主动推送指标的中间网关。(若server采集间隔期间,pushgateway上的数据没有变化,server将采集2次相同数据,仅时间戳不同)

Alertmanager程序

主要是负责实现报警功能。Prometheus告警插件,支持发送告警到邮件,Pagerduty,HipChat等。

Service discovery:

支持根据配置file_sd监控本地配置文件的方式实现服务发现,同时支持配置监听Kubernetes的API来动态发现服务。

关键工作流程

工作流程概述

  • Prometheus server定期从配置好的 jobs 中获取度量数据;
  • Prometheus server在本地存储收集到的度量数据,并对这些数据进行聚合;
  • 运行已定义好的 alert.rules,记录新的时间序列或者向告警管理器推送警报。
  • 告警管理器根据配置文件,对接收到的警报进行处理,并通过email等途径发出告警。
  • Grafana等图形工具获取到监控数据,并以图形化的方式进行展示。

Prometheus数据采集流程

在Prometheus server中配置探针暴露的端口地址以及采集的间隔时间,Prometheus按配置的时间间隔通过http的方式去访问探针,这时探针通过调用接口的方式获取监控数据并对应指标返回给Prometheus server进行存储。(若探针在Prometheus配置的采集间隔时间内没有完成采集数据,这部分数据就会丢失)

Prometheus Server获取数据的策略是Pull而不是Push,也就是说,它会自己去抓取,而不用你来推送。抓取使用的是HTTP协议,在配置文件中指定目标程序的端口,路径及间隔时间即可。这也就意味着任何程序想要使用Prometheus存储数据都很简单,定义一个HTTP接口即可。Prometheus的数据格式是简单的文本格式,可以直接阅读。

数据示例

#号开头的是注释,除此之外,每一行一个数据项,数据名在前,值在后。{}中是标签,标签可以省略,一条数据可以有多个标签。

# HELP go_gc_duration_seconds A summary of the GC invocation durations.
# TYPE go_gc_duration_seconds summary
http_request_count{endpoint="/a"} 10
http_request_count{endpoint="/b"} 200
http_request_count(endpoint="/c") 3

如何根据采集到的监控数据配和alertmanager完成告警?

举一个常见的告警示例,在主机可用内存低于总内存的20%时发送告警。我们可以根据Prometheus server采集的主机性能指标配置这样一条规则:node_memory_Active/node_memory_MemTotal < 0.2,Prometheus server分析采集到的数据,当满足该条件时,发送告警信息到alertmanager,alertmanager根据本地配置处理告警信息并发送到第三方工具由相关的负责人接收。

Prometheus抓取到异常值后,支持通过“告警(Alert)”机制向用户发送反馈或警示,以触发用户能够及时采取应对措施;

Prometheus server在这里主要负责根据告警规则分析数据并发送告警信息到alertmanager,alertmanager则是根据配置处理告警信息并发送。

Prometheus Server仅负责生成告警指示,具体的告警行为由另一个独立的应用程序AlertManager负责;

  • 告警指示由Prometheus Server基于用户提供的“告警规则”周期性计算生成;
  • Alertmanager接收到Prometheus Server发来的告警指示后,基于用户定义的告警路由(route)向告警接收人(receivers)发送告警信息;

79bcfd58921743441d7e0a8b416244889ca.jpg

Alertmanager又有哪些处理告警信息的方式呢?

  1. 分组:将监控目标相同的告警进行分组。如发生停电,收到的应该是单一信息,信息中包含所有受影响宕机的机器,而不是针对每台宕机的机器都发送一条告警信息。
  2. 抑制:抑制是指当告警发出后,停止发送由此告警引发的其他告警的机制。如机器网络不可达,就不再发送因网络问题造成的其他告警。
  3. 沉默:根据定义的规则过滤告警信息,匹配的告警信息不会发送。

服务发现

6391bb46abd1d10c7f207f5f7b0033f57b0.jpg

Prometheus支持多种服务发现的方式,这里主要介绍架构图中提到的file_sd的方式。之前提到Prometheus server的数据采集配置都是通过配置文件,那服务发现该怎么做?总不能每次要添加采集目标还要修改配置文件并重启服务吧。

这里使用file_sd_configs指定定义了采集目标的文件。Prometheus server会动态检测该配置文件的变化来更新采集目标信息。现在只要能更新这个配置文件就能动态的修改采集目标的配置了。

如果采用consul+consul template的方式。在新增或减少探针(增减采集目标)时在consul更新k/v,如新增一个探针,添加如下记录Prometheus/linux/node/10.15.15.132=10.15.15.132:9100,然后配置consul template监控consul的Prometheus/linux/node/目录下k/v的变化,根据k/v的值以及提前定义的discovery.ctmpl模板动态生成Prometheus server的配置文件discovery.yml。

联邦模式

eb315bdf3d6fe89950693d4ec1283f1e283.jpg

中心化的数据采集存储,分析,而且还不支持集群模式。带来的性能问题显而易见。Prometheus给出了一种联邦的部署方式,就是Prometheus server可以从其他的Prometheus server采集数据。

可能有人会问,这样最后的数据不是还是要全部汇集到Prometheus的global节点吗?

并不是这样的,我们可以在shard节点就完成分析处理,然后global节点直接采集分析处理过的数据进行展示。

比如在shard节点定义指标可用内存占比job:memory_available:proportion的结果为(node_memory_MemFree + node_memory_Buffers + node_memory_Cached)/node_memory_MemTotal,这样在shard节点就可以完成聚合操作,然后global节点直接采集处理过的数据就可以了,而不用采集零散的如node_memory_MemFree这类指标。

联邦模式