Prometheus

一、Prometheus 概念

Prometheus 是一个开源的系统监控 和告警工具包。Prometheus 将其指标作为时序数据进行收集和存储,即指标信息与记录的时间戳一起存储,同时还包含称为标签的可选键值对。

1. 特性

  • 多维数据模型,通过指标名称和键/值对标识时序数据
  • PromQL ,一种灵活的查询语言,可利用这种多维性
  • 不依赖分布式存储;单个服务器节点是自治的
  • 通过 HTTP 的**拉取(pull)**模型进行时序数据收集
  • 支持通过中间网关推送(push)时序数据
  • 通过服务发现或静态配置发现目标
  • 支持多种图形和仪表盘模式

2. 什么是指标?

指标就是数值测量。时序:随时间变化的记录

用户想要测量的内容因应用程序而异。对于 Web 服务器,可能是请求时间;对于数据库,可能是活动连接数或活动查询数等等。

3. 架构

#mermaid-svg-5uxMIJkNR9ffFZej{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-5uxMIJkNR9ffFZej .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-5uxMIJkNR9ffFZej .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-5uxMIJkNR9ffFZej .error-icon{fill:#552222;}#mermaid-svg-5uxMIJkNR9ffFZej .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5uxMIJkNR9ffFZej .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-5uxMIJkNR9ffFZej .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5uxMIJkNR9ffFZej .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5uxMIJkNR9ffFZej .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-5uxMIJkNR9ffFZej .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5uxMIJkNR9ffFZej .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5uxMIJkNR9ffFZej .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5uxMIJkNR9ffFZej .marker.cross{stroke:#333333;}#mermaid-svg-5uxMIJkNR9ffFZej svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5uxMIJkNR9ffFZej p{margin:0;}#mermaid-svg-5uxMIJkNR9ffFZej .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-5uxMIJkNR9ffFZej .cluster-label text{fill:#333;}#mermaid-svg-5uxMIJkNR9ffFZej .cluster-label span{color:#333;}#mermaid-svg-5uxMIJkNR9ffFZej .cluster-label span p{background-color:transparent;}#mermaid-svg-5uxMIJkNR9ffFZej .label text,#mermaid-svg-5uxMIJkNR9ffFZej span{fill:#333;color:#333;}#mermaid-svg-5uxMIJkNR9ffFZej .node rect,#mermaid-svg-5uxMIJkNR9ffFZej .node circle,#mermaid-svg-5uxMIJkNR9ffFZej .node ellipse,#mermaid-svg-5uxMIJkNR9ffFZej .node polygon,#mermaid-svg-5uxMIJkNR9ffFZej .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5uxMIJkNR9ffFZej .rough-node .label text,#mermaid-svg-5uxMIJkNR9ffFZej .node .label text,#mermaid-svg-5uxMIJkNR9ffFZej .image-shape .label,#mermaid-svg-5uxMIJkNR9ffFZej .icon-shape .label{text-anchor:middle;}#mermaid-svg-5uxMIJkNR9ffFZej .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-5uxMIJkNR9ffFZej .rough-node .label,#mermaid-svg-5uxMIJkNR9ffFZej .node .label,#mermaid-svg-5uxMIJkNR9ffFZej .image-shape .label,#mermaid-svg-5uxMIJkNR9ffFZej .icon-shape .label{text-align:center;}#mermaid-svg-5uxMIJkNR9ffFZej .node.clickable{cursor:pointer;}#mermaid-svg-5uxMIJkNR9ffFZej .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-5uxMIJkNR9ffFZej .arrowheadPath{fill:#333333;}#mermaid-svg-5uxMIJkNR9ffFZej .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-5uxMIJkNR9ffFZej .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-5uxMIJkNR9ffFZej .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5uxMIJkNR9ffFZej .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-5uxMIJkNR9ffFZej .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5uxMIJkNR9ffFZej .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-5uxMIJkNR9ffFZej .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-5uxMIJkNR9ffFZej .cluster text{fill:#333;}#mermaid-svg-5uxMIJkNR9ffFZej .cluster span{color:#333;}#mermaid-svg-5uxMIJkNR9ffFZej div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-5uxMIJkNR9ffFZej .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-5uxMIJkNR9ffFZej rect.text{fill:none;stroke-width:0;}#mermaid-svg-5uxMIJkNR9ffFZej .icon-shape,#mermaid-svg-5uxMIJkNR9ffFZej .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5uxMIJkNR9ffFZej .icon-shape p,#mermaid-svg-5uxMIJkNR9ffFZej .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-5uxMIJkNR9ffFZej .icon-shape .label rect,#mermaid-svg-5uxMIJkNR9ffFZej .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5uxMIJkNR9ffFZej .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-5uxMIJkNR9ffFZej .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-5uxMIJkNR9ffFZej :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-5uxMIJkNR9ffFZej .collect>*{fill:#e3f2fd!important;stroke:#1e88e5!important;stroke-width:2px!important;}#mermaid-svg-5uxMIJkNR9ffFZej .collect span{fill:#e3f2fd!important;stroke:#1e88e5!important;stroke-width:2px!important;}#mermaid-svg-5uxMIJkNR9ffFZej .mem>*{fill:#fff8e1!important;stroke:#fbc02d!important;stroke-width:2px!important;}#mermaid-svg-5uxMIJkNR9ffFZej .mem span{fill:#fff8e1!important;stroke:#fbc02d!important;stroke-width:2px!important;}#mermaid-svg-5uxMIJkNR9ffFZej .crash>*{fill:#fce4ec!important;stroke:#d81b60!important;stroke-width:2px!important;stroke-dasharray:4 4!important;}#mermaid-svg-5uxMIJkNR9ffFZej .crash span{fill:#fce4ec!important;stroke:#d81b60!important;stroke-width:2px!important;stroke-dasharray:4 4!important;}#mermaid-svg-5uxMIJkNR9ffFZej .storage>*{fill:#f3e5f5!important;stroke:#8e24aa!important;stroke-width:2px!important;}#mermaid-svg-5uxMIJkNR9ffFZej .storage span{fill:#f3e5f5!important;stroke:#8e24aa!important;stroke-width:2px!important;} 重放
还原数据
📊 数据采集

Scrape Metrics
🧠 写入内存

Memory Block

(当前活动块)
📝 写入 WAL

Write-Ahead Log

(128MB 段文件)
🔄 系统崩溃恢复

WAL Replay
⏰ 2小时后触发

Block Compaction
💾 持久化到磁盘

2-hour Block

(chunks + index + metadata)
📦 后台压缩

Background Compaction

(合并为更大的块)
🏛️ 长期存储

Long-term Blocks

(最长31天或保留期10%)

1.Prometheus Server

  • Retrieval(抓取模块):定期通过 HTTP **pull(拉)**指标
  • TSDB(时序数据库):存储监控数据
  • HTTP Server:提供查询 API + Web UI

2.Service Discovery

  • 自动发现要监控谁

3.Exporters / Jobs(数据来源)

  • 各种 exporter(如 node_exporter、mysql_exporter)
  • 业务服务自身暴露 /metrics

4.Pushgateway

  • 给 短生命周期任务(Short-lived jobs) 用,比如批处理、定时任务(cron job)

  • 流程:任务结束后把指标push到Pushgateway,Prometheus 再去 pull Pushgateway

Pushgateway(让短任务也能被监控):job → Pushgateway → Prometheus pull。解决任务结束太快,抓不到指标(监控数据会推送到Pushgateway,保存在内存,等Prometheus 来 pull,然后保存TSDB)

5.Alertmanager(告警系统)

  • 接收 Prometheus 发来的 alerts(做分组、去重、静默、路由)然后通知:PagerDuty、Email
  • 核心:告警治理中心

Prometheus 定期拉各个服务的指标 → 存储 → 查询 → 触发告警 → Alertmanager 负责通知

Prometheus 从插桩任务抓取指标 ,或者通过中间推送网关抓取短期任务的指标。它在本地存储所有抓取的样本,并对这些数据运行规则,以便从现有数据聚合和记录新的时序数据,或者生成告警。可以使用 Grafana 或其他 API 消费者来可视化收集的数据。

使用场景

  • 监控 数值型指标
  • 微服务 / 云原生:k8s或微服务中服务可能很多,实例动态变化,Prometheus 自动发现服务、多维度标签(label)
  • 故障排查:系统挂了也能看历史数据
  • 报警系统

不适用

  • 绝对精确的数据(Prometheus是采样+拉取模式(可能会丢数据))
  • 计费系统(计费系统要求百分百精确)
  • 日志 / 大文本 (只存数值,不存日志内容)
  • 不适合长期大规模存储 (Prometheus 本地 TSDB、不适合存几年数据)

