Prometheus是由SoundCloud开发的开源监控报警系统时序列数据库(TSDB)。基于Go语言开发,是Google BorgMon监控系统的开源版本。

适用/不适用场景

适用场景

Prometheus在记录纯数字时间序列方面表现非常好。它既适用于面向服务器等硬件指标的监控,也适用于高动态的面向服务架构的监控。对于现在流行的微服务,Prometheus的多维度数据收集数据筛选查询语言也是非常的强大。

Prometheus是为服务的可靠性而设计的,当服务出现故障时,它可以使你快速定位和诊断问题。它的搭建过程对硬件和服务没有很强的依赖关系。

从ProcessOn上的模板中也能够发现,它主要是用来监听和警告微服务相关的信息,在公司中也是用来进行项目的多维度流量监控。
常用于的监控有:
mysql、redis、zookeeper、linux、elasticsearch、kafka、cadvisor、asr、jvm、node、jmx、Micrometer、rabbitMQ等。

不适用场景

Prometheus,它的价值在于可靠性,甚至在很恶劣的环境下,你都可以随时访问它和查看系统服务各种指标的统计信息。 如果你对统计数据需要100%的精确,它并不适用,例如:它不适用于实时计费系统

特征&优势

特征

  1. 多维度数据模型
  2. 灵活的查询语言
  3. 不依赖分布式存储,单个服务器节点是自主的
  4. 以HTTP方式,通过pull模型拉去时间序列数据
  5. 也通过中间网关支持push模型
  6. 通过服务发现或者静态配置,来发现目标服务对象
  7. 支持多种多样的图表和界面展示,grafana也支持它

优势

相较于同类监控系统产品,如:Graphite、OpenTSDB、Nagios等。它的优势在于:

  1. 主要做度量指标监控
  2. 更强大的查询语言,警告和通知功能
  3. 图表和警告的高可靠性和稳定性
  4. 如果你想要使用白盒、或者有一个动态的云环境,那么Prometheus是一个很好的选择。

整体架构

Prometheus
名词解释

(Alert)警告
警告是Prometheus服务正在激活警报规则的结果。警报将数据从Prometheus服务发送到警告管理器

(Alertmanager)警告管理器
警告管理器接收警告,并把它们聚合成组、去重复数据、应用静默和节流,然后发送通知到邮件、Pageduty或者Slack等系统中

(Bridge)网桥
网桥是一个从客户端库提取样本,然后将其暴露给非Prometheus监控系统的组件。例如:Python客户端可以将度量指标数据导出到Graphite。

(Client library)客户库
客户库是使用某种语言(Go、Java、Python、Ruby等),可以轻松直接调试代码,编写样本收集器去拉取来自其他系统的数据,并将这些度量指标数据输送给Prometheus服务。

(Collector) 收集器
收集器是表示一组度量指标导出器的一部分。它可以是单个度量指标,也可以是从另一个系统提取的多维度度量指标。

(Direct instrumentation)直接测量
直接测量是将测量在线添加到程序的代码中

(Exporter)导出器
导出器是暴露Prometheus度量指标的二进制文件,通常将非Prometheus数据格式转化为Prometheus支持的数据处理格式

(Notification)通知
通知表示一组或者多组的警告,通过警告管理器将通知发送到邮件,Pagerduty或者Slack等系统中

(PromDash) 面板
PromDash是Prometheus的Ruby-on-rails主控面板构建器。它和Grafana有高度的相似之处,但是它只能为Prometheus服务

Prometheus
Prometheus经常称作Prometheus系统的核心二进制文件。它也可以作为一个整体,被称作Prometheus监控系统

(PromQL) Prometheus查询语言
PromQL是Prometheus查询语言。它支持聚合、分片、切割、预测和连接操作

Pushgateway
Pushgateway会保留最近从批处理作业中推送的度量指标。这允许服务中断后Prometheus能够抓取它们的度量指标数据

Silence
在AlertManager中的静默可以阻止符合标签的警告通知

Target
在Prometheus服务中,一个应用程序、服务、端点的度量指标数据

Prometheus服务,可以直接通过目标拉取数据,或者间接地通过中间网关拉(Pushgateway)取数据。它在本地存储抓取的所有数据,并通过一定规则进行清理和整理数据,并把得到的结果存储到新的时间序列中,PromQL和其他API可视化地展示收集的数据。
Prometheus服务彼此独立运行,它仅仅依赖于本地存储。Prometheus有三个核心的功能:抓取、规则处理和警告

如果官方图不是很明确,那下面这两张图应该能够加深对Prometheus职能的理解:

为什么是使用的是pull而不是push?

