Skip to content

Prometheus

前言

企业级运维监控理论基础

基础概念

img

运维是什么?说白了就是管理服务器,保障服务器给线上产品提供稳定运行的服务环境

监控是什么?说白了就是用一种形式,去盯着观察服务器把服务器的各种行为表现都显示出来,用以发现问题和不足

报警是什么?监控是把行为表现展示出来,用来观察;报警则是当监控获取的数据发生异常并且达到了某个临界点的时候,采用各种途径来通知用户、通知管理员、通知运维人员甚至老板

  • 阈值:监控系统中对数据达到某一个临界值的定义

数据不是凭空从天上掉下来的,也不是研发人员主动给你的,只能从运维数据采集而来

  • 数据采集不仅仅为监控提供服务,还用于分析用户行为/安全策略
  • 数据采集的方式:服务器/网络设备/用户数据 -> 产生行为和状态 -> 数据采集软件、脚本、硬件 -> 录入监控系统

Prometheus 相比其他老款监控的优势与不足

优势:

  • 监控数据的精细程度绝对一流,可以精确到1~5秒的采集精度,4~5分钟为理想的状态
  • 集群部署的速度,监控脚本的制作非常快速,大大缩短监控的搭建时间成本
  • 周边插件很丰富,大多数都不需要自己开发(exporter、pushgateway)
  • 本身基于数学计算模型,大量的使用函数,可以实现很复杂规则的业务逻辑监控(例如:QPS曲线、弯曲、凸起、下跌等等)
  • 可以嵌入很多开源工具的内部,进行监控数据更准时更可信
  • 本身是开源的,更新速度快,bug修复快。支持N种语言做本身和插件的二次开发
  • 跟 Grafana 结合生成的图形很高大上、很美观

不足:

  • 因其数据采集的精度,如果集群数量太大,那么单点的监控有性能瓶颈,只能 workaround
  • 学习成本太大,尤其是其独有的数学命令行,本身的各种数学模型的概念很复杂
  • 对磁盘资源也是耗费的较大,这个具体要看监控的集群量和监控项的多少和保存时间的长短

监控系统体系

image-20250819101706249

监控系统设计

  1. 评估系统的业务流程、业务种类、架构体系

  2. 分类监控项种类

    监控项种类:业务级监控/系统级别监控/网络监控/程序代码监控/日志监控/用户行为分析监控/其他种类监控

    • 业务监控:可以包含用户访问QPS、DAU日活、访问状态、业务接口、产品转换率、充值额度、用户投诉等等这些宏观的概念(上层)
    • 系统监控:主要是跟操作系统相关的基本监控项 CPU/内存/硬盘/IO/TCP链接/流量 等等(Nagios-plugins, prometheus)
    • 网络监控:对网络状态的监控(交换机、路由器、防火墙、VPN)互联网公司必不可少,但是很多时候又被忽略,例如:内网之间(物理内网、逻辑内网、可用区、创建虚拟机、内网IP)、外网丢包率、延迟等等
    • 日志监控:监控中的重头戏(Splunk、ELK),往往单独设计和搭建,全部种类的日志都有需要采集(syslog, soft, 网络设备, 用户行为)
    • 程序监控:一般需要和开发人员配合,程序中嵌入各种接口,直接获取数据,或者特定的日志格式
  3. 监控技术的方案/软件选取

  4. 监控人员的安排

监控系统搭建

  • 单点服务端的搭建(prometheus)
  • 单点客户端的部署
  • 单点客户端服务器测试
  • 采集程序单点部署
  • 采集程序批量部署
  • 监控服务器端HA/cloud(自己定制)
  • 监控数据图形化搭建(Grafana)
  • 报警系统测试(Pagerduty)
  • 报警规则测试
  • 监控+报警联调测试
  • 正式上线监控

数据采集的编写

