Prometheus监控系统
一、Prometheus简介
1.1 什么是Prometheus?
Prometheus是由前 Google 工程师从2012 年开始在Soundcloud以开源软件的形式进行研发的系统监控和告警工具包,自此以后,许多公司和组织都采用Prometheus 作为监控告警工具。Prometheus的开发者和用户社区非常活跃,它现在是一个独立的开源项目,可以独立于任何公司进行维护。为了证明这一点,Prometheus 于 2016 年 5 月加入CNCF基金会,成为继 Kubernetes 之后的第二个 CNCF 托管项目。
1.2 Prometheus的优势
Prometheus 的主要优势有:
- 由指标名称和和键/值对标签标识的时间序列数据组成的多维数据模型
- 强大的查询语言 PromQL
- 不依赖分布式存储;单个服务节点具有自治能力。
- 时间序列数据是服务端通过 HTTP 协议主动拉取获得的。
- 也可以通过中间网关来推送时间序列数据
- 可以通过静态配置文件或服务发现来获取监控目标。
- 支持多种类型的图表和仪表盘。
1.3 Prometheus的组件、架构
Prometheus 的整体架构以及生态系统组件如下图所示:
Prometheus Server 直接从监控目标中或者间接通过推送网关来拉取监控指标,它在本地存储所有抓取到的样本数据,并对此数据执行一系列规则,以汇总和记录现有数据的新时间序列或生成告警。可以通过 Grafana或者其他工具来实现监控数据的可视化
-
Prometheus server是Prometheus架构中的核心组件,基于go语言编写而成,无第三方依赖关系,可以独立部署在物理服务器上、云主机、Docker容器内。主要用于收集每个目标数据,并存储为时间序列数据,对外可提供数据查询支持和告警规则配置管理。 Prometheus服务器可以对监控目标进行静态配置管理或者动态配置管理,它将监控采集到的数据按照时间序列存储在本地磁盘的时序数据库中(当然也支持远程存储),自身对外提供了自定义的PromQL语言,可以对数据进行查询和分析 -
Client Library是用于检测应用程序代码的客户端库。在监控服务之前,需要向客户端库代码添加检测,从而事先Prometheus中metric的类型。 -
Exporter:用于输出被监控组件信息的HTTP接口统称为Exporter(导出器)。目前互联网公司常用的组件大部分都有Expoter供直接使用,比如Nginx、MySQL、linux系统信息等。 -
Pushgateway是指用于支持短期临时或批量计划任务工作的汇聚节点。主要用于短期的job,此类存在的job时间较短,可能在Prometheus来pull之前就自动消失了。所以针对这类job,设计成可以直接向Pushgateway推送metric,这样Prometheus服务器端便可以定时去Pushgateway拉去metric -
Alertmanager 主要用于处理Prometheus服务器端发送的alerts信息,对其去除重数据、分组并路由到正确的接收方式,发出告警,支持丰富的告警方式。 -
Service Discovery:动态发现待监控的target,从而完成监控配置的重要组件,在容器环境中尤为重要,该组件目前由Prometheus Server内件支持
1.4 Prometheus适用于什么场景
- Prometheus适用于记录文本格式的时间序列,它既适用于以机器为中心的监控,也适用于高度动态的
面向服务的监控,在微服务的世界中,它对多维数据收集和查询的支持有特殊优势。 - Prometheus是专为提高系统可靠性而设计的,它可以在断电期间快速诊断问题,每个Prometheus Server都是相互独立的,不依赖于网络存储或者其他远程服务。
- 当基础架构出现问题时,你可以通过Prometheus快速定位故障点,而且不会消耗大量的基础架构资源。
1.5 Prometheus不适合什么场景
Prometheus非常重视可靠性,即使在出现故障的情况下,你也可以随时统计有关系统的可用系统信 息。如果你需要百分之百的准确度,例如按请求数量计费,那么Prometheus可能不太适合你,因为它 收集的数据可能不够详细完整精确。
二、相关概念
2.1 数据模型
Prometheus所有采集的监控数据均以指标的形式保存在内置的时间序列数据库当中(TSDB):属于同 一指标名称、同一标签集合的、有时间戳标记的数据流。
除了存储的时间序列,Prometheus还可以根据查询请求产生临时的、衍生的时间序列作为返回结果。
2.2 指标名称和标签
- 每一条时间序列由指标名称(Metric Name)以及一组标签(键值对)唯一标识。
- 其中指标的名称(Metric Name)可以反映被监控样本的含义(例如,http_request_total可以看出来表示当前系统接收到的http请求总量)
- 指标名称只能由ASCII字符、数字、下划线以及冒号组成,同时必须匹配正则表达式 [a-zA-Z_:][a-zA-Z0-9_:]* 。
注意
-
冒号用来表示用户自定义的记录规则,不能在 exporter 中或监控对象直接暴露的指标中使用冒号来定义 指标名称。 -
通过使用标签,Prometheus开启了强大的多维数据模型:对于相同的指标名称,通过不同标签列表的 集合,会形成特定的度量维度实例(例如,所有包含度量名称为 /api/tracks 的 http 请求,打上 method=POST 的标签,就会形成具体的 http 请求)。查询语言在这些指标和标签列表的基础上进行过 滤和聚合,改变任何度量指标上的任何标签值(包括添加或删除指标),都会创建新的时间序列。 -
标签的名称只能由ASCII字符、数字、以及下划线组成并满足正则表达式 [a-zA-Z_][a-zA-Z0-9_]* 。其中 以 __ 作为前缀的标签,是系统保留的关键字,只能在系统内部使用。标签的值则可以包含任何 Unicode 编码的字符。
2.3 样本
在时间序列中的每一个点称为样本,样本由以下三部分组成:
- 指标(metric):指标名称和描述当前样本特征的labelset(标签集合);
- 时间戳:一个精确到时间毫秒的时间戳
- 样本值:一个浮点型数据表示当前样本的值
2.4 表示方式
通过如下表示方式表示指定名称和指定标签集合的时间序列
<metric name>{<label name>=<label value>, ...}
例如,指标名称为 api_http_requests_total ,标签为 method=“POST” 和 handler="/messages"的时间序列可以表示为:
api_http_requests_total{method="POST",handler="/messages"}
三、指标类型
Prometheus的客户端库中提供了四种核心的指标类型。但这些类型只是在客户端库(客户端可以根据不同的数据类型调用不同的api接口)和在线协议中
实际在Prometheus Server中并不对指标类型进行区分,而是简单地把这些指标统一视为无类型的时间序列
3.1 Counter计数器
Counter类型代表一种样本数据单调递增的指标,即只增不减,除非监控系统发生了重置。例如,你可以使用counter类型的指标表示服务请求总数、已经完成的任务数、错误发生的次数等。 counter类型数据可以让用户方便的了解事件发生的速率的变化,在PromQL内置的相关操作函数可以提供相应的分析,比如HTTP应用请求量来进行说明:
// 通过rate()函数获取HTTP请求量的增长率
rate(http_requests_total[5m])
// 查询当前系统中,访问量前10的HTTP地址
topk(10, http_requests_total)
3.2 Gauge仪表盘
Gauge类型代表一种样本数据可以任意变化的指标,即可增可减。Gauge通常用于像温度或者内存使用率这种指标数据,也可以表示能随时请求增加会减少的总数,例如当前并发请求的数量。
对于Gauge类型的监控指标,通过PromQL内置的函数delta() 可以获取样本在一段时间内的变化情况
例如,计算cpu温度在两小时内的差异:
delta(cpu_temp_celsius{host="zeus"}[2h])
还可以通过PromQL内置函数predict_linear() 基于简单线性回归的方式,对样本数据的变化趋势做出预测。
例如,基于两小时的样本数据,来预测主机可用磁盘空间在4个小时之后的剩余情况
predict_linear(node_filesystem_free{job="node"}[2h], 4*3600) < 0
3.3 Histogram直方图
- 在大多数情况下人们都倾向于使用某些量化指标的平均值,例如cpu的平均使用率、页面的平均响应时间。这种方式的问题很明显,以系统api调用的平均响应时间为例:如果大多数api请求都维持在100ms的响应时间范围内,而个别请求的响应时间需要5秒,那么就会导致某些web页面的响应落到中位数的情况,而这种现象被称为长尾问题。
- 为了区分是平均的慢还是长尾的慢,最简单的方式就是按照请求延迟的范围进行分组例如,统计延迟在0-10ms之间的请求数有多少而10-20ms之间的请求数又有多少。通过这种方式可以快速分析系统慢的原因。Histogram和Summary都是为了能够解决这样问题的存在,通过Histogram和Summary类型的监控指标我们可以快速了解监控样本的分布情况。
- Histogram在一段时间范围内对数据进行采样(通常是请求持续时间或响应大小等),并将其计入**可配置的存储桶(bucket)**中,后续可通过指定区间筛选样本,也可以统计样本总数,最后一般将数据展示为直方图。
Histogram类型的样本会提供三种指标(假设指标名称为):
- 样本的值分布在 bucket 中的数量,命名为
<basename>_bucket{le="<上边界>"} 。解释的更通俗易懂一点,这个值表示指标值小于等于上边界的所有样本数量。
EQ 就是 EQUAL等于 NE就是 NOT EQUAL不等于 GT 就是 GREATER THAN大于 LT 就是 LESS THAN小于 GE 就是 GREATER THAN OR EQUAL 大于等于 LE 就是 LESS THAN OR EQUAL 小于等于
// 在总共2次请求当中。http 请求响应时间 <=0.005 秒 的请求次数为0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method= "GET",code="200",le="0.005",} 0.0
// 在总共2次请求当中。http 请求响应时间 <=0.01 秒 的请求次数为0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method= "GET",code="200",le="0.01",} 0.0
// 在总共2次请求当中。http 请求响应时间 <=0.025 秒 的请求次数为0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method= "GET",code="200",le="0.025",} 0.0
- 所有样本值的大小总和,命名为
<basename>_sum 。
// 实际含义: 发生的2次 http 请求总的响应时间为 13.107670803000001 秒
io_namespace_http_requests_latency_seconds_histogram_sum{path="/",method="GET ",code="200",} 13.107670803000001
- 样本总数,命名为
<basename>_count 。值和 <basename>_bucket{le="+Inf"} 相同。
// 实际含义: 当前一共发生了 2 次 http 请求
io_namespace_http_requests_latency_seconds_histogram_count{path="/",method="G ET",code="200",} 2.0
bucket 可以理解为是对数据指标值域的一个划分,划分的依据应该基于数据值的分布。注意后面的采样点是包含前面的采样点的,假设 xxx_bucket{…,le=“0.01”} 的值为 10,而xxx_bucket{…,le=“0.05”} 的值为 30,那么意味着这 30 个采样点中,有 10 个是小于 10 ms 的,其余 20 个采样点的响应时间是介于 10 ms 和 50 ms 之间的。
3.4 Summary概率图
Summary即概率图,类似于Histogram,常用于跟踪与时间相关的数据。典型的应用包括请求持续时间、响应大小等。Summary同样提供样本的count和sum功能;还提供quantiles功能,可以按百分比划分跟踪结果,例如,quantile取值0.95,表示取样本里的95%数据。Histogram需要通过bucket计算quantile,而Summary直接存储了quantile的值。
3.5 Jobs和Instances
在Prometheus中,任何被采集的目标,即每一个暴露监控样本数据的HTTP服务都称为一个实例instance,通常对应于单个进程。而具有相同采集目的实例集合称为作业job。
四、Prometheus快速开始
4.1 使用二进制文件部署
- 打开下载网址:https://prometheus.io/download/ ,下载自己想要的版本
[root@server1 ~]
[root@server1 ~]
- 获取软件包的哈希值,与官网提供的软件包的哈希值进行对比,保证下载的Prometheus软件包的完整性
[root@server1 ~]
9c542a653bf2f17043056ca13ea428e56ff2f677ee03bf7494aa2efe2b8329a3 prometheus-2.30.1.linux-amd64.tar.gz
- 解压缩二进制软件包到指定的安装目录,运行Prometheus
[root@server1 ~]
[root@server1 ~]
prometheus-2.30.1.linux-amd64/
prometheus-2.30.1.linux-amd64/consoles/
prometheus-2.30.1.linux-amd64/consoles/index.html.example
prometheus-2.30.1.linux-amd64/consoles/node-cpu.html
prometheus-2.30.1.linux-amd64/consoles/node-disk.html
prometheus-2.30.1.linux-amd64/consoles/node-overview.html
prometheus-2.30.1.linux-amd64/consoles/node.html
prometheus-2.30.1.linux-amd64/consoles/prometheus-overview.html
prometheus-2.30.1.linux-amd64/consoles/prometheus.html
prometheus-2.30.1.linux-amd64/console_libraries/
prometheus-2.30.1.linux-amd64/console_libraries/menu.lib
prometheus-2.30.1.linux-amd64/console_libraries/prom.lib
prometheus-2.30.1.linux-amd64/prometheus.yml
prometheus-2.30.1.linux-amd64/LICENSE
prometheus-2.30.1.linux-amd64/NOTICE
prometheus-2.30.1.linux-amd64/prometheus
prometheus-2.30.1.linux-amd64/promtool
[root@server1 ~]
[root@server1 data]
"prometheus" -> "prometheus-2.30.1.linux-amd64/"
- 启动Prometheus,会输出如下信息,此时当终端关闭或者按下ctrl + c服务会自动关闭
[root@server1 data]
[root@server1 prometheus]
level=info ts=2021-09-29T13:13:54.539Z caller=main.go:400 msg="No time or size retention was set so using the default time retention" duration=15d
level=info ts=2021-09-29T13:13:54.539Z caller=main.go:438 msg="Starting Prometheus" version="(version=2.30.1, branch=HEAD, revision=fafb309d4027b050c917362d7d2680c5ad6f6e9e)"
level=info ts=2021-09-29T13:13:54.539Z caller=main.go:443 build_context="(go=go1.17.1, user=root@36ab67e1b043, date=20210928-09:41:36)"
level=info ts=2021-09-29T13:13:54.539Z caller=main.go:444 host_details="(Linux 3.10.0-957.el7.x86_64 #1 SMP Thu Nov 8 23:39:32 UTC 2018 x86_64 server1 (none))"
level=info ts=2021-09-29T13:13:54.539Z caller=main.go:445 fd_limits="(soft=1024, hard=4096)"
level=info ts=2021-09-29T13:13:54.539Z caller=main.go:446 vm_limits="(soft=unlimited, hard=unlimited)"
level=info ts=2021-09-29T13:13:54.542Z caller=web.go:541 component=web msg="Start listening for connections" address=0.0.0.0:9090
level=info ts=2021-09-29T13:13:54.557Z caller=main.go:822 msg="Starting TSDB ..."
level=info ts=2021-09-29T13:13:54.559Z caller=tls_config.go:191 component=web msg="TLS is disabled." http2=false
level=info ts=2021-09-29T13:13:54.578Z caller=head.go:466 component=tsdb msg="Replaying on-disk memory mappable chunks if any"
level=info ts=2021-09-29T13:13:54.578Z caller=head.go:500 component=tsdb msg="On-disk memory mappable chunks replay completed" duration=9.209μs
level=info ts=2021-09-29T13:13:54.578Z caller=head.go:506 component=tsdb msg="Replaying WAL, this may take a while"
level=info ts=2021-09-29T13:13:54.579Z caller=head.go:577 component=tsdb msg="WAL segment loaded" segment=0 maxSegment=0
level=info ts=2021-09-29T13:13:54.579Z caller=head.go:583 component=tsdb msg="WAL replay completed" checkpoint_replay_duration=41.933μs wal_replay_duration=319.446μs total_replay_duration=405.495μs
level=info ts=2021-09-29T13:13:54.581Z caller=main.go:849 fs_type=XFS_SUPER_MAGIC
level=info ts=2021-09-29T13:13:54.581Z caller=main.go:852 msg="TSDB started"
level=info ts=2021-09-29T13:13:54.581Z caller=main.go:979 msg="Loading configuration file" filename=prometheus.yml
level=info ts=2021-09-29T13:13:54.609Z caller=main.go:1016 msg="Completed loading of configuration file" filename=prometheus.yml totalDuration=27.517369ms db_storage=4.915μs remote_storage=27.114μs web_handler=1.694μs query_engine=4.352μs scrape=25.816703ms scrape_sd=76.617μs notify=41.677μs notify_sd=34.672μs rules=6.229μs
level=info ts=2021-09-29T13:13:54.609Z caller=main.go:794 msg="Server is ready to receive web requests."
在Prometheus日常维护中,一定会对配置文件prometheus.yml进行再编辑操作,通常对Prometheus服务进行重新启动操作即可完成对配置文件的加载。当然也可以通过动态的热加载来更新prometheus.yml中的配置信息,查看进程id,向进程发送SIHHUP信号
[root@server1 ~]
root 7159 7072 0 21:13 pts/0 00:00:00 ./prometheus
root 7260 7206 0 21:21 pts/1 00:00:00 grep --color=auto prometheus
[root@server1 ~]
- 通过HTTP API发送post请求到/-/reload
[root@server1 ~]
[root@server1 ~]
[root@server1 prometheus]
console_libraries consoles data LICENSE NOTICE prometheus prometheus.yml promtool
[root@server1 prometheus]
Checking prometheus.yml
SUCCESS: 0 rule files found
[root@server1 prometheus]
[root@server1 prometheus]
- 浏览器可以正常访问则说明部署Prometheus server成功(端口号默认是9090)
4.2 Exporter类型
- 直接采集型
- 这类Exporter直接内置了响应的应用程序,用于向Prometheus直接提供target数据支持。这样设计的好处是,可以更好地监控各自系统内部的运行状态,同时也适合更多自定义监控指标的项目实施。
- 间接采集型
- 原始监控目标并不直接支持Prometheus,需要我们使用Prometheus提供的客户端库编写该监控目标的监控采集数据,用户可以将该程序独立运行,取获取指定的各类监控数据值。例如,由于Linux操作系统自身并不能直接支持Prometheus,用户无法从操作系统层面上直接提供对Prometheus的支持,因此单独提供Node Exporter,还有数据库或网站HTTP应用类等Exporter。
文本数据格式
在Prometheus的监控环境中,所有返回监控样本数据的Exporter程序,均需要遵守Prometheus规范,即基于文本的数据格式,其特点是具有更好的跨平台和可读性。
- 可以使用浏览器,或者通过curl工具来获得采集数据
- 以HELP开头的行,表示metric的帮助与说明解释,可以包含当前监控指标名称和对应的说明信息
- 以TYPE开始的行,表示定义metric的类型
- 以非#开头的行即监控样本的数据,包括metric_name{label_name1,label_name2…} value [timestamp可选项]
4.3 Linux主机监控
Prometheus社区很活跃,提供了非常多类型的Exporter。可以在官网中找到自己想要的Exporter并进行下载https://prometheus.io/download/ 由于Linux操作系统自身并不支持Prometheus,所以Prometheus官方提供了go语言编写的Node_Exporter来实现对Linux操作系统主机的监控数据采集。它提供了系统内部几乎所有的标准指标,如cpu、内存、磁盘空间、磁盘I/O、系统负载和网络带宽。另外它还提供了由内核公开的大量额外监控指标,从负载平均到主板温度等。
[root@server2 ~]
[root@server2 ~]
344bd4c0bbd66ff78f14486ec48b89c248139cdd485e992583ea30e89e0e5390 node_exporter-1.2.2.linux-amd64.tar.gz
[root@server2 ~]
[root@server2 ~]
node_exporter-1.2.2.linux-amd64/
node_exporter-1.2.2.linux-amd64/LICENSE
node_exporter-1.2.2.linux-amd64/NOTICE
node_exporter-1.2.2.linux-amd64/node_exporter
[root@server2 ~]
[root@server2 data]
"node_exporter" -> "node_exporter-1.2.2.linux-amd64/"
[root@server2 data]
[root@server2 node_exporter]
总用量 18080
-rw-r--r--. 1 3434 3434 11357 8月 6 21:49 LICENSE
-rwxr-xr-x. 1 3434 3434 18494215 8月 6 21:45 node_exporter
-rw-r--r--. 1 3434 3434 463 8月 6 21:49 NOTICE
[root@server2 node_exporter]
当启动node_exporter开始工作时,node_exporter和Prometheus server还没有进行关联,二者各自独立没有关联。
可以在Prometheus server中,找到主机目录,找到主配置文件,使用其中的静态配置功能static_configs来采集node_exporter提供的数据
global:
scrape_interval:每次数据采集的时间间隔,默认为1秒
scrape_timeout:采集请求超时时间,默认为10秒
evaluation_interval:执行rules的频率,默认为1秒
scrape_configs:主要用于配置被采集数据节点操作,每一个采集配置主要由以下几个参数
job_name:全局唯一名称
scrape_interval:默认等于global内设置的参数,设置后可以覆盖global中的值
scrape_timeout:默认等于global内设置的参数
metrics_path:从targets获取meitric的HTTP资源路径,默认是/metrics
honor_labels:Prometheus如何处理标签之间的冲突。若设置为True,则通过保留变迁来解 决冲突;若设置为false,则通过重命名;
scheme:用于请求的协议方式,默认是http
params:数据采集访问时HTTP URL设定的参数
relabel_configs:采集数据重置标签配置
metric_relabel_configs:重置标签配置
sample_limit:对每个被已知样本数量的每次采集进行限制,如果超过限制,该数据将被视为失 败。默认值为0,表示无限制
[root@server1 data]
[root@server1 prometheus]
console_libraries consoles data LICENSE NOTICE prometheus prometheus.yml promtool
[root@server1 prometheus]
global:
scrape_interval: 15s
evaluation_interval: 15s
alerting:
alertmanagers:
- static_configs:
- targets:
rule_files:
scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["localhost:9090"]
- 在默认配置文件的基础上,重新编辑配置文件,添加job与node_exporter进行关联
scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["localhost:9090"]
- job_name: "node_exporter"
static_configs:
- targets: ["192.168.71.20:9100"]
[root@server1 prometheus]
root 7159 7072 0 21:13 pts/0 00:00:04 ./prometheus
root 7390 7206 0 22:43 pts/1 00:00:00 grep --color=auto prometheus
[root@server1 prometheus]
或者是通过搜索up找到node_exporter
4.4 metricts数据采集
对于cpu数据采集的主要监控指标是node_cpu_seconds_total
可以通过PromQL(后面会介绍这种查询语言)表达式进行查询,计算每核cpu每秒的空闲时间,然后对主机上的所有cpu求平均值avg without(cpu,mode) (rate(node_cpu_seconds_total {mode="idle"} [1m]))
[root@server2 ~]
total used free shared buff/cache available
Mem: 1907970048 123441152 1376419840 9969664 408109056 1587052544
Swap: 2147479552 0 2147479552
- node_memory_MemAvailable_bytes
- node_memory_MemFree_bytes
- node_memory_MemAvailable_bytes
- 磁盘信息采集
- node_disk_io_time_seconds_total
- 文件系统采集
- node_filesystem_size_bytes
任意一个Exporter都会提供足够多的metric,我们在学习的时候也不需要关心具体有多少metric,每个metric具体意思(其实见名知义大概也可以猜到)
|