4. Prometheus 指标类型

  1. Counter:累积计数器 ,只能增加或重置为零,适合统计请求总数、错误次数等单调递增的指标。
  2. Gauge:仪表盘类型 ,数值可以任意上下波动,适合记录当前状态值,比如内存使用量、当前在线用户数、队列长度等。
  3. Histogram:直方图类型,用于观察数据分布情况,比如请求响应时间的分布。它会自动生成多个时间序列,包括各个桶的计数、总和以及总数,可以用来计算百分位数等统计指标。
  4. Summary:和 Histogram 类似,但它在客户端预先计算百分位数,适合需要精确百分位数计算但对网络传输有要求的场景。

5. 监控数据分类

  1. 系统指标(Infrastructure Metrics):CPU、内存、磁盘 I/O。属于底层物理状态。
  2. 应用指标(Application Metrics):QPS、响应时间(RT)、错误率。属于服务健康状态。
  3. 业务指标(Business Metrics):AI 调用次数、Token 消耗量、活跃用户数。属于钱和用户体验层面的数据。
  4. 调用链(Distributed Tracing):跨越多个服务、多个进程的请求轨迹。

调用链里的核心术语(Trace vs Span)

Trace(整条链路) :代表你从北京飞到巴黎的完整旅程。

Span(操作单元) :代表旅程中的具体单步操作。比如:

  • Span 1: 北京打车去机场。
  • Span 2: 机场安检排队。
  • Span 3: 飞机在空中飞行。

渲染错误: Mermaid 渲染失败: Invalid date:800ms) : 0

指标 (Prometheus):看系统是不是还活着(概览)。

日志 (ES + Kibana):看系统挂掉的那一刻打印了什么(细节)。

追踪 (Trace + Span):看请求卡在哪个微服务、哪个数据库查询上(定位瓶颈)。

6. 百分位数

  • P50 :中位数。表示 50% 的请求响应时间都在这个值以下。
  • P75:表示 75% 的请求响应时间都在这个值以下。
  • P90:表示 90%的请求响应时间都在这个值以下。
  • P99:表示 99% 的请求响应时间都在这个值以下。

例如:一个接口的 P99 响应时间是 500ms,这意味着 99%的请求都能在 500ms 内完成,只有 1% 的请求可能超过这个时间。

Prometheus 中,百分位数通常是通过 Histogram(直方图) 类型指标结合 histogram_quantile 函数计算出来的估算值:

bash 复制代码
# 计算过去 5 分钟内,HTTP 请求耗时的 P99 (0.99)
histogram_quantile(
  0.99, 
  sum by (le) (rate(http_request_duration_seconds_bucket[5m]))
)

7. 可观测性方法论

**1. 统计什么?**需要根据业务特点确定关键指标,既要覆盖 系统层面 的通用指标,也要包含 业务特有 的监控维度。

**2. 如何收集?**数据收集是可观测性的基础,可以通过代码埋点、探针技术、日志分析等多种方式实现。

**3. 如何存储?**监控数据通常量大且连续,需要选择合适的存储方案,比如时序数据库或专门的监控系统。

  • 时序数据(指标):Prometheus TSDB。
  • 文本数据(日志):Elasticsearch(ES)。
  • 海量持久化(存储):Ceph。

**4. 如何展示?**最终需要通过直观的图表和仪表板将数据呈现给用户,一般会实时监控(页面自动刷新)。

  • 大屏展示:Grafana(对接 Prometheus 数据源)。
  • 日志检索:Kibana(对接 ES 数据源)。

二、常见术语

采集 → 存储 → 查询 → 告警

1. 数据核心

1.时间序列(Time Series) :指标名 + 标签集合(http_requests_total{method="GET",status="200"}),<metric name>{<label name>="<label value>", ...}

2.样本(Sample):时间序列中的一个点,某一时刻的值

3.标签(Label):用来区分数据维度的键值对,分组过滤

2. 数据怎么来的

1.Exporter :翻译器,把系统数据----->转换成Prometheus 格式

2.Client Library :埋点SDK,在代码里直接打指标,http_requests_total++,类似代码里打日志

3.Endpoint(抓取点):一个Http地址:http://ip:port/metrics,Prometheus 就是访问这里拿数据

4.Target(目标): Prometheus 要抓的一个具体对象

5.Job(任务):一组 target 的集合,job = 一类服务

6.Instance(实例): job中的单机器,通常是一个进程

3.告警体系

1.Alert(告警): Prometheus 根据规则触发,例如CPU > 80%

2.Alertmanager :告警调度中心,功能分组、去重、路由、静默

3.Notification(通知):最终发出去的消息

4.Silence(静默):临时屏蔽告警,告警仍存在,但不发送通知

在 Prometheus 中,instance 表示一个具体的抓取目标(通常是一个进程),job 是一组具有相同功能的 instance。Prometheus 在抓取时会自动为所有时间序列添加 job 和 instance 标签,用于标识数据来源。同时,每次抓取还会生成如 up、scrape_duration_seconds 等内部指标,用于监控抓取本身的健康状态。最终数据:metric_name{job=..., instance=..., 其他标签...}

三、配置文件结构

文件 作用
prometheus.yml (采集层:去哪拿数据) 抓谁(采集配置)
rules.yml (计算告警层:拿到数据后要干嘛) 怎么算 / 怎么告警

Prometheus 的配置采用 YAML 格式,prometheus.yml

1.三个配置块

yaml 复制代码
global:
  scrape_interval:     15s  #控制 Prometheus 抓取目标的频率
  evaluation_interval: 15s  #控制 Prometheus 评估规则的频率

rule_files:
  # - "first.rules"
  # - "second.rules"

scrape_configs:   #控制 Prometheus 监控哪些资源
  - job_name: prometheus  #任务名
    static_configs:
      - targets: ['localhost:9090']

有三个配置块:global、rule_files 和 scrape_configs。

  • global 块控制 Prometheus 服务器的全局配置 。 scrape_interval,控制 Prometheus 抓取目标的频率。``evaluation_interval` 选项控制 Prometheus 评估规则的频率。Prometheus 使用规则来创建新的时间序列并生成告警。

  • rule_files 块加载规则文件的位置

  • scrape_configs 控制 Prometheus 监控哪些资源 。Prometheus 会通过 HTTP 端点公开自身的数据。期望监控指标:https://:9090/metrics。

bash 复制代码
./prometheus --config.file=prometheus.yml  #启动命令

#或者启动脚本
@echo off
REM 启动 Prometheus
prometheus.exe --config.file=prometheus.yml
REM 保持命令窗口打开,以查看输出
pause

node_exporter:采集服务器资源指标的工具,把操作系统的运行状态 → 转成 Prometheus 能读的数据

2.配置案例

prometheus.yaml

yaml 复制代码
# ==========全局配置===============
global:
  scrape_interval: 15s        # 全局默认抓取间隔(Prometheus 每 15 秒去拉一次指标)
  evaluation_interval: 15s    # 告警规则评估间隔(每 15 秒计算一次告警表达式)

  # 给所有时间序列自动添加的标签(用于区分不同 Prometheus 实例)
  external_labels:
    monitor: 'codelab-monitor'


# =========================
# 规则文件(告警 / 记录规则)
# =========================
rule_files:
  - 'prometheus.rules.yml'   # 定义告警规则(Alert)或记录规则(Recording Rule)

# =========抓取配置(核心)================
scrape_configs:

  # -------------------------
  # 1. 监控 Prometheus 自身
  # -------------------------
  - job_name: 'prometheus'   # job 名称(服务分类)
    scrape_interval: 5s      # 覆盖全局配置:每 5 秒抓一次(更高频监控自己)
    static_configs:
      - targets: ['localhost:9090']   # Prometheus 自己的 metrics 地址
                                      # 实际抓取:http://localhost:9090/metrics


  # -------------------------
  # 2. 监控节点 / 服务(你自定义的)
  # -------------------------
  - job_name: 'node'         # 表示一类服务(比如 node_exporter / 应用)
    scrape_interval: 5s      # 每 5 秒抓取一次(比默认更频繁)
    static_configs:
      # ===== 第一组:生产环境 =====
      - targets: ['localhost:8080', 'localhost:8081']
        labels:
          group: 'production'   # 自定义标签:标识这是生产环境
      # ===== 第二组:灰度 / 金丝雀环境 =====
      - targets: ['localhost:8082']
        labels:
          group: 'canary'       # 自定义标签:标识这是测试/灰度环境
```

prometheus.rules.yml