例如:shell、python、awk、lua、php、perl、go 等

  • shell:运维的入门脚本,任何和性能/后台/界面无关的逻辑 都可以实现最快速的开发(shell 是在运维领域里开发速度最快难度最低的)
  • python:各种扩展功能扩展库功能丰富 ,伴随各种程序的展示+开发框架(如django)等 可以实现快速的中高档次的平台逻辑开发
  • awk:本身是一个实用命令也是一门庞大的编程语言,结合 shell 脚本 或者独立都可以使用在文本和标准输出处理上有很大的优势
  • lua: 多用于 nginx 的模块结合是比较新型的一个语言
  • php:老牌子的开发语言,在大型互联网开发中,目前有退潮的趋势不过在运维中工具开发还是很依赖 PHP
  • perl:传说中对文本处理最快的脚本语言(但是代码可读性不强)
  • go:在各种后端服务逻辑的编写上开发速度快成型早

数据采集的形式分类

  • 一次性采集
  • 后台式采集
  • 桥接式采集

监控数据分析和算法

监控数据的采集其实属于最基本的最小监控单位数据采集

采集回来的单位数据,如果没有懂行的人,将它们形成监控公式和报警阈值。CPU 采集回来的平均负载数值,以及 CPU 的时间片分布百分比

  • 例如:平均负载是如何计算的,CPU 的时间分片是如何分类的,什么叫作 用户态/内核态 CPU等待/处理时间,什么是 Interruptable/uninterruptable CPU等等概念。那么即使数据被采集回来的再精细准确,你也利用不好

监控的数据分析和算法,其实非常依赖运维架构师对 Linux 操作系统的各种底层知识的掌握

监控稳定测试

不管是一次性采集,还是后台采集,只要是在 Linux 上运行的东西都会多多少少对系统产生一定的影响

稳定性测试 就是通过一段时间的单点部署观察 对线上有没有任何影响

监控自动化

监控客户端的批量部署,监控服务端的 HA 再安装,监控项目的修改,监控项目的监控集群变化

自动化的引进 会很大程度上 缩短我们对监控系统的维护成本

  • 比如:Puppet(配置文件部署),Jenkins(CI 持续集成部署),CMDB(运维自动化的最高资源管理平台和理念)....等等

监控图形化工作

采集的数据和准备好的监控算法,最终需要一个好的图形展示,才能发挥最好的作用

监控的设计搭建需要大量的技术知识,但是对于一个观察者来说,往往不需要多少技术,只要能看懂图就好(例如 老板想看看当前用户访问量状况,想看看整体CPU高不高等等)

企业监控通用技术

早期企业无监控

  • 全部都是人工盯着服务器、操作系统、软件、网络等等

中前期企业 半自动脚本监控

  • 利用shell脚本这种类似的形式,做最简单的监控脚本循环登陆机器 查看一些状态,之后人工记录无报警、无自动化、无监控图形

中期企业 自动化程序/脚本/软件/监控

  • 脚本更新换代 开始使用各种开源非开源软件程序
  • 监控的搭建和开发监控形成图形化,加入报警系统,有一定的监控本身自动化实现
  • 这个阶段监控开始逐步成型 但是仍然缺乏精确度和稳定程度 报警的精细度

中后期企业 集群式监控 各种外援监控方案

  • 监控开始自成体系,加入各种自动化
  • 除去自身开发和搭建监控系统外,还会大量使用各种外围监控(各种商品监控,例如云计算监控 监控宝、友盟等等)
  • 监控发展出内监控、外监控(内监控是企业自己搭建的自用监控,外监控是使用外援的商业监控产品,往往对产品的最外展接口和用户行为进行更宏观的监控)

当前和未来监控。根据目前的发展状况,未来的监控主要会在几个方面不断的提高

  • 监控准确性、真实性
  • 监控高度集成自动化 无人值守
  • 监控成本的日益降低
  • 监控和 CMDB 的集成化以及自愈系统的发展

开源/非开源工具监控,如:Nagios/Cacti/Icinga/Zabbix/Ntop/prometheus 等等

