监控系统-prometheus
【部分图片显示有问题~,如影响阅读可移步到 监控系统-prometheus】
1. 简介
1.1 官方的介绍
Prometheus 是由前 Google 工程师从 2012 年开始在 Soundcloud 以开源软件的形式进行研发的系统监控和告警工具包,自此以后,许多公司和组织都采用了 Prometheus 作为监控告警工具。Prometheus 的开发者和用户社区非常活跃,它现在是一个独立的开源项目,可以独立于任何公司进行维护。为了证明这一点,Prometheus 于 2016 年 5 月加入 CNCF 基金会,成为继 Kubernetes 之后的第二个 CNCF 托管项目。
图比较老了,现在已经更新到2.25版本了。
1.2 主要功能/优势
如以下案例:查询实例为10.224.192.\d{3}:9100的机器,用户近30s平均cpu使用率。
avg(rate(node_cpu_seconds_total{instance=~"10.224.192.\\d{3}:9100", mode="user"}[30s]))*100
- 无依赖存储,支持 local 和 remote 不同模型。单个服务节点具有自治能力
- 采用 http 协议,使用 pull 模式拉取数据,简单易懂。也可以用过中间网关来推送数据
- 监控目标,可以采用服务发现或静态配置的方式
- 支持多种统计数据模型,图形化友好
1.3 监控系统的比较
这里对比了4款监控系统
Zabbix和Nagios都是老牌的监控系统
open-falcon是小米公司开源的一款监控系统
- 从系统成熟度上看,Zabbix和Nagios都是老牌的监控系统,系统功能比较稳定,成熟度较高。而Prometheus和Open-Falcon都是最近几年才诞生的,功能还在不断的迭代更新。
- 扩展性:Prometheus可以通过各种exporter扩展系统采集能力,以及通过接口扩展存储方案,这个后面会介绍到。
- 活跃度方面:Prometheus社区活跃度最高,并且还受到CNCF的支持;
- 性能方面,主要在于存储上的区别,Prometheus采用高性能的时序数据库,Zabbix采用关系数据库,Nagios和Open-Falcon都采用RRD数据存储。
- 容器支持方面:Zabbix和Nagios出现得比较早,容器还没有诞生,所以对容器的支持也比较差。Open-Falcon对于容器的监控,支持力度有限。Prometheus的动态发现机制,支持各种容器集群的监控,是目前容器监控最好解决方案。
1.4 总结而言
- Prometheus 属于一站式监控告警平台,依赖少,功能齐全。
- Prometheus 支持对云或容器的监控,其他系统主要对主机监控。
- Prometheus 数据查询语句表现力更强大,内置更强大的统计函数。
- Prometheus 在数据存储扩展性以及持久性上没有 InfluxDB,OpenTSDB,Sensu 好。
- 适用场景
Prometheus 适用于记录文本格式的时间序列,它既适用于以机器为中心的监控,也适用于高度动态的面向服务架构的监控。在微服务的世界中,它对多维数据收集和查询的支持有特殊优势。Prometheus 是专为提高系统可靠性而设计的,它可以在断电期间快速诊断问题,每个 Prometheus Server 都是相互独立的,不依赖于网络存储或其他远程服务。当基础架构出现故障时,你可以通过 Prometheus 快速定位故障点,而且不会消耗大量的基础架构资源。 - 不适用场景
Prometheus 非常重视可靠性,即使在出现故障的情况下,你也可以随时查看有关系统的可用统计信息。如果你需要百分之百的准确度,例如按请求数量计费,那么 Prometheus 不太适合你,因为它收集的数据可能不够详细完整。这种情况下,你最好使用其他系统来收集和分析数据以进行计费,并使用 Prometheus 来监控系统的其余部分。
2. 架构设计
2.1整体架构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QWpDeuaA-1617093666707)(https://raw.githubusercontent.com/1458428190/prometheus-demo/main/images/prometheus.svg)]
Prometheus包含了几个关键的组件,也就是上图黄色的部分:Prometheus server、Pushgateway、Alertmanager,还有相关的webui。
Prometheus server会从服务发现或者静态配置,拿到要拉数据的目标节点,然后定期从目标节点拉取并存储数据,这里的目标节点可以是各种直接通过http接口暴露数据的exporter,也可以是专门用来接收推送数据的pushgateway。
Prometheus还可以配置各种规则,然后定时查询数据,当条件触发的时候,会将 alert 推送到配置的alertmanager。
最后由alertmanager 收到警告,alertmanager可以根据配置,聚合,去重,降噪,最后发送警告。
Prometheus支持从其他prometheus实例采集信息,假如有多个数据中心,可以通过联邦集群的方式,在各个数据部署一个单独的promeheus实例,然后再通过一个中心的Prometheus Server负责聚合多个数据中心的监控数据。
2.2 主要模块
2.2.1 prometheus server
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mJfwjY0Q-1617093666708)(https://raw.githubusercontent.com/1458428190/prometheus-demo/main/images/prometheus-server.svg)]
根据工作原理,prometheus本身先要通过Scrape discovery manager发现目标节点,再利用Scrape manager 指标刮削
然后通过一个存储代理层 Fanout storage,将数据存到对应的本地存储或者远程存储中。
Local storage:采用自定义的存储格式将样本数据保存在本地磁盘当中,但本地存储本身可靠性较差,只推荐在数据持久化要求不高的场景下使用。
Remote storage:为了灵活拓展,prometheus通过定义两个标准接口(remote_write/remote_read),让用户可以基于这两个接口对接将数据保存到任意第三方的存储服务中。
RuleManager负责所配置规则的定时查询,当条件触发的时候将,将结果写到存储里,并将需要触发alert信息通过notifier推给alertmanager
2.2.2 exporter
只需要简单的部署exporter(有很多官方和第三方提供的库,也可以自己实现),便可以采集很多常见的指标数据,比如数据库指标、硬件指标…详情见官网。
2.2.3 alertmanager
2.2.3.1 简介
告警能力在Prometheus的架构中被划分成两个独立的部分。通过在Prometheus server中定义AlertRule(告警规则),Prometheus会周期性的对告警规则进行计算,如果满足告警触发条件就会向Alertmanager发送告警信息。
一条告警规则的组成:
- 告警名称
用户需要为告警规则命名,当然对于命名而言,需要能够直接表达出该告警的主要内容 - 告警规则
告警规则实际上由PromQL进行定义,其实际意义是当表达式(PromQL)查询结果持续多长时间(During)后出发告警
Alertmanager作为一个独立的组件,负责接收并处理来自Prometheus Server(也可以是其它的客户端程序)的告警信息。Alertmanager可以对这些告警信息进行进一步的处理,比如去重、分组和路由。目前Prometheus内置了对邮件,Slack等多种通知方式的支持,其他的通知方式,比如popo或者短信通知,可以通过Webhook实现。
这里再介绍下背景知识,Prometheus 生态中的告警是在 Prometheus Server 中计算告警规则(Alert Rule)并产生的,而所谓计算告警规则,其实就是周期性地执行一段 PromQL,得到的查询结果会记录一个用于告警的时间序列 ALERTS {alertname =“ ”,<alert标签>} 用于后续的告警。当 Prometheus Server 计算出一些告警后,它自己并没有能力将这些告警通知出去,只能将告警推给 Alertmanager,由 Alertmanager 进行发送。这个切分,一方面是出于单一职责的考虑, 另一方面则是因为告警发送确实不是一件"简单"的事,需要一个专门的系统来做好它。可以这么说,Alertmanager 的目标不是简单地"发出告警",而是"发出高质量的告警"。
2.2.3.2 特性
Alertmanager除了提供基本的告警通知能力以外,还主要提供了如:分组、抑制以及静默等告警特性:
- 分组: 分组机制可以将详细的告警信息合并成一个通知
分组机制可以将详细的告警信息合并成一个通知。在某些情况下,比如由于系统宕机导致大量的告警被同时触发,在这种情况下分组机制可以将这些被触发的告警合并为一个告警通知,避免一次性接受大量的告警通知,而无法对问题进行快速定位。
例如,当集群中有数百个正在运行的服务实例,并且为每一个实例设置了告警规则。假如此时发生了网络故障,可能导致大量的服务实例无法连接到数据库,结果就会有数百个告警被发送到Alertmanager。而作为用户,可能只希望能够在一个通知中中就能查看哪些服务实例收到影响。这时可以按照服务所在集群或者告警名称对告警进行分组,而将这些告警内聚在一起成为一个通知。
告警分组,告警时间,以及告警的接受方式可以通过Alertmanager的配置文件进行配置。 - 抑制:当某一告警发出后,可以停止重复发送由此告警引发的其它告警的机制
抑制是指当某一告警发出后,可以停止重复发送由此告警引发的其它告警的机制。
例如,当集群不可访问时触发了一次告警,通过配置Alertmanager可以忽略与该集群有关的其它所有告警。这样可以避免接收到大量与实际问题无关的告警通知。抑制机制同样通过Alertmanager的配置文件进行设置。
- 静默:提供了一个简单的机制可以快速根据标签对告警进行静默处理。如果接收到的告警符合静默的配置,Alertmanager则不会发送告警通知
静默提供了一个简单的机制可以快速根据标签对告警进行静默处理。如果接收到的告警符合静默的配置,Alertmanager则不会发送告警通知。静默设置需要在Alertmanager的Werb页面上进行设置。
2.2.3.3 架构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ee2TYGsR-1617093666711)(https://raw.githubusercontent.com/1458428190/prometheus-demo/main/images/alertmanager.svg)]
- 从左上开始,在prometheus server里配了个告警规则,默认情况下,每分钟对这些告警规则进行计算,如果满足触发条件就会生成一个告警记录,通过API推送给alertmanager。
- alertmanager通过API接收到告警记录,随后经过验证、转换、最终将告警信息存储到 AlertProvider 中,目前这里的实现是存在内存中,可以通过接口的方式自行实现其他存储方式。
- Dispatcher它会一直监听并接收新的告警,根据路由树的配置将告警路由到对应的分组中,方便统一管理具有那些有相同属性信息的告警 【通过group_by**来定义分组规则。基于告警中包含的标签】。这里可以极大的减少告警风暴。
- 每个分组会以配置的周期时间定时的进行Notification Pipeline 流程处理;
- 这个Notification Pipeline流程其实就是执行抑制逻辑,静默逻辑,等待数据收集,去重,发送与重试逻辑,最终实现告警,告警完成后,会把通知记同步到集群中,后续用于集群间的静默和去重处理
- 告警抑制
可以避免当某种问题告警产生之后用户接收到大量由此问题导致的一系列的其它告警通知。例如当集群不可用时,用户可能只希望接收到一条告警,告诉他这时候集群出现了问题,而不是大量的如集群中的应用异常、中间件服务异常的告警通知。
inhibit_rules:
- source_match:
alertname: NodeDown
severity: critical
target_match:
severity: warning
equal:
- node
例如当集群中的某一个主机节点异常宕机导致告警NodeDown被触发,同时在告警规则中定义了告警级别severity=critical。由于主机异常宕机,该主机上部署的所有服务,中间件会不可用并触发报警。根据抑制规则的定义,如果有新的告警级别为severity=critical,并且告警中标签node的值与NodeDown告警的相同,则说明新的告警是由NodeDown导致的,则启动抑制机制停止向接收器发送通知。
- 告警静默
用户通过后台或者API配置临时屏蔽特定的告警通知。通过定义标签的匹配规则(字符串或者正则表达式),如果新的告警通知满足静默规则的设置,则停止向receiver发送通知。
2.2.4 pushgateway
它的存在允许短暂和批量作业将其指标暴露给 Prometheus。由于这些工作的生命周期可能不足够长,不能够存在足够的时间以让 Prometheus 抓取它们的指标。Pushgateway 允许它们可以将其指标推送到 Pushgateway,然后 Pushgateway 再将这些指标暴露给 Prometheus 抓取。
使用它的原因主要是:
- Prometheus 采用 pull 模式,可能由于不在一个子网或者防火墙原因,导致 Prometheus 无法直接拉取各个 target 数据。
- 在监控业务数据的时候,需要将不同数据汇总, 由 Prometheus 统一收集。
- 临时任务的数据采集
弊端:
- 将多个节点数据汇总到 pushgateway, 如果 pushgateway 挂了,受影响比多个 target 大。
- Prometheus 拉取状态
up
只针对 pushgateway, 无法做到对每个节点有效。 - Pushgateway 可以持久化推送给它的所有监控数据。
因此,即使你的监控已经下线,prometheus 还会拉取到旧的监控数据,需要手动清理 pushgateway 不要的数据。
3. 如何集成
详见另一篇文章~