yaml 复制代码
groups:
# 如果某个实例 up == 0 持续 1 分钟 → 触发告警
  - name: example-alert
    rules:
      - alert: InstanceDown  #告警名字
        expr: up == 0        #PromQL 条件
        for: 1m              #持续多久才触发
        
        labels:            #附加消息,如严重级别
          severity: critical

        annotations:                    #告警描述
          summary: "实例挂了"
          description: "{{$labels.instance}} 已经 1 分钟不可访问"
          
  #记录规则,生成派生时间序列
  - name: example-record
    rules:
      - record: job:http_requests:rate5m
        expr: rate(http_requests_total[5m])
        
        
  - name: system-metrics
  interval: 30s

  rules:
  # ===== Recording Rule =====
  - record: instance:cpu_usage:rate5m
    expr: |
      100 - avg by(instance)(
        rate(node_cpu_seconds_total{mode="idle"}[5m])
      ) * 100

  # ===== Alert Rule =====
  - alert: HighCPU
    expr: instance:cpu_usage:rate5m > 80
    for: 2m

    labels:
      severity: warning

    annotations:
      summary: "CPU 使用率过高"
      description: "{{ $labels.instance }} CPU > 80%"

**规则可以热加载:**修改 rules.yml,不用重启 Prometheus,立即生效

bash 复制代码
curl -X POST http://localhost:9090/-/reload

派生时间序列:根据现有的时间序列计算出的新指标

四、规则

Prometheus 支持两种类型的规则,可以进行配置并定期评估:记录规则 和告警规则

1. 记录规则(Recording Rule)

记录规则:给复杂 PromQL 起一个缓存后的新指标名(提前算好,存起来)

cpu.rules.yml

yaml 复制代码
groups:
  - name: cpu_rules
    interval: 15s
    rules:
      - record: instance:cpu_usage:rate5m   
        expr: avg by (instance) (
          rate(node_cpu_seconds_total{mode!="idle"}[5m])
        )

record 推荐格式:level:metric:operation 级别:指标:操作 instance:cpu_usage:rate5m

prometheus.yml引入

yaml 复制代码
rule_files:
  - "rules/cpu.rules.yml"

重载

bash 复制代码
curl -X POST http://localhost:9090/-/reload

查询

bash 复制代码
instance:cpu_usage:rate5m  #不用写复杂表达式,查询速度快	

原理:每个时间间隔执行一次计算写入TSDB,最终变成一个普通指标,只要查普通指标

2. 告警规则(Alerting Rule)

告警规则:基于 Prometheus 表达式语言定义告警条件,并将触发告警的通知发送到外部服务

流程:
#mermaid-svg-0s7j7wyLWJ5Bk9QS{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-0s7j7wyLWJ5Bk9QS .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .error-icon{fill:#552222;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .marker.cross{stroke:#333333;}#mermaid-svg-0s7j7wyLWJ5Bk9QS svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0s7j7wyLWJ5Bk9QS p{margin:0;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .cluster-label text{fill:#333;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .cluster-label span{color:#333;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .cluster-label span p{background-color:transparent;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .label text,#mermaid-svg-0s7j7wyLWJ5Bk9QS span{fill:#333;color:#333;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .node rect,#mermaid-svg-0s7j7wyLWJ5Bk9QS .node circle,#mermaid-svg-0s7j7wyLWJ5Bk9QS .node ellipse,#mermaid-svg-0s7j7wyLWJ5Bk9QS .node polygon,#mermaid-svg-0s7j7wyLWJ5Bk9QS .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .rough-node .label text,#mermaid-svg-0s7j7wyLWJ5Bk9QS .node .label text,#mermaid-svg-0s7j7wyLWJ5Bk9QS .image-shape .label,#mermaid-svg-0s7j7wyLWJ5Bk9QS .icon-shape .label{text-anchor:middle;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .rough-node .label,#mermaid-svg-0s7j7wyLWJ5Bk9QS .node .label,#mermaid-svg-0s7j7wyLWJ5Bk9QS .image-shape .label,#mermaid-svg-0s7j7wyLWJ5Bk9QS .icon-shape .label{text-align:center;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .node.clickable{cursor:pointer;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .arrowheadPath{fill:#333333;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-0s7j7wyLWJ5Bk9QS .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0s7j7wyLWJ5Bk9QS .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-0s7j7wyLWJ5Bk9QS .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .cluster text{fill:#333;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .cluster span{color:#333;}#mermaid-svg-0s7j7wyLWJ5Bk9QS div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-0s7j7wyLWJ5Bk9QS rect.text{fill:none;stroke-width:0;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .icon-shape,#mermaid-svg-0s7j7wyLWJ5Bk9QS .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .icon-shape p,#mermaid-svg-0s7j7wyLWJ5Bk9QS .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .icon-shape .label rect,#mermaid-svg-0s7j7wyLWJ5Bk9QS .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0s7j7wyLWJ5Bk9QS .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-0s7j7wyLWJ5Bk9QS :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .prom>*{fill:#e1f5fe!important;stroke:#01579b!important;stroke-width:2px!important;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .prom span{fill:#e1f5fe!important;stroke:#01579b!important;stroke-width:2px!important;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .am>*{fill:#fff8e1!important;stroke:#ff8f00!important;stroke-width:2px!important;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .am span{fill:#fff8e1!important;stroke:#ff8f00!important;stroke-width:2px!important;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .notify>*{fill:#e8f5e9!important;stroke:#1b5e20!important;stroke-width:2px!important;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .notify span{fill:#e8f5e9!important;stroke:#1b5e20!important;stroke-width:2px!important;} Alertmanager 内部管道处理

  1. 查询数据
  2. 触发阈值
    条件满足但小于 for 时间
    满足时间持续达到 for
  3. 发送告警 API
  4. 满足路由规则
  5. 钉钉
  6. Slack
  7. 邮件
    时序数据库 TSDB
    计算 PromQL Expr
    状态评估
    Pending 挂起
    Firing 激活
    Alertmanager
  8. 抑制 Inhibit
  9. 静默 Silence
  10. 分组 Group
  11. 去重 Deduplicate
    Webhook / 接收器
    钉钉机器人
    Slack Channel
    SMTP 邮件
txt 复制代码
Prometheus 计算 expr
        ↓
生成告警(pending / firing)
        ↓
发送给 Alertmanager
        ↓
分组 / 去重 / 抑制 / 静默
        ↓
发通知(钉钉 / Slack / 邮件)

案例

yaml 复制代码
groups:
- name: app_alerts
  rules:
  - alert: HighCPUUsage
    expr: avg by (pod) (
      rate(container_cpu_usage_seconds_total{image!=""}[5m])
    ) > 0.8  #布尔值
    for: 5m               #必须连续5分钟都满足条件才报警 在触发前用
    keep_firing_for: 5m   #在恢复后用
    labels:
      severity: warning
    annotations:
      summary: "Pod CPU 过高"
      description: "{{ $labels.pod }} CPU 超过 80%,当前值 {{ $value }}"
  • for 控制报警要不要触发 ,告警必须要加for,避免误报

  • keep_firing_for 告警恢复后,继续保持告警状态的时间,避免告警风暴

txt 复制代码
原始指标 (node_cpu...)
        ↓
记录规则(预计算)
        ↓
新指标(pod:cpu_usage:rate5m)
        ↓
告警规则(判断)
        ↓
Alertmanager(通知)

记录规则:算结果出来

告警规则:从结果中挑需要的出来

五、Agent Mode

Prometheus Agent :只负责 采集 + 转发 的轻量版 Prometheus, Agent Mode :采集器(collector)

功能 普通 Prometheus Agent Mode
抓取(scrape) ✅ ✅
本地存储(TSDB) ✅ ❌(只有临时 WAL)
查询(PromQL) ✅ ❌
记录规则 ✅ ❌
告警规则 ✅ ❌
Remote Write ✅ ✅(核心功能)

解决的问题

传统普罗米修斯的问题,大规模环境(比如 Kubernetes 多集群):每个节点都跑完整 Prometheus → 太重,数据分散 → 没有全局视图,运维复杂

1. Agent Mode 的思路