未来理想中最完美的监控

  • 完整自愈式监控体系

    未来当自愈系统完善之后。各种层级的问题都会被各种自动化、持续集成、人工智能、灾备、系统缓冲等等技术自行修复

  • 真实链路式监控

    监控和报警的准确性、真实性发展到最终级的一个理想化模型

    例如:真实发生的问题是在于数据库的一个新的联合查询,对系统资源消耗太大造成各个方面的资源被大量消耗,间接的就引起各种链路的问题。于是乎各个层面的报警接踵而至,日志在报警,慢查询在报警,数据库CPU内存报警,程序层TCP连接堆积报警,HTTP返回码5xx报警

最终理想的未来报警系统,可以把所有无关的报警全部忽略掉,以链路的方式对问题一查到底,把最终引起问题的地方报警出来,让运维和开发即时做出响应和处理

Prometheus入门

监控入门

https://prometheus.io/docs/introduction/overview/

Prometheus 是一款基于时序数据库的开源监控告警系统,非常适合 Kubernetes 集群的监控

Prometheus 可以针对未来监控对于准确性和精确性的要求

Prometheus 监控的优质特性:

  • 基于 time series 时间序列模型

    时间序列是一系列的数据。通常是等时间间隔的采样数据

  • 基于 K/V 的数据模型

    Key/Value 键值的概念

  • 采样数据的查询完全基于数学运算,而不是其他的表达式,并提供专有的查询输入 console

  • 采用 HTTP pull/push 两种对应的数据采集传输方式

  • 开源,且大量的社区成品插件

  • push 的方法非常非常灵活

  • 本身自带图形调试

  • 最精细的数据采样

image-20250822103256959

Prometheus 对于运维的要求:

  • 要求对操作系统有很深入扎实的知识,不能只是浮在表面
  • 对数学思维有一定的要求,因为它基本的内核就是数学公式组成
  • 对监控的经验有很高的要求,很多时候监控项需要很细的定制

运行框架

Prometheus architecture

Prometheus 本身是一个以进程方式启动,之后以多进程和多线程实现监控数据收集、计算、查询更新、存储的这样一个 C/S 模型运行模式

Prometheus 解压之后,./prometheus 即可,之后默认监听在 9090 端口,用来访问

  • prometheus 采用的是 time-series(时间序列)的方式以一种自定义的格式存储在本地硬盘上
  • prometheus 的本地 T-S(time-series)数据库以每两小时为间隔来分block(块)存储,每一个块中 又分为多个 chunk 文件,chunk 文件是用来存放 采集过来的数据的 T-S 数据,metadata 和 索引文件(index)
  • index 文件是对 metrics(prometheus 中一次 K/V 采集数据叫做一个 metrics) 和 labels(标签)进行索引之后存储在 chunk 中chunk 是作为存储的基本单位,index and metadata 是作为子集
  • prometheus 平时是将采集过来的数据 先都存放在内存之中(prometheus 对内存的消耗还是不小的)以类似缓存的方式,用于加快搜索和访问
  • 当出现宕机时,prometheus 有一种保护机制叫做 WAL 可以将数据定期存入硬盘中以chunk来表示,并在重新启动时用以恢复进入内存

Service Discovery 服务发现功能

  • Prometheus 本身跟其他开源软件类似,也是通过定义配置文件,来给 Prometheus 本身规定需要被监控的项目和被监控节点

Prometheus 的客户端主要有两种方式采集

  • pull 主动拉取的形式

    客户端(被监控机器)先安装各类已有 exporters(由社区组织或企业开发的监控客户端插件)在系统上之后,exporters 以守护进程的模式运行并开始采集数据

    exporter 本身也是一个 http_server 可以对 http 请求做出响应,返回数据(K/V metrics)

    Prometheus 用 pull 这种主动拉的方式去访问每个节点上 exporter 并采样回需要的数据

  • push 被动推送的形式

    在客户端安装这个官方提供的 pushgateway 插件

    然后,使用我们运维自行开发的各种脚本,把监控数据组织成 K/V 的形式、metrics 形式,发送给 pushgateway,之后 pushgateway 会再推送给 prometheus