基于Http方式的pull模型提供了以下优点:

  • 当开发变化时,你可以在本地上运行你的监控
  • 如果目标实例挂掉,你可以很容易地知道
  • 你可以手动指定一个目标,并通过浏览器检查该目标实例的监控状况
  • 对于研发来说,你只需要将需要的指标封装成prometheus采集需要的格式,再提供一个不需要权限校验的监控地址就行了。剩下的就都交给运维来搞定。(如果是push的话你得写策略或定时器将数据推送到pushgateway上,并且还要实现缓存策略存储采集下来的数据。)

也就是说,如果你非得用push不可的话,那么推送到pushgateway再让Prometheus从中拉取,是最佳的选择,但这无疑会加大研发同学的难度。

数据模型

Prometheus从根本上存储的所有数据都是时间序列: 具有时间戳的数据流只属于单个度量指标和该度量指标下的多个标签维度。
除了存储时间序列数据外,Prometheus也可以利用查询表达式存储5分钟的返回结果中的时间序列数据

上文提到的指标标签,正是Prometheus的核心。

metrics(度量指标名称,简称:指标)

每一个时间序列数据由metric度量指标名称和它的labels标签的键值对集合唯一确定。
metric指定了监控目标系统的测量特征(如:http_requests_total—— 接收http请求的总计数)
metric以ASCII字母、数字、下划线和冒号命名,必须配正则表达式[a-zA-Z_:][a-zA-Z0-9_:]*
(注意此处没有-,如果指标名称不合法在注册时会报命名不合法的异常)

metrics类型

Prometheus客户库提供了四个核心的metrics类型。
Counter(计数器)、Gauge(测量器)、Histogram(柱状图)、Summary(概要图)
主要使用的是 Counter(计数器)、Gauge(测量器)这两者。

Counter(计数器)

counter 是一个累计度量指标,它是一个只能递增的数值。计数器主要用于统计服务的请求数、任务完成数和错误出现的次数等等。计数器是一个递增的值。反例:统计goroutines的数量。
counter-github-demo

Gauge(测量器)

gauge是一个度量指标,它表示一个既可以递增, 又可以递减的值。
测量器主要测量类似于温度、当前内存使用量等,也可以统计当前服务运行随时增加或者减少的Goroutines数量
gauge-github-demo

labels(标签)

labels标签开启了Prometheus的多维数据模型:对于相同的指标名称,通过不同标签列表的结合, 会形成特定的指标维度实例。(例如:所有包含度量名称为/api/tracks的http请求,打上method=POST的标签,则形成了具体的http请求)。
改变任何指标上的任何标签值,都会形成新的时间序列图
label名称可以包含ASCII字母、数字和下划线。它们必须匹配正则表达式[a-zA-Z_][a-zA-Z0-9_]*。带有_下划线的标签名称被保留内部使用。
labels值可包含任意的Unicode码。

Jobs(任务)和Instances(实例)

就Prometheus而言,pull拉取采样点的端点服务称之为instance。多个这样pull拉取采样点的instance, 则构成了一个job

例如, 一个被称作api-server的任务有四个相同的实例。

job: api-server
instance 1:1.2.3.4:5670
instance 2:1.2.3.4:5671
instance 3:5.6.7.8:5670
instance 4:5.6.7.8:5671

当Prometheus拉取一个目标, 会自动地把两个标签添加到度量指标名称的标签列表中(这句其实不是很理解,因为在监控指标上没看到这两个标签),分别是:
job: 目标所属的配置任务名称 api-server
instance: 采样点所在服务 host:port
(相当于拼接成:127.0.0.1:8080/project-name/actuator/prometheus,后面可以拼接具体的具体的指标)

配置、查找、存储、可视化

这些操作基本都是运维那块的,也没有细学,贴个文档用到的时候再看看。
Prometheus官方文档

可视化首选Grafana,简单又好用。具体在下一篇实战中说明。

客户端库

在你能够监控你的服务器之前,你需要通过Prometheus客户端库把监控的代码放在被监控的服务代码中。在你的服务实例上通过HTTP端口提供内部度量指标。

接下来这句是整个文档的重点,也是通过这句话我才打通了整个Prometheus的流程:

When Prometheus scrapes your instance's HTTP endpoint, the client library sends the current state of all tracked metrics to the server.

当Prometheus获取实例的HTTP端点时,客户库发送所有跟踪的度量指标数据到服务器上。

解释:
也就是说如果是通过Prometheus直接pull拉取项目的话,每次它定时访问到该监控端口时候,客户端(项目)就会发送/更新所有成功注册的度量指标(默认+自定义)数据到该端口。这样相当于每次Prometheus拉取的时候就会更新一次。
对于客户端(项目)需要做的只是编写自定义的监控指标并注册上去。


剩下的基本都跟代码相关,丢到实战了。

传送门:

Last modification:September 16th, 2021 at 02:26 pm
喵ฅฅ