#mermaid-svg-RlRkReUkD05V8ICk{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-RlRkReUkD05V8ICk .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-RlRkReUkD05V8ICk .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-RlRkReUkD05V8ICk .error-icon{fill:#552222;}#mermaid-svg-RlRkReUkD05V8ICk .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-RlRkReUkD05V8ICk .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-RlRkReUkD05V8ICk .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-RlRkReUkD05V8ICk .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-RlRkReUkD05V8ICk .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-RlRkReUkD05V8ICk .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-RlRkReUkD05V8ICk .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-RlRkReUkD05V8ICk .marker{fill:#333333;stroke:#333333;}#mermaid-svg-RlRkReUkD05V8ICk .marker.cross{stroke:#333333;}#mermaid-svg-RlRkReUkD05V8ICk svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-RlRkReUkD05V8ICk p{margin:0;}#mermaid-svg-RlRkReUkD05V8ICk .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-RlRkReUkD05V8ICk .cluster-label text{fill:#333;}#mermaid-svg-RlRkReUkD05V8ICk .cluster-label span{color:#333;}#mermaid-svg-RlRkReUkD05V8ICk .cluster-label span p{background-color:transparent;}#mermaid-svg-RlRkReUkD05V8ICk .label text,#mermaid-svg-RlRkReUkD05V8ICk span{fill:#333;color:#333;}#mermaid-svg-RlRkReUkD05V8ICk .node rect,#mermaid-svg-RlRkReUkD05V8ICk .node circle,#mermaid-svg-RlRkReUkD05V8ICk .node ellipse,#mermaid-svg-RlRkReUkD05V8ICk .node polygon,#mermaid-svg-RlRkReUkD05V8ICk .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-RlRkReUkD05V8ICk .rough-node .label text,#mermaid-svg-RlRkReUkD05V8ICk .node .label text,#mermaid-svg-RlRkReUkD05V8ICk .image-shape .label,#mermaid-svg-RlRkReUkD05V8ICk .icon-shape .label{text-anchor:middle;}#mermaid-svg-RlRkReUkD05V8ICk .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-RlRkReUkD05V8ICk .rough-node .label,#mermaid-svg-RlRkReUkD05V8ICk .node .label,#mermaid-svg-RlRkReUkD05V8ICk .image-shape .label,#mermaid-svg-RlRkReUkD05V8ICk .icon-shape .label{text-align:center;}#mermaid-svg-RlRkReUkD05V8ICk .node.clickable{cursor:pointer;}#mermaid-svg-RlRkReUkD05V8ICk .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-RlRkReUkD05V8ICk .arrowheadPath{fill:#333333;}#mermaid-svg-RlRkReUkD05V8ICk .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-RlRkReUkD05V8ICk .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-RlRkReUkD05V8ICk .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-RlRkReUkD05V8ICk .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-RlRkReUkD05V8ICk .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-RlRkReUkD05V8ICk .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-RlRkReUkD05V8ICk .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-RlRkReUkD05V8ICk .cluster text{fill:#333;}#mermaid-svg-RlRkReUkD05V8ICk .cluster span{color:#333;}#mermaid-svg-RlRkReUkD05V8ICk div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-RlRkReUkD05V8ICk .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-RlRkReUkD05V8ICk rect.text{fill:none;stroke-width:0;}#mermaid-svg-RlRkReUkD05V8ICk .icon-shape,#mermaid-svg-RlRkReUkD05V8ICk .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-RlRkReUkD05V8ICk .icon-shape p,#mermaid-svg-RlRkReUkD05V8ICk .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-RlRkReUkD05V8ICk .icon-shape .label rect,#mermaid-svg-RlRkReUkD05V8ICk .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-RlRkReUkD05V8ICk .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-RlRkReUkD05V8ICk .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-RlRkReUkD05V8ICk :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-RlRkReUkD05V8ICk .edge>*{fill:#e1f5fe!important;stroke:#01579b!important;stroke-width:2px!important;}#mermaid-svg-RlRkReUkD05V8ICk .edge span{fill:#e1f5fe!important;stroke:#01579b!important;stroke-width:2px!important;}#mermaid-svg-RlRkReUkD05V8ICk .center>*{fill:#e8f5e9!important;stroke:#1b5e20!important;stroke-width:2px!important;}#mermaid-svg-RlRkReUkD05V8ICk .center span{fill:#e8f5e9!important;stroke:#1b5e20!important;stroke-width:2px!important;}#mermaid-svg-RlRkReUkD05V8ICk .ui>*{fill:#fff8e1!important;stroke:#ff8f00!important;stroke-width:2px!important;}#mermaid-svg-RlRkReUkD05V8ICk .ui span{fill:#fff8e1!important;stroke:#ff8f00!important;stroke-width:2px!important;} 统一观测与告警
监控中心 / 中央存储
边缘/各 K8s 节点集群
Remote Write
历史冷数据
PromQL 查询
评估规则
飞书/邮件/微信
应用 A /metrics
Prometheus Agent
应用 B /metrics
WAL 本地盘
中央网关/分发器
时序数据库 Mimir/Thanos/Cortex
对象存储 S3/MinIO
Grafana 面板
Alertmanager 告警
运维人员

txt 复制代码
每个节点:Prometheus Agent(只采集)
        ↓
Remote Write
        ↓
中心:Prometheus / Thanos / Cortex / Mimir
        ↓
统一查询 + 告警

边缘采集 + 中心分析

工作流程
#mermaid-svg-5FjOOUW5RtcxQ5gW{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-5FjOOUW5RtcxQ5gW .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-5FjOOUW5RtcxQ5gW .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-5FjOOUW5RtcxQ5gW .error-icon{fill:#552222;}#mermaid-svg-5FjOOUW5RtcxQ5gW .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5FjOOUW5RtcxQ5gW .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-5FjOOUW5RtcxQ5gW .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5FjOOUW5RtcxQ5gW .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5FjOOUW5RtcxQ5gW .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-5FjOOUW5RtcxQ5gW .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5FjOOUW5RtcxQ5gW .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5FjOOUW5RtcxQ5gW .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5FjOOUW5RtcxQ5gW .marker.cross{stroke:#333333;}#mermaid-svg-5FjOOUW5RtcxQ5gW svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5FjOOUW5RtcxQ5gW p{margin:0;}#mermaid-svg-5FjOOUW5RtcxQ5gW .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-5FjOOUW5RtcxQ5gW .cluster-label text{fill:#333;}#mermaid-svg-5FjOOUW5RtcxQ5gW .cluster-label span{color:#333;}#mermaid-svg-5FjOOUW5RtcxQ5gW .cluster-label span p{background-color:transparent;}#mermaid-svg-5FjOOUW5RtcxQ5gW .label text,#mermaid-svg-5FjOOUW5RtcxQ5gW span{fill:#333;color:#333;}#mermaid-svg-5FjOOUW5RtcxQ5gW .node rect,#mermaid-svg-5FjOOUW5RtcxQ5gW .node circle,#mermaid-svg-5FjOOUW5RtcxQ5gW .node ellipse,#mermaid-svg-5FjOOUW5RtcxQ5gW .node polygon,#mermaid-svg-5FjOOUW5RtcxQ5gW .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5FjOOUW5RtcxQ5gW .rough-node .label text,#mermaid-svg-5FjOOUW5RtcxQ5gW .node .label text,#mermaid-svg-5FjOOUW5RtcxQ5gW .image-shape .label,#mermaid-svg-5FjOOUW5RtcxQ5gW .icon-shape .label{text-anchor:middle;}#mermaid-svg-5FjOOUW5RtcxQ5gW .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-5FjOOUW5RtcxQ5gW .rough-node .label,#mermaid-svg-5FjOOUW5RtcxQ5gW .node .label,#mermaid-svg-5FjOOUW5RtcxQ5gW .image-shape .label,#mermaid-svg-5FjOOUW5RtcxQ5gW .icon-shape .label{text-align:center;}#mermaid-svg-5FjOOUW5RtcxQ5gW .node.clickable{cursor:pointer;}#mermaid-svg-5FjOOUW5RtcxQ5gW .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-5FjOOUW5RtcxQ5gW .arrowheadPath{fill:#333333;}#mermaid-svg-5FjOOUW5RtcxQ5gW .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-5FjOOUW5RtcxQ5gW .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-5FjOOUW5RtcxQ5gW .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5FjOOUW5RtcxQ5gW .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-5FjOOUW5RtcxQ5gW .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5FjOOUW5RtcxQ5gW .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-5FjOOUW5RtcxQ5gW .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-5FjOOUW5RtcxQ5gW .cluster text{fill:#333;}#mermaid-svg-5FjOOUW5RtcxQ5gW .cluster span{color:#333;}#mermaid-svg-5FjOOUW5RtcxQ5gW div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-5FjOOUW5RtcxQ5gW .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-5FjOOUW5RtcxQ5gW rect.text{fill:none;stroke-width:0;}#mermaid-svg-5FjOOUW5RtcxQ5gW .icon-shape,#mermaid-svg-5FjOOUW5RtcxQ5gW .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5FjOOUW5RtcxQ5gW .icon-shape p,#mermaid-svg-5FjOOUW5RtcxQ5gW .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-5FjOOUW5RtcxQ5gW .icon-shape .label rect,#mermaid-svg-5FjOOUW5RtcxQ5gW .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5FjOOUW5RtcxQ5gW .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-5FjOOUW5RtcxQ5gW .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-5FjOOUW5RtcxQ5gW :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-5FjOOUW5RtcxQ5gW .app>*{fill:#f9f!important;stroke:#333!important;stroke-width:2px!important;}#mermaid-svg-5FjOOUW5RtcxQ5gW .app span{fill:#f9f!important;stroke:#333!important;stroke-width:2px!important;}#mermaid-svg-5FjOOUW5RtcxQ5gW .agent>*{fill:#bbf!important;stroke:#333!important;stroke-width:2px!important;stroke-dasharray:5 5!important;}#mermaid-svg-5FjOOUW5RtcxQ5gW .agent span{fill:#bbf!important;stroke:#333!important;stroke-width:2px!important;stroke-dasharray:5 5!important;}#mermaid-svg-5FjOOUW5RtcxQ5gW .storage>*{fill:#dfd!important;stroke:#333!important;stroke-width:2px!important;}#mermaid-svg-5FjOOUW5RtcxQ5gW .storage span{fill:#dfd!important;stroke:#333!important;stroke-width:2px!important;} 监控远端存储中心
Kubernetes 集群 / 边缘节点

  1. 暂存
  2. 重放
    历史归档
    暴露指标
    Pull 拉取
  3. Remote Write 推送
    应用服务
    HTTP /metrics
    Prometheus Agent
    WAL 本地缓存
    接收器/分发器
    时序数据库 Mimir/Thanos
    对象存储 S3/OSS