报警绘图部分

  • prometheus 本身不具备告警功能,只能通过第三方开源或商业软件实现报警

监控数据格式

Prometheus 监控中,对于采集过来的数据,统一称为 metrics 数据。metrics 是一种对采样数据的总称

metrics 几种主要类型:

  • Gauges

    最简单的度量指标,只有一个简单的返回值,或者瞬时状态

    例如:监控硬盘容量或者内存使用量,那么就应该使用 Gauges 的 metrics 格式来度量

    因为硬盘的容量或者内存的使用量,是随着时间的推移、不断的瞬时、没有规则变化的

  • Counters

    Counter 就是计数器,从数据量 0 开始累积计算,在理想状态下,只能是永远的增长,不会降低

    例如:对用户访问量的采样数据

  • Histograms

    Histogram 统计数据分布情况。比如最小值、最大值、中间值还有中位数,75百分位、90百分位、95百分位、98百分位、99百分位和99.9百分位的值

    比如:http_response_time HTTP 响应时间,代表的是一次用户 HTTP 请求,在系统传输和执行过程中,总共花费的时间。我们想监控用户的访问时间

    如果我们想通过监控的方式,抓取当天的 nginx_access_log,并且想监控用户的访问时间

    • 把日志每行的 http_response_time 数值统统采集下来,然后计算一下平均值。比如今天访问量是 100万次,然后把 100万次 http_response_time 全部加一起,然后除以 100万,最后得出一个值,那这个数据有意义大吗
    • 例如,今天中午 1:00 时候,发生了一次线上故障,系统整体的访问变得非常缓慢,大部分用户请求时间都达到了 0.5~1 秒左右,但是这一段时间只持续了 5 分钟,总的一天平均值并不能表现得出来

    所以 Histograms 的 metrics 类型,就派上用场了,通过 histogram 类型可以分别统计出,全部用户的响应时间中,~=0.5秒的有多少,>2秒的有多少,>10秒的有多少

K/V 的数据形式:

  • 当一个 node_exporter 被安装和运行在监控的服务器上后,使用简单的 curl 命令,就可以看到 exporter 帮我们采集到 metrics 数据的样式,以 K/V 形式展示
bash
process_max_fds 65535
process_open_fds 10

pushgateway 介绍:

exporter 是首先安装在被监控服务器上,运行在后台,然后自动采集系统数据,本身又是一个 http_server 可以被 prometheus 定时去 HTTP GET 获取数据,属于 pull 形式

push 的形式是把 pushgateway 安装在客户端或服务端,pushgateway 本身也是一个 http 服务器

为什么已经有了那么强大的 pull 形式的 node_exporter 采集,还需要一个 pushgateway 的形式呢?

  • exporter 虽然采集类型已经很丰富了,但是我们依然需要很多自制的监控数据,非规则化、自定制的
  • exporter 由于数据类型采集量大,其实很多数据或者大部分数据,其实我们监控中真的用不到,用 pushgateway 定义一项数据,就采集着一种,节省资源
  • 一个新的自定义的 pushgateway 脚本开发,远远比开发一个全新的 exporter 简单快速的多的多的多
  • exporter 虽然已经很丰富了,但是依然有很多我们需要的采集形式,exporter 无法提供,或者说现有的 exporter 还不支持,但是如果使用 pushgateway 的形式,就可以任意灵活,想做什么都可以做到,而且非常快速

初探和配置

