基础
Prometheus 是一个开源的完整监控解决方案,其对传统监控系统的测试和告警模型进行了彻底的颠覆,形成了基于中央化的规则计算、统一分析和告警的新模型,基于 Golang
编写。
优点
易于管理
Prometheus
基于 Pull
模型的架构方式,可以在任何地方(本地电脑,开发环境,测试环境)搭建我们的监控系统。对于一些复杂的情况,还可以使用 Prometheus
服务发现 (Service Discovery
) 能力动态管理监控目标。
强大的数据模型
所有采集的监控数据均以指标 metric
的形式保存在内置的时间序列数据库当中 TSDB
。所有的样本除了基本的指标名称以外,还包含一组用于描述该样本特征的标签。
如下所示:
1 | http_request_status{code='200',content_path='/api/path', environment='produment'} => [value1@timestamp1,value2@timestamp2...] |
每一条时间序列由指标名称 Metrics Name
以及一组标签 Labels
唯一标识。每条时间序列按照时间的先后顺序存储一系列的样本值。表示维度的标签可能来源于你的监控对象的状态,比如 code=404
或者 content_path=/api/path
。基于这些 Labels
,我们可以方便地对监控数据进行聚合、过滤、裁剪。
强大的查询语言 PromSQL
Prometheus
内置了一个强大的数据查询语言 PromQL
。 通过 PromQL
可以实现对监控数据的查询、聚合。同时 PromQL
也被应用于数据可视化(如 Grafana
)以及告警当中。
高效
对于监控系统而言,大量的监控任务必然导致有大量的数据产生。而Prometheus
可以高效地处理这些数据,对于单一 Prometheus Server
实例而言它可以处理:
- 数以百万的监控指标
- 每秒处理数十万的数据点
易于集成
Prometheus
社区还提供了大量第三方实现的监控数据采集支持:MySQL
、Consul
、Redis
等等。
可视化
Prometheus Server
中自带了一个 Prometheus UI
,通过这个 UI 可以方便地直接对数据进行查询,并且支持直接以图形化的形式展示数据。开源第三方可视化工具 Grafana
也已经提供了完整的 Prometheus
支持,基于 Grafana
可以创建更加精美的监控图标。
缺点:相比于 zabbix,更加消耗资源
架构
Prometheus Server:是 Prometheus
组件中的核心部分,负责实现对监控数据的获取、存储以及查询。
Prometheus Server
可以通过静态配置管理监控目标(prometheus.yml
),也可以配合使用Service Discovery
的方式动态管理监控目标,并从这些监控目标中获取数据。Prometheus Server
需要对采集到的监控数据进行存储,它本身就是一个时序数据库,将采集到的监控数据按照时间序列的方式存储在本地磁盘当中。Prometheus Server
对外提供了自定义的PromQL
语言,实现对数据的查询以及分析。
exporters:负责将监控数据采集的端点通过 HTTP
服务的形式暴露给 Prometheus Server
,Prometheus Server
通过访问该 exporter
提供的 Endpoint
端点,即可获取到需要采集的监控数据。一般来说可以将exporter
分为 2 类:
- 直接采集:这一类
exporter
直接内置了对Prometheus
监控的支持,例如:Kubernetes
。 - 间接采集:原有监控目标并不直接支持
Prometheus
,因此我们需要通过Prometheus
提供的Client Library
编写该监控目标的监控采集程序。例如:监控主机有 node_exporter,监控MySQL
有 mysqld_exporter。
Pushgateway:由于 Prometheus
数据采集基于 Pull
模型进行设计,因此在网络环境的配置上必须要让Prometheus Server
能够直接与 exporter
进行通信。 当这种网络需求无法直接满足时,就可以利用PushGateway
来进行中转。可以通过 PushGateway
将内部网络的监控数据主动 Push
到 Gateway
当中。而 Prometheus Server
则可以采用同样 Pull
的方式从 PushGateway
中获取到监控数据。
Alertmanager:在 Prometheus Server
中支持基于 PromQL
创建告警规则,如果满足 PromQL
定义的规则,则会产生一条告警,而告警的后续处理流程则由 AlertManager
进行管理。在 AlertManager
中我们可以与邮件,Slack
等等内置的通知方式进行集成,也可以通过 Webhook
自定义告警处理方式。AlertManager
即 Prometheus
体系中的告警处理中心。
Web UI:数据可视化,主要使用第三方工具 Grafana 来实现。
安装
Prometheus Server
二进制包方式安装
(1)下载最新版本 软件包
(2)解压
1 | wget https://github.com/prometheus/prometheus/releases/download/v2.12.0/prometheus-2.12.0.linux-amd64.tar.gz |
(3)配置文件 promethes.yml
,修改 job_name
。
1 | # my global config |
(4)创建数据存储目录,默认的存储路径为 data/
,用户也可以通过参数 --storage.tsdb.path="data/"
修改本地数据存储的路径。
1 | mkdir -p data |
(5)启动 prometheus
服务,http://10.133.0.53:9090
1 | $ ./prometheus |
docker 方式安装
直接使用 Prometheus
的镜像即可启动 Prometheus Server
。启动完成后,可以通过 http://10.133.0.53:9090 访问 UI
界面:
1 | docker run -p 9090:9090 -v /etc/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus |
node_exporter
采集主机的运行指标如 CPU、内存、磁盘等信息。同样采用 Golang
编写,并且不存在任何的第三方依赖。
1 | wget https://github.com/prometheus/node_exporter/releases/download/v0.18.1/node_exporter-0.18.1.linux-amd64.tar.gz |
启动成功后,可以看到如下输出:
1 | INFO[0000] Listening on :9100 source="node_exporter.go:170" |
访问 http://10.133.0.53:9100/metrics,可以看到采集到的监控数据:
1 | # HELP node_cpu Seconds the cpus spent in each mode. |
HELP:解释当前指标的含义。
TYPE:说明当前指标的数据类型。有四种数据类型,counter
(计数器)、gauge
(仪表盘)、histogram
(直方图)、summary
(求和)
除了这些之外,还可以看到如下监控指标:
- node_boot_time:系统启动时间
- node_cpu:系统
CPU
使用量 - node_disk_*:磁盘
IO
- node_filesystem_*:文件系统用量
- node_load1:系统负载
- node_memeory_*:内存使用量
- node_network_*:网络带宽
- node_time:当前系统时间
- go_*:
node_exporter
中go
相关指标 - process_*:
node_exporter
自身进程相关运行指标
mysqld_exporter
(1)下载二进制包
1 | wget https://github.com/prometheus/mysqld_exporter/releases/download/v0.12.1/mysqld_exporter-0.12.1.linux-amd64.tar.gz |
(2)编辑 .my.cnf
1 | [client] |
(3)启动 mysqld_exporter
,默认端口是 9104
,可以看到采集到的 MySQL Metrics。
1 | ./mysqld_exporter --config.my-cnf=/data/mysqld_exporter-0.12.1.linux-amd64/.my.cnf |
数据收集
为了能够让 Prometheus Server
能够从当前 node_exporter
获取到监控数据,这里需要修改 Prometheus
配置文件,编辑 prometheus.yml
并在 scrape_configs
节点下添加以下内容:
1 | scrape_configs: |
重新启动 Prometheus Server
,访问 http://10.133.0.53:9090,进入到 Prometheus Server
。如果输入 up
并且点击执行按钮以后,可以看到如下结果:
如果 Prometheus
能够正常从 node_exporter
获取数据,则会看到以下结果:
1 | up{instance="localhost:9090",job="prometheus"} 1 |
其中 "1"
表示正常,反之 "0"
则为异常。
数据模型
Prometheus
存储的是 时序数据,即按照相同时序(相同的名字和标签),以时间维度存储连续的数据的集合。时序(Time Series
)是由名字(Metric
),以及一组 key/value
标签定义的,具有相同的名字以及标签属于相同时序。时序的名字由 ASCII
字符、数字、下划线、以及冒号组成,它必须满足正则表达式 [a-zA-Z_:][a-zA-Z0-9_:]*
, 其名字应该具有语义化,一般表示一个可以度量的指标,例如: http_requests_total
, 可以表示 http
请求的总数。
时序的标签可以使 Prometheus
的数据更加丰富,能够区分具体不同的实例,例如 http_requests_total{method="POST"}
可以表示所有 Http
中的 POST
请求。标签名称由 ASCII
字符,数字,以及下划线组成, 其中 __
开头属于 Prometheus
保留,标签的值可以是任何 Unicode
字符,支持中文。
1 | <metric name>{<label name>=<label value>, ...} |
数据可视化
Prometheus UI
提供了快速验证 PromQL
以及临时可视化支持的能力,而在大多数场景下引入监控系统通常还需要构建可以长期使用的监控数据可视化面板( Dashboard )。这时用户可以考虑使用第三方的可视化工具如Grafana
,Grafana 是一个开源的可视化平台,并且提供了对 Prometheus
的完整支持。
安装 Grafana
(使用向导:安装 -> 添加数据源 -> 创建 Dashboard -> 邀请成员 -> 安装应用和插件)
1 | docker方式: |
访问 http://10.133.0.53:3000 就可以进入到 Grafana
的界面中,默认情况下使用账户 admin/admin
进行登录
任务和实例
在 Prometheus
中,每一个暴露监控样本数据的 HTTP
服务称为一个实例。例如在当前主机上运行的 node_exporter
可以被称为一个实例(Instance
)。
1 | scrape_configs: |
而一组用于相同采集目的的实例,或者同一个采集进程的多个副本则通过一个任务(Job
)进行管理。
1 | * job: node |
当前在每一个 Job
中主要使用了静态配置(static_configs
)的方式定义监控目标,Prometheus
还支持与 Consul
、Kubernetes
等进行集成实现自动发现实例,并从这些实例上获取监控数据。可以访问 targets 直接查看当前所有的任务以及每个任务对应的实例信息。
服务发现
Push vs Pull
如上所示,展示了 Push
系统和 Pull
系统的核心差异。相较于 Push
模式,Pull
模式的优点可以简单总结为以下几点:
- 只要
exporter
在运行,你可以在任何地方(比如在本地),搭建你的监控系统; - 你可以更容易的查看监控目标实例的健康状态,并且可以快速定位故障;
- 更利于构建
DevOps
文化的团队; - 松耦合的架构模式更适合于云原生的部署环境。
Consul
Consul:由 HashiCorp
开发的一个支持多数据中心的分布式服务发现和键值对存储服务的开源软件,被大量应用于基于微服务的软件架构当中,使用 Golang
语言开发。
安装
下载二进制包
与 Prometheus 集成
PromQL
PromQL(Prometheus Query Language
),是 Prometheus
自己开发的数据查询 DSL
语言,PromQL
作为Prometheus
的核心能力除了实现数据的对外查询和展现,同时告警监控也是依赖 PromQL
实现的。
时间序列
Prometheus 可以采集到当前主机所有监控指标的样本数据,例如:
1 | # HELP node_cpu Seconds the cpus spent in each mode. |
其中非 # 开头的每一行表示当前 node_exporter 采集到的一个监控样本:node_cpu 和 node_load1 表明了当前指标的名称、大括号中的标签则反映了当前样本的一些特征和维度、浮点数则是该监控样本的具体值。
样本
Prometheus 会将所有采集到的样本数据以时间序列(time-series)的方式保存在内存数据库中,并且定时保存到硬盘上。如下所示,可以将 time-series 理解为一个以时间为 Y 轴的数字矩阵:
1 | ^ |
在 time-series 中的每一个点称为一个样本(sample),样本由以下三部分组成:
- 指标 (metric):metric name 和描述当前样本特征的 label sets。
- 时间戳 (timestamp):一个精确到毫秒的时间戳。
- 样本值 (value): 一个 folat64 的浮点型数据表示当前样本的值。
1 | <--------------- metric ---------------------><-timestamp -><-value-> |
指标 (Metric)
在形式上,所有的指标 (Metric) 都通过如下格式标示:
1 | <metric name>{<label name>=<label value>, ...} |
指标名称(metric name):反映监控样本的含义。
标签(label):反映当前样本的特征维度。
指标类型:Counter(计数器)、Gauge(仪表盘)、Histogram(直方图)、Summary(摘要)
Counter:只增不减的计数器
Gauge:可增可减的仪表盘
使用 Histogram 和 Summary 分析数据分布情况