tex 复制代码
应用 → /metrics
        ↓
Prometheus Agent(pull)
        ↓
WAL(短暂缓存)
        ↓
Remote Write(push)
        ↓
远端存储(Prometheus / Thanos / Mimir)

2. 核心优势

  • 资源占用极低
  • 水平扩展能力强(要扩容加 Agent 就行)
  • 解耦架构:采集层(Agent) ≠ 存储层(Remote)
  • 支持全局监控( 所有数据汇总到一个中心)

缺点

  • 不能本地查询(本地不能执行PromQL)
  • 不能写记录规则( 必须放到远端系统)
  • 不能告警( Agent 不会发任何告警)

3. 启动Agent

Agent 模式 : 只负责采集 + 转发,不负责存储和计算

bash 复制代码
prometheus --config.file=prometheus.yml --agent
#===========或===========================
prometheus \
  --config.file=prometheus.yml \
  --agent \
  --storage.agent.path=data-agent/   #本地缓存目录,临时存储,用于远程写remote_write

启动一个 Prometheus Agent,只负责采集指标,并通过 remote_write 转发,data-agent/ 用来做临时缓存(WAL),不做长期存储。只有两小时缓存时间

WAL是预写日志,防止系统崩了,内存中的数据也没了

4. 实验

本地采集 node metrics,直接推到中心 Prometheus

Node Exporter → Agent → remote_write → 中央存储

Agent(采集) → 中心 Prometheus(规则 + 告警)
#mermaid-svg-H5tOd6vB3mPemTxU{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-H5tOd6vB3mPemTxU .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-H5tOd6vB3mPemTxU .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-H5tOd6vB3mPemTxU .error-icon{fill:#552222;}#mermaid-svg-H5tOd6vB3mPemTxU .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-H5tOd6vB3mPemTxU .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-H5tOd6vB3mPemTxU .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-H5tOd6vB3mPemTxU .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-H5tOd6vB3mPemTxU .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-H5tOd6vB3mPemTxU .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-H5tOd6vB3mPemTxU .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-H5tOd6vB3mPemTxU .marker{fill:#333333;stroke:#333333;}#mermaid-svg-H5tOd6vB3mPemTxU .marker.cross{stroke:#333333;}#mermaid-svg-H5tOd6vB3mPemTxU svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-H5tOd6vB3mPemTxU p{margin:0;}#mermaid-svg-H5tOd6vB3mPemTxU .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-H5tOd6vB3mPemTxU .cluster-label text{fill:#333;}#mermaid-svg-H5tOd6vB3mPemTxU .cluster-label span{color:#333;}#mermaid-svg-H5tOd6vB3mPemTxU .cluster-label span p{background-color:transparent;}#mermaid-svg-H5tOd6vB3mPemTxU .label text,#mermaid-svg-H5tOd6vB3mPemTxU span{fill:#333;color:#333;}#mermaid-svg-H5tOd6vB3mPemTxU .node rect,#mermaid-svg-H5tOd6vB3mPemTxU .node circle,#mermaid-svg-H5tOd6vB3mPemTxU .node ellipse,#mermaid-svg-H5tOd6vB3mPemTxU .node polygon,#mermaid-svg-H5tOd6vB3mPemTxU .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-H5tOd6vB3mPemTxU .rough-node .label text,#mermaid-svg-H5tOd6vB3mPemTxU .node .label text,#mermaid-svg-H5tOd6vB3mPemTxU .image-shape .label,#mermaid-svg-H5tOd6vB3mPemTxU .icon-shape .label{text-anchor:middle;}#mermaid-svg-H5tOd6vB3mPemTxU .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-H5tOd6vB3mPemTxU .rough-node .label,#mermaid-svg-H5tOd6vB3mPemTxU .node .label,#mermaid-svg-H5tOd6vB3mPemTxU .image-shape .label,#mermaid-svg-H5tOd6vB3mPemTxU .icon-shape .label{text-align:center;}#mermaid-svg-H5tOd6vB3mPemTxU .node.clickable{cursor:pointer;}#mermaid-svg-H5tOd6vB3mPemTxU .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-H5tOd6vB3mPemTxU .arrowheadPath{fill:#333333;}#mermaid-svg-H5tOd6vB3mPemTxU .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-H5tOd6vB3mPemTxU .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-H5tOd6vB3mPemTxU .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-H5tOd6vB3mPemTxU .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-H5tOd6vB3mPemTxU .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-H5tOd6vB3mPemTxU .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-H5tOd6vB3mPemTxU .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-H5tOd6vB3mPemTxU .cluster text{fill:#333;}#mermaid-svg-H5tOd6vB3mPemTxU .cluster span{color:#333;}#mermaid-svg-H5tOd6vB3mPemTxU div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-H5tOd6vB3mPemTxU .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-H5tOd6vB3mPemTxU rect.text{fill:none;stroke-width:0;}#mermaid-svg-H5tOd6vB3mPemTxU .icon-shape,#mermaid-svg-H5tOd6vB3mPemTxU .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-H5tOd6vB3mPemTxU .icon-shape p,#mermaid-svg-H5tOd6vB3mPemTxU .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-H5tOd6vB3mPemTxU .icon-shape .label rect,#mermaid-svg-H5tOd6vB3mPemTxU .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-H5tOd6vB3mPemTxU .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-H5tOd6vB3mPemTxU .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-H5tOd6vB3mPemTxU :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-H5tOd6vB3mPemTxU .exporter>*{fill:#e8f5e9!important;stroke:#2e7d32!important;stroke-width:2px!important;}#mermaid-svg-H5tOd6vB3mPemTxU .exporter span{fill:#e8f5e9!important;stroke:#2e7d32!important;stroke-width:2px!important;}#mermaid-svg-H5tOd6vB3mPemTxU .agent>*{fill:#e1f5fe!important;stroke:#0288d1!important;stroke-width:2px!important;stroke-dasharray:5 5!important;}#mermaid-svg-H5tOd6vB3mPemTxU .agent span{fill:#e1f5fe!important;stroke:#0288d1!important;stroke-width:2px!important;stroke-dasharray:5 5!important;}#mermaid-svg-H5tOd6vB3mPemTxU .center>*{fill:#fff8e1!important;stroke:#f57c00!important;stroke-width:2px!important;}#mermaid-svg-H5tOd6vB3mPemTxU .center span{fill:#fff8e1!important;stroke:#f57c00!important;stroke-width:2px!important;}#mermaid-svg-H5tOd6vB3mPemTxU .storage>*{fill:#eceff1!important;stroke:#455a64!important;stroke-width:2px!important;}#mermaid-svg-H5tOd6vB3mPemTxU .storage span{fill:#eceff1!important;stroke:#455a64!important;stroke-width:2px!important;} 中心端 (监控数据中心)
边缘端 (Windows 本地环境)
暂存/重放
暴露指标

  1. HTTP Pull 拉取
  2. HTTP Post 远程推送
    💻 Windows 物理机

OS 性能计数器
📊 windows_exporter

端口: 9182
🚀 Prometheus Agent

端口: 9091
💾 临时 WAL

data-agent/
📥 Remote Write 接收器

端口: 9090
🗄️ 中心 TSDB

data-center/
📈 Grafana 大屏

可视化展示

目录结构

bash 复制代码
├── prometheus.exe              # 主程序
├── prometheus-agent.yml        # 边缘 Agent 配置文件
├── prometheus-center.yml       # 中心 Server 配置文件
├── data-agent/                 # 边缘 WAL 缓存目录(自动生成)
└── data-center/                # 中心 TSDB 存储目录(自动生成)