安装 Prometheus 之前,必须先安装 ntp 时间同步(T_S 对系统时间的准确性要求很高,必须保证本机时间同步)

  1. Prometheus 下载

    https://prometheus.io/download/

  2. Prometheus 安装

    bash
    tar -zxvf prometheus-x.x.x.linux-amd64.tar.gz
    cp -rf prometheus-x.x.x.linux-amd64 /usr/local/prometheus
  3. Prometheus 启动和后台运行

    bash
    ./prometheus

    默认运行在 9090,就可以直接打开访问,无账号密码验证(如果希望加上验证,可以使用类似 apache httppass 方式添加)

  4. Prometheus 主配置文件

    bash
    ./prometheus --config.file=prometheus.yml
    
    global:
      scrape_interval: 15s
      evaluation_interval: 15s
    • scrape_interval:抓取采样数据的时间间隔,默认每15秒去被监控机采样一次
    • evaluation_interval:监控数据规则的评估频率

    Alertmanaeger 是 prometheus 的一个用于管理和发出报警的插件(4.0 版本的 Grafana 本身就已经支持报警发出功能了)

    bash
    # Here it's Prometheus itself.
    scrape_configs:
      - job_name: "prometheus"
        static_configs:
          - targets: ["localhost:9090"]
            labels:
              app: "prometheus"
    • targets 的设定,默认带了一个 prometheus 本机的

node_exporter

bash
./node_exporter

CPU 使用时间,还会分成几个重要的状态类型:

  • 比如:CPU time 分成 CPU user time / sys time / nice time / idle time / irq / 等等...

CPU 使用率 = (所有非空闲的CPU使用时间综合) / (所有状态CPU时间的总和)

命令行使用扩展

函数

  • increase 函数在 prometheus 中,是用来针对 Counter 这种持续增长的数值,截取其中一段时间的增量
  • sum 起到 value 加合的作用
  • by 可以把 sum 合并到一起的数值,按照指定的方式进行一层拆分

示例:

  • sum(increase(node_cpu{mode="idle"}[1m]))
  • sum(increase(node_cpu{mode="idle"}[1m])) by (instance)

空闲CPU百分比:(sum(increase(node_cpu{mode="idle"}[1m])) by (instance) / sum(increase(node_cpu[1m])) by (instance)) * 100

prometheus命令行格式:

  • count_netstat_wait_connections 不是 node_exporter 的(TCP wait_connect 数)

  • gauge 类型的数据,属于随机变换数值,可以直接使用当前值,并不像 counter 那样

    counter 类型的数据,需要使用 increase()、rate() 等函数去计算单位时间段的增量

  • count_netstat_wait_connections {exported_instance="log"}

    exported_instance 指明是那台被监控服务器,log 是一台日志服务器的机器名

  • 标签匹配,.*属于正则表达式:模糊匹配(=~)、模糊不匹配(!~

  • 标签过滤之后就是数值的过滤,count_netstat_wait_connections {exported_instance=~"web.*"} > 400

Grafana

Grafana 是一款近几年新兴的开源数据绘图工具平台

Prometheus 擅长发现异常,而 PagerDuty 擅长处理异常。具体来说,当 Prometheus 检测到指标异常(如服务器宕机)时,它可以通过 Alertmanager 将告警转发给 PagerDuty。PagerDuty 则负责升级处理——根据预设规则通知值班人员(电话/短信/邮件),跟踪事件状态,直到问题解决

Grafana 与 PagerDuty 的分工对比

功能GrafanaPagerDuty
数据可视化✅ 丰富图表展示监控指标❌ 不直接展示数据
基础告警触发✅ 基于阈值规则生成告警事件❌ 依赖外部输入告警
通知路由❌ 仅基础推送(邮件/Slack)✅ 多级通知、值班调度、电话强提醒
事件闭环管理❌ 无状态跟踪✅ 全生命周期记录(触发→解决)
智能降噪❌ 需手动配置✅ 机器学习降噪+根因建议
跨团队协作❌ 有限✅ 多角色协同与自动化路由

CPU密集型 与 IO密集型

类型核心瓶颈资源消耗特点任务本质
CPU密集型CPU计算能力(如算力不足)CPU利用率高(常达90%~100%)计算为主,极少等待外部操作
IO密集型I/O设备速度(如磁盘/网络延迟)CPU利用率低(常<30%),大量等待时间等待为主,少量计算

常备不懈,才能有备无患