Prometheus指南:66k星云原生监控标准,指标采集+PromQL+告警规则全流程

项目:prometheus/prometheus | 星数:66850 | 语言:Go | 协议:Apache-2.0 | GitHub仓库

更新日期:2026-10-30 · 作者:CodeArts 编辑部

为什么监控绕不开 Prometheus

我给客户做过一次线上故障复盘:数据库连接池被打满,应用日志里只有一行超时,没人知道是什么时候开始劣化的。事后我们把监控从「日志里找答案」换成了「指标上看趋势」,用的就是 Prometheus。它现在是云原生监控事实标准,66850 星,Apache-2.0 协议,指标拉取模型配 PromQL 查询,几乎是所有 Kubernetes 集群的默认选择。

它的定位很清晰:时序指标数据库 + 拉取式采集 + 告警规则引擎。它不做日志、不做长周期存证,日志交给 Loki 或 ELK,长期存储交给 Thanos/Mimir。想清楚这条边界,能省掉后面很多纠结。

四个组件先分清

组件职责常见误区
prometheus server定时拉取指标、存 TSDB、执行告警规则以为它能存储海量历史数据
exporter把第三方系统指标翻译成 HTTP 端点以为不装 exporter 也能监控数据库
alertmanager告警去重、分组、路由、静默以为 Prometheus 自己能发邮件
pushgateway接收短生命周期任务的推送把长驻服务也往这里推

最后一条是我踩过的坑。曾经把一个常驻服务的指标推到 Pushgateway,指标永远不会过期,进程挂了图表上还是一条直线,告警根本不响。Pushgateway 只适合 cron 任务这类跑完就退出的场景,常驻服务必须走 pull。

Docker 起一个最小可用实例

# prometheus.yml
global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

docker run -d --name prometheus   -p 9090:9090   -v $PWD/prometheus.yml:/etc/prometheus/prometheus.yml   prom/prometheus

访问 http://localhost:9090 就能用内置的表达式浏览器查询。默认只抓自己,想监控主机就加 node_exporter,想监控容器就加 cAdvisor,这两个加起来覆盖了八成日常需求。

PromQL 从这五条查询开始

PromQL 是 Prometheus 真正的门槛。下面五条覆盖日常八成排查场景:

# 1. 目标是否在线(1=在线 0=离线)
up{job="node"}

# 2. 主机 5 分钟平均 CPU 使用率
100 - (avg by(instance) (rate(node_cpu_seconds_total{{mode="idle"}}[5m])) * 100)

# 3. 内存可用百分比
node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes * 100

# 4. 磁盘 4 小时内预计写满
predict_linear(node_filesystem_avail_bytes{{mountpoint="/"}}[4h], 4*3600) < 0

# 5. HTTP 5xx 比例
rate(http_requests_total{{status=~"5.."}}[5m]) / rate(http_requests_total[5m])

第 4 条是我最推荐放进告警的查询。predict_linear 用线性回归预测未来值,比「磁盘使用率 > 90%」这种静态阈值靠谱得多——大文件写入导致的暴涨能被提前几小时发现。

告警规则怎么写才不吵

groups:
  - name: host
    rules:
      - alert: DiskWillFillIn4Hours
        expr: predict_linear(node_filesystem_avail_bytes{{mountpoint="/"}}[4h], 4*3600) < 0
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "{{{{ $labels.instance }}}} 磁盘预计 4 小时内写满"

for: 10m 这个字段千万别省。没有它,一次瞬时的抖动就会触发告警,半夜被叫起来发现只是备份任务在跑,两三次之后团队就会集体忽略告警,监控体系等于废了。

能力边界

能做不能做
秒级指标采集、查询、告警日志全文检索(用 Loki)
多维标签聚合、下钻长期冷数据存储(用 Thanos/Mimir)
服务发现自动纳管目标分布式追踪(用 Tempo/Jaeger)
丰富的 exporter 生态高基数标签(如用户 ID 做 label 会炸)

关于高基数:我们曾经给指标加了一个 request_id 标签,一天之内 TSDB 涨了 40GB,查询直接超时。标签只放能聚合的维度——服务名、实例、状态码、接口路径,绝不放唯一值。

要不要上 Prometheus Operator

在 Kubernetes 里,手写 prometheus.yml 很快就会失控。Prometheus Operator 用 CRD 管理采集目标和告警规则,改一行 YAML 就能加一个抓取项。代价是多一层抽象,出了问题要理解 CRD 到最终配置的转换链路。我的建议:K8s 集群超过一个团队在用就上 Operator,单机或两三台服务器手写配置文件更透明。

常见问题

Prometheus 和 Zabbix 该选哪个?

以云原生、容器化环境为主选 Prometheus,多维标签和 PromQL 对动态实例更友好;以传统物理机、网络设备为主且需要完善的中文界面与开箱即用的模板,Zabbix 上手更快。两者可以并存,各管一部分。

数据保留多久合适?

默认 15 天,多数中小团队够用。保留期越长磁盘压力越大,且单机 TSDB 不建议存超过半年数据。需要长期保存就接 Thanos 或 Mimir 做对象存储后端,Prometheus 本地只留短期数据。

指标突然查不到是什么原因?

先查 up 指标确认目标是否在线,再看抓取间隔与超时配置。常见原因是目标被翻墙代理挡住、exporter 端口未暴露,或标签变更导致时间序列断裂——Prometheus 用标签集标识序列,标签一变就是新序列,历史数据不会接上。