边缘端配置文件:prometheus-agent.yml

yaml 复制代码
global:
  scrape_interval: 5s            # 实验期间设置快一点,5秒抓一次
  external_labels:
    cluster: "windows-edge-01"   # 标识数据来自你的 Windows 边缘端

scrape_configs:
  - job_name: "agent-self"
    static_configs:
      - targets: ["localhost:9091"] # 抓取 Agent 自己
  
  # 抓取本地 Windows 的硬件指标
  - job_name: "windows-host-metrics"
    static_configs:
      - targets: ["localhost:9182"] # 对应 windows_exporter 的端口

remote_write:
  - url: "http://localhost:9090/api/v1/write" # 推送到本地 9090 端口(中心端)

中心端配置文件:prometheus-center.yml

yaml 复制代码
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: "center-self"
    static_configs:
      - targets: ["localhost:9090"] # 抓取中心自己

启动三个服务

  • 中心端必须带上 --web.enable-remote-write-receiver 开启接收功能
  • Agent 必须带上 --agent 参数!且修改监听端口(默认是 9090 会冲突)
bash 复制代码
# 启动中心 Prometheus(端口:9090)
prometheus.exe --config.file=prometheus-center.yml --storage.tsdb.path=data-center/ --web.enable-remote-write-receiver 

#启动边缘 Agent(端口:9091)
prometheus.exe --config.file=prometheus-agent.yml --agent --storage.agent.path=data-agent/ --web.listen-address=":9091"

#读取 Windows 的性能计数器---->并转化为 Prometheus 看得懂的指标
windows_exporter.exe  # 默认监听在 9182 端口

访问中心端的 UI 界面:http://localhost:9090 查询中输入up点击执行查看到两台数据

  • up{instance="localhost:9090", job="center-self"}(中心自己抓的)。

  • up{cluster="windows-edge-01", instance="localhost:9091", job="agent-self"}(Agent 抓取后通过 Remote Write 推送过来的!)

查询命令

bash 复制代码
#查看 C 盘剩余空间百分比
windows_logical_disk_free_bytes{volume="C:"} / windows_logical_disk_size_bytes{volume="C:"} * 100

六、PromQL

PromQL: 从 时间序列数据库 里做计算的 SQL

1. 常用函数

官网查询:https://prometheus.io/docs/prometheus/latest/querying/functions/

https://promlabs.com/promql-cheat-sheet/

rate(xxx[时间窗口]):在这个时间窗口内,指标平均每秒增长多少

rate :把 累计计数器 转换成 每秒变化速度

rate( [5m] ):计算 5 分钟内所有点,取平均斜率。适合告警,因为它平滑,不会因为秒级的毛刺误报。

irate( [5m] ):只取 5 分钟内最后两个点 计算瞬时斜率。适合 Dashboard 展示,能敏锐捕捉瞬间的流量尖峰。

函数 含义
rate() 只要 _total 结尾必用 平均每秒增长(最常用)
irate() 看瞬时尖峰,不建议告警 瞬时速率
increase() 一段时间内总增量
sum() 求和(聚合整体指标)
avg() 平均值
max() / min() 最大值 / 最小值
sum by() K8s 必备 按标签分组聚合
topk() 取前 N(找最耗资源)
histogram_quantile() 计算 P95 / P99 延迟
avg_over_time() 时间窗口平均(平滑数据)
max_over_time() 时间窗口最大值(抓峰值)
absent() 告警神器 数据不存在(服务挂了)
场景 用什么
计数器(_total) rate()
总量统计 sum()
分组(pod/node) by()
延迟分析 histogram_quantile()
平滑数据 avg_over_time()
找峰值 max_over_time()
服务消失 absent()
bash 复制代码
rate(http_requests_total[5m])  		 #每秒多少请求
increase(http_requests_total[5m])    #5分钟内总共多少请求

2. 数据类型

类型 含义 示例
Instant Vector(瞬时向量) 某一时刻的数据 http_requests_total
Range Vector (范围向量) 一段时间的数据 http_requests_total[5m]
Scalar(标量) 单个数字,浮点值 5
String 字符串 "abc"

3. 查询

官网案例:https://prometheus.io/docs/prometheus/latest/querying/examples/

Instant Vector

bash 复制代码
http_requests_total    #查询所有 http_requests_total,返回"当前值"
http_requests_total{job="prometheus"}  #带标签过滤
http_requests_total{env=~"prod|test"}   #正则匹配

Range Vector

bash 复制代码
http_requests_total[5m]   #取过去 5 分钟的数据, 这个不能画图必须搭配rate
rate(http_requests_total[5m]) 
sum(rate(http_requests_total[5m]))  #全局 QPS

avg by (instance) (                 #按实例分组,先rate再聚合
  rate(http_requests_total[5m])
)

increase(http_requests_total[5m])  #5分钟内增加了多少

sum by (job) (
  rate(http_requests_total[5m])
)

其它常用

bash 复制代码
http_requests_total offset 5m  #看 5 分钟前的数据

rate(http_requests_total[5m])  #当前 vs 1小时前
/
rate(http_requests_total[5m] offset 1h)

http_requests_total @ 1609746000   #查历史某一刻

rate(http_requests_total[5m])[30m:]  #在过去30分钟内,每个时间点都计算一次最近5分钟的请求速率

七、存储

Prometheus 本地存储 = WAL(防丢) + 内存 Head(当前数据) + Block(2小时文件块) + 后台压缩

数据流

bash 复制代码
采集数据
   ↓
WAL(写前日志)
   ↓
Head(内存 + chunks_head)
   ↓(每2小时)
Block(磁盘文件)
   ↓(后台)
Compaction(合并大块)
====================================================
写入 → WAL(防丢)
     → Head(可查询)
     → Block(落盘)
     → Compaction(优化存储)

#mermaid-svg-3jErtQj2h4Fi7vXF{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-3jErtQj2h4Fi7vXF .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-3jErtQj2h4Fi7vXF .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-3jErtQj2h4Fi7vXF .error-icon{fill:#552222;}#mermaid-svg-3jErtQj2h4Fi7vXF .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-3jErtQj2h4Fi7vXF .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-3jErtQj2h4Fi7vXF .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-3jErtQj2h4Fi7vXF .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-3jErtQj2h4Fi7vXF .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-3jErtQj2h4Fi7vXF .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-3jErtQj2h4Fi7vXF .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-3jErtQj2h4Fi7vXF .marker{fill:#333333;stroke:#333333;}#mermaid-svg-3jErtQj2h4Fi7vXF .marker.cross{stroke:#333333;}#mermaid-svg-3jErtQj2h4Fi7vXF svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-3jErtQj2h4Fi7vXF p{margin:0;}#mermaid-svg-3jErtQj2h4Fi7vXF .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-3jErtQj2h4Fi7vXF .cluster-label text{fill:#333;}#mermaid-svg-3jErtQj2h4Fi7vXF .cluster-label span{color:#333;}#mermaid-svg-3jErtQj2h4Fi7vXF .cluster-label span p{background-color:transparent;}#mermaid-svg-3jErtQj2h4Fi7vXF .label text,#mermaid-svg-3jErtQj2h4Fi7vXF span{fill:#333;color:#333;}#mermaid-svg-3jErtQj2h4Fi7vXF .node rect,#mermaid-svg-3jErtQj2h4Fi7vXF .node circle,#mermaid-svg-3jErtQj2h4Fi7vXF .node ellipse,#mermaid-svg-3jErtQj2h4Fi7vXF .node polygon,#mermaid-svg-3jErtQj2h4Fi7vXF .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-3jErtQj2h4Fi7vXF .rough-node .label text,#mermaid-svg-3jErtQj2h4Fi7vXF .node .label text,#mermaid-svg-3jErtQj2h4Fi7vXF .image-shape .label,#mermaid-svg-3jErtQj2h4Fi7vXF .icon-shape .label{text-anchor:middle;}#mermaid-svg-3jErtQj2h4Fi7vXF .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-3jErtQj2h4Fi7vXF .rough-node .label,#mermaid-svg-3jErtQj2h4Fi7vXF .node .label,#mermaid-svg-3jErtQj2h4Fi7vXF .image-shape .label,#mermaid-svg-3jErtQj2h4Fi7vXF .icon-shape .label{text-align:center;}#mermaid-svg-3jErtQj2h4Fi7vXF .node.clickable{cursor:pointer;}#mermaid-svg-3jErtQj2h4Fi7vXF .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-3jErtQj2h4Fi7vXF .arrowheadPath{fill:#333333;}#mermaid-svg-3jErtQj2h4Fi7vXF .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-3jErtQj2h4Fi7vXF .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-3jErtQj2h4Fi7vXF .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3jErtQj2h4Fi7vXF .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-3jErtQj2h4Fi7vXF .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3jErtQj2h4Fi7vXF .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-3jErtQj2h4Fi7vXF .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-3jErtQj2h4Fi7vXF .cluster text{fill:#333;}#mermaid-svg-3jErtQj2h4Fi7vXF .cluster span{color:#333;}#mermaid-svg-3jErtQj2h4Fi7vXF div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-3jErtQj2h4Fi7vXF .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-3jErtQj2h4Fi7vXF rect.text{fill:none;stroke-width:0;}#mermaid-svg-3jErtQj2h4Fi7vXF .icon-shape,#mermaid-svg-3jErtQj2h4Fi7vXF .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3jErtQj2h4Fi7vXF .icon-shape p,#mermaid-svg-3jErtQj2h4Fi7vXF .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-3jErtQj2h4Fi7vXF .icon-shape .label rect,#mermaid-svg-3jErtQj2h4Fi7vXF .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3jErtQj2h4Fi7vXF .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-3jErtQj2h4Fi7vXF .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-3jErtQj2h4Fi7vXF :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-3jErtQj2h4Fi7vXF .memory>*{fill:#e1f5fe!important;stroke:#01579b!important;stroke-width:2px!important;}#mermaid-svg-3jErtQj2h4Fi7vXF .memory span{fill:#e1f5fe!important;stroke:#01579b!important;stroke-width:2px!important;}#mermaid-svg-3jErtQj2h4Fi7vXF .disk>*{fill:#e8f5e9!important;stroke:#1b5e20!important;stroke-width:2px!important;}#mermaid-svg-3jErtQj2h4Fi7vXF .disk span{fill:#e8f5e9!important;stroke:#1b5e20!important;stroke-width:2px!important;}#mermaid-svg-3jErtQj2h4Fi7vXF .action>*{fill:#fff!important;stroke:#333!important;stroke-width:1px!important;}#mermaid-svg-3jErtQj2h4Fi7vXF .action span{fill:#fff!important;stroke:#333!important;stroke-width:1px!important;} 磁盘持久化层
内存层
拉取
同步写入
每2小时 Cut
指标来源 Exporter
数据采集引擎
Head 内存块
chunks_head 样本
WAL 本地磁盘日志
Block 2小时块
Block 2小时块
Compaction 后台合并
合并后的 Big Block

1. 磁盘目录结构

bash 复制代码
data/
├── 01ABC...        # block(2小时数据)
│   ├── chunks/     # 真正的数据
│   ├── index       # 索引(label → 数据)
│   ├── meta.json   # 元数据
│   └── tombstones  # 删除标记
│
├── wal/            # 写前日志(防崩溃)
├── chunks_head/    # 当前未落盘数据

2. 核心组件

2.1 WAL(Write-Ahead Log)

本质 :防止数据丢失

数据一来先写 WAL,每个文件默认 128MB,至少保留 3 个

作用:就算 Prometheus 崩了,也能恢复数据

2.2 Head(当前数据区)

特点:

  • 在内存中(+ 磁盘映射 chunks_head)

  • 保存 最近 2 小时的数据

这部分数据 还没变成 block

2.3 Block(核心存储单位)

每 2 小时生成一个 block:

tex 复制代码
block/
├── chunks/     时间序列数据(压缩后)
├── index       倒排索引
├── meta.json   时间范围等信息

一个 block: 一段时间的数据快照(默认 2 小时)

2.4 Compaction(压缩)

后台自动做:把多个 2h block 合并,变成更大的 block

最大:≤ 31天 或 retention(保留) 的 10%

3. 删除机制

Prometheus 删除数据时,不会立即删除数据,会写到 tombstones

tombstones = 删除标记

真正删除发生再下一次 compaction(压缩)

WAL:是你的草稿纸,随时记下灵感,怕忘了。

Head:是你的脑子,记着最近 2 小时发生的事,随时可以查。

2h Block:是一本小笔记本。

Compaction:是年底把这些小笔记本装订成合集。

31 天或 10% 限制:合集不能太厚,太厚了书架放不下(内存不够),过期了想撕掉其中一页也很难撕。

4. 数据保留策略

  1. 时间 :--storage.tsdb.retention.time=15d 默认15天
  2. 大小:--storage.tsdb.retention.size=100GB 超过就删旧数据

谁先触发用谁(时间 or 大小)

Prometheus 用 WAL 保证不丢数据,用内存缓存当前数据,每 2 小时切块落盘,再通过 compaction 合并,并按 retention 删除旧数据。

八、Federation

一个 Prometheus 去抓取另一个 Prometheus 的部分指标

Prometheus 暴露一个接口:

复制代码
http://prometheus:9090/federate

专门用于被别的 Prometheus 抓

抓什么数据必须指定

bash 复制代码
match[]={job="prometheus"}
match[]={__name__=~"job:.*"}

配置案例

yaml 复制代码
scrape_configs:
  - job_name: 'federate'
    scrape_interval: 15s

    honor_labels: true   #保留源Prometheus的label,否则会被覆盖
    metrics_path: '/federate'  # 专用接口

    params:
      'match[]':   #过滤规则,必须写,否则会拉全量数据
        - '{job="prometheus"}'
        - '{__name__=~"job:.*"}'

    static_configs:
      - targets:
        - 'source-prometheus-1:9090'
  • 只能拉当前值,当前时刻的样本值
  • 不是远程存储

适用:多机房汇总、全局 dashboard

架构
#mermaid-svg-3ScDrLqd8iTQOTMD{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-3ScDrLqd8iTQOTMD .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-3ScDrLqd8iTQOTMD .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-3ScDrLqd8iTQOTMD .error-icon{fill:#552222;}#mermaid-svg-3ScDrLqd8iTQOTMD .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-3ScDrLqd8iTQOTMD .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-3ScDrLqd8iTQOTMD .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-3ScDrLqd8iTQOTMD .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-3ScDrLqd8iTQOTMD .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-3ScDrLqd8iTQOTMD .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-3ScDrLqd8iTQOTMD .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-3ScDrLqd8iTQOTMD .marker{fill:#333333;stroke:#333333;}#mermaid-svg-3ScDrLqd8iTQOTMD .marker.cross{stroke:#333333;}#mermaid-svg-3ScDrLqd8iTQOTMD svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-3ScDrLqd8iTQOTMD p{margin:0;}#mermaid-svg-3ScDrLqd8iTQOTMD .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-3ScDrLqd8iTQOTMD .cluster-label text{fill:#333;}#mermaid-svg-3ScDrLqd8iTQOTMD .cluster-label span{color:#333;}#mermaid-svg-3ScDrLqd8iTQOTMD .cluster-label span p{background-color:transparent;}#mermaid-svg-3ScDrLqd8iTQOTMD .label text,#mermaid-svg-3ScDrLqd8iTQOTMD span{fill:#333;color:#333;}#mermaid-svg-3ScDrLqd8iTQOTMD .node rect,#mermaid-svg-3ScDrLqd8iTQOTMD .node circle,#mermaid-svg-3ScDrLqd8iTQOTMD .node ellipse,#mermaid-svg-3ScDrLqd8iTQOTMD .node polygon,#mermaid-svg-3ScDrLqd8iTQOTMD .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-3ScDrLqd8iTQOTMD .rough-node .label text,#mermaid-svg-3ScDrLqd8iTQOTMD .node .label text,#mermaid-svg-3ScDrLqd8iTQOTMD .image-shape .label,#mermaid-svg-3ScDrLqd8iTQOTMD .icon-shape .label{text-anchor:middle;}#mermaid-svg-3ScDrLqd8iTQOTMD .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-3ScDrLqd8iTQOTMD .rough-node .label,#mermaid-svg-3ScDrLqd8iTQOTMD .node .label,#mermaid-svg-3ScDrLqd8iTQOTMD .image-shape .label,#mermaid-svg-3ScDrLqd8iTQOTMD .icon-shape .label{text-align:center;}#mermaid-svg-3ScDrLqd8iTQOTMD .node.clickable{cursor:pointer;}#mermaid-svg-3ScDrLqd8iTQOTMD .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-3ScDrLqd8iTQOTMD .arrowheadPath{fill:#333333;}#mermaid-svg-3ScDrLqd8iTQOTMD .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-3ScDrLqd8iTQOTMD .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-3ScDrLqd8iTQOTMD .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3ScDrLqd8iTQOTMD .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-3ScDrLqd8iTQOTMD .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3ScDrLqd8iTQOTMD .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-3ScDrLqd8iTQOTMD .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-3ScDrLqd8iTQOTMD .cluster text{fill:#333;}#mermaid-svg-3ScDrLqd8iTQOTMD .cluster span{color:#333;}#mermaid-svg-3ScDrLqd8iTQOTMD div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-3ScDrLqd8iTQOTMD .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-3ScDrLqd8iTQOTMD rect.text{fill:none;stroke-width:0;}#mermaid-svg-3ScDrLqd8iTQOTMD .icon-shape,#mermaid-svg-3ScDrLqd8iTQOTMD .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3ScDrLqd8iTQOTMD .icon-shape p,#mermaid-svg-3ScDrLqd8iTQOTMD .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-3ScDrLqd8iTQOTMD .icon-shape .label rect,#mermaid-svg-3ScDrLqd8iTQOTMD .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3ScDrLqd8iTQOTMD .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-3ScDrLqd8iTQOTMD .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-3ScDrLqd8iTQOTMD :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 查询 / 聚合层
存储层
边缘层 / 数据采集
Agent
App Metrics
Prometheus Local
remote_write
Thanos / Long-term Storage
Federation /federate
Global Prometheus
Grafana / Alertmanager

例如

tx 复制代码
北京机房 Prometheus
上海机房 Prometheus
深圳机房 Prometheus
        ↓
     Federation
        ↓
   Global Prometheus

Global 只关心:总QPS = 30000,不关心每台机器

九、Pushgateway

1.原理

Pushgateway :把短生命周期任务的指标,临时存起来,等 Prometheus 来拉

Prometheus 默认是Pull 模型(拉模式)。Prometheus → 主动去抓 exporter。特点:服务必须长期存活

有些任务运行几秒就退出了,Prometheus 来不及抓,任务就结束了

Pushgateway 解决方案:任务 → Pushgateway(存起来) → Prometheus(再来拉)

只是一个临时的指标缓存仓库 ,存储的不是历史数据,而是某一时刻的最后值,短任务的最后值缓存器

Pushgateway 内部是:

复制代码
job + instance + metric → 内存存储

类似:

复制代码
backup_job + server1 → task_duration_seconds = 3.5

Pushgateway存储的数据不会自动消失,它不会过期和自动清理,需要手动删除

由于短任务结束后,Pushgateway 会一直保留最后一次的值。如果任务失败了不再上报,Prometheus 依然会拉到旧值,导致误报。

解决方案:在脚本任务结束时,主动调用 API 删除它:

bash 复制代码
# 任务完成后,删除这个 Job 的数据
curl -X DELETE http://localhost:9091/metrics/job/backup_job

数据流
#mermaid-svg-kApBeSZwySAetpSt{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-kApBeSZwySAetpSt .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-kApBeSZwySAetpSt .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-kApBeSZwySAetpSt .error-icon{fill:#552222;}#mermaid-svg-kApBeSZwySAetpSt .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-kApBeSZwySAetpSt .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-kApBeSZwySAetpSt .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-kApBeSZwySAetpSt .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-kApBeSZwySAetpSt .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-kApBeSZwySAetpSt .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-kApBeSZwySAetpSt .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-kApBeSZwySAetpSt .marker{fill:#333333;stroke:#333333;}#mermaid-svg-kApBeSZwySAetpSt .marker.cross{stroke:#333333;}#mermaid-svg-kApBeSZwySAetpSt svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-kApBeSZwySAetpSt p{margin:0;}#mermaid-svg-kApBeSZwySAetpSt .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-kApBeSZwySAetpSt .cluster-label text{fill:#333;}#mermaid-svg-kApBeSZwySAetpSt .cluster-label span{color:#333;}#mermaid-svg-kApBeSZwySAetpSt .cluster-label span p{background-color:transparent;}#mermaid-svg-kApBeSZwySAetpSt .label text,#mermaid-svg-kApBeSZwySAetpSt span{fill:#333;color:#333;}#mermaid-svg-kApBeSZwySAetpSt .node rect,#mermaid-svg-kApBeSZwySAetpSt .node circle,#mermaid-svg-kApBeSZwySAetpSt .node ellipse,#mermaid-svg-kApBeSZwySAetpSt .node polygon,#mermaid-svg-kApBeSZwySAetpSt .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-kApBeSZwySAetpSt .rough-node .label text,#mermaid-svg-kApBeSZwySAetpSt .node .label text,#mermaid-svg-kApBeSZwySAetpSt .image-shape .label,#mermaid-svg-kApBeSZwySAetpSt .icon-shape .label{text-anchor:middle;}#mermaid-svg-kApBeSZwySAetpSt .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-kApBeSZwySAetpSt .rough-node .label,#mermaid-svg-kApBeSZwySAetpSt .node .label,#mermaid-svg-kApBeSZwySAetpSt .image-shape .label,#mermaid-svg-kApBeSZwySAetpSt .icon-shape .label{text-align:center;}#mermaid-svg-kApBeSZwySAetpSt .node.clickable{cursor:pointer;}#mermaid-svg-kApBeSZwySAetpSt .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-kApBeSZwySAetpSt .arrowheadPath{fill:#333333;}#mermaid-svg-kApBeSZwySAetpSt .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-kApBeSZwySAetpSt .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-kApBeSZwySAetpSt .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-kApBeSZwySAetpSt .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-kApBeSZwySAetpSt .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-kApBeSZwySAetpSt .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-kApBeSZwySAetpSt .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-kApBeSZwySAetpSt .cluster text{fill:#333;}#mermaid-svg-kApBeSZwySAetpSt .cluster span{color:#333;}#mermaid-svg-kApBeSZwySAetpSt div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-kApBeSZwySAetpSt .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-kApBeSZwySAetpSt rect.text{fill:none;stroke-width:0;}#mermaid-svg-kApBeSZwySAetpSt .icon-shape,#mermaid-svg-kApBeSZwySAetpSt .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-kApBeSZwySAetpSt .icon-shape p,#mermaid-svg-kApBeSZwySAetpSt .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-kApBeSZwySAetpSt .icon-shape .label rect,#mermaid-svg-kApBeSZwySAetpSt .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-kApBeSZwySAetpSt .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-kApBeSZwySAetpSt .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-kApBeSZwySAetpSt :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} push metrics
Prometheus scrape 定时拉取
PromQL 查询
脚本 / 批处理任务 / CronJob
Pushgateway
Prometheus TSDB
Grafana / Alertmanager

组件 模式
任务 → Pushgateway Push
Prometheus → Pushgateway Pull

2.案例

脚本 → Pushgateway → Prometheus → Alert规则

启动: 运行 pushgateway.exe

默认端口:http://localhost:9091

在 prometheus.yml 加:

复制代码
- job_name: pushgateway
  static_configs:
    - targets: ["localhost:9091"]

创建指标文件metrics.txt 写入,内容末尾有换行

tex 复制代码
task_duration_seconds{type="backup"} 3.5

rules.yml添加 (文件编码要utf-8)

yaml 复制代码
groups:
- name: pushgateway
  rules:
  - alert: JobFailed
	expr: task_duration_seconds{job="backup_job"} > 8
    for: 10s
    labels:
      severity: warning
    annotations:
      summary: "任务执行时间过长"

测试(push)

bash 复制代码
C:\Users\linshengqian\Desktop\Monitoring>curl --data-binary @metrics.txt http://localhost:9091/metrics/job/backup_job

检查http://localhost:9091/metrics 指标中是否有task_duration_seconds

bash 复制代码
task_duration_seconds{instance="",job="backup_job",type="backup"} 3.5

prometheus的PromQL查询

bash 复制代码
task_duration_seconds
相关推荐
川石课堂软件测试1 天前
JMeter异步接口测试实战
数据库·python·jmeter·mysql·kubernetes·测试用例·prometheus
lbb 小魔仙5 天前
Redis运行状态总靠手动查?我用redis_exporter+Prometheus把指标、告警和远程抓取全接起来了
redis·bootstrap·prometheus
程序员-Benothing5 天前
Linux系统监控工具全家桶:sar、dstat、glances、Prometheus
linux·运维·prometheus
wzq11_6665 天前
Prometheus监控——云原生与非云原生监控
云原生·prometheus
东风微鸣6 天前
把 Tailscale 接进 Prometheus 监控
java·数据库·prometheus
Kendra9196 天前
运维监控平台(Prometheus + Grafana)部署与维护
运维·grafana·prometheus
Dovis(誓平步青云)6 天前
一年1956亿行:智能电表场景下的时序数据存储实践
运维·前端·自动化·音视频·prometheus
空空dream7 天前
06 | Prometheus打通FastAPI云原生数据采集
云原生·prometheus·fastapi
Dovis(誓平步青云)8 天前
常用命令藏得太深?怎么做一个快捷命令坞
运维·前端·自动化·音视频·prometheus