Prometheus监控告警体系搭建实战:PromQL查询语法与Alertmanager告警路由配置

Prometheus作为云原生监控体系的事实标准,在DevOps实践和SRE稳定性工程中占据核心地位。一套完整的Prometheus监控告警体系包含指标采集、时序存储、查询分析和告警路由四个环节。网站运维团队在构建监控体系时面临的主要问题包括:PromQL查询语法学习曲线陡峭、告警规则容易产生噪声、Alertmanager路由配置复杂导致告警漏发或误发。本文以Prometheus 3.0 + Alertmanager 0.28为例,从安装部署到告警路由配置,提供可直接复用的配置方案和查询模板。

Prometheus架构与安装部署

Prometheus采用拉取(Pull)模式采集指标,通过Service Discovery动态发现监控目标,时序数据存储在本地TSDB中。生产环境部署推荐使用Prometheus Operator(Kubernetes环境)或二进制部署(裸机环境),两者配置语法完全一致。

# 二进制部署 Prometheus 3.0
wget https://github.com/prometheus/prometheus/releases/download/v3.0.0/prometheus-3.0.0.linux-amd64.tar.gz
tar xzf prometheus-3.0.0.linux-amd64.tar.gz
cd prometheus-3.0.0.linux-amd64

# prometheus.yml 核心配置
global:
  scrape_interval: 15s
  evaluation_interval: 15s
  external_labels:
    cluster: "production"
    region: "cn-east-1"

rule_files:
  - "rules/*.yml"
  - "rules/service/*.yml"

alerting:
  alertmanagers:
    - static_configs:
        - targets: ["127.0.0.1:9093"]

scrape_configs:
  # 应用服务监控
  - job_name: "app-metrics"
    metrics_path: /metrics
    static_configs:
      - targets: ["app1:9100", "app2:9100", "app3:9100"]
        labels:
          team: "backend"
  
  # Kubernetes服务发现
  - job_name: "k8s-pods"
    kubernetes_sd_configs:
      - role: pod
    relabel_configs:
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
        regex: "true"
        action: keep
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
        target_label: __metrics_path__
      - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
        regex: "([^:]+)(?::\d+)?;(\d+)"
        target_label: __address__
        replacement: "$1:$2"

# 远程写入(长期存储)
remote_write:
  - url: "http://thanos-receive:19291/api/v1/receive"
    queue_config:
      capacity: 10000
      max_samples_per_send: 2000

生产环境的数据保留策略需要平衡存储成本和历史数据查询需求。Prometheus本地TSDB默认保留15天,超过15天的历史数据通过remote_write写入Thanos或VictoriaMetrics做长期存储。单机Prometheus的合理承载规模约为200万活跃时间序列(约500个目标,每个目标4000个指标),超过此规模应考虑分片或联邦集群方案。

PromQL查询语法详解

PromQL的查询能力分为即时查询(instant query)和范围查询(range query),配合聚合操作符和向量匹配逻辑,可以实现复杂的指标计算。以下从基础到进阶列出运维中高频使用的查询模板。

# 1. 基础查询:CPU使用率
# 即时值
100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

# 范围值(过去1小时,每5分钟一个点)
100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)[1h:5m]

# 2. 内存使用率
(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100

# 3. 磁盘IO等待
rate(node_disk_io_time_seconds_total[5m]) * 100

# 4. HTTP请求P99延迟(histogram_quantile)
histogram_quantile(0.99, 
  rate(http_request_duration_seconds_bucket[5m])
)

# 5. 错误率计算(带标签匹配)
sum(rate(http_requests_total{status=~"5.."}[5m])) by(service)
/
sum(rate(http_requests_total[5m])) by(service)
* 100

# 6. 多维度聚合:按服务分组计算QPS
sum by(service, status_code) (rate(http_requests_total[1m]))

# 7. 计算环比增长
# 当前5分钟QPS相比1小时前5分钟QPS的增长率
(
  sum(rate(http_requests_total[5m])) - 
  sum(rate(http_requests_total[5m] offset 1h))
) / 
sum(rate(http_requests_total[5m] offset 1h)) * 100

# 8. recording rule(预计算高频查询,降低查询延迟)
# rules/recording.yml
groups:
  - name: http_metrics
    rules:
      - record: job:http_requests:rate5m
        expr: sum by(job)(rate(http_requests_total[5m]))
      - record: job:http_errors:ratio
        expr: |
          sum by(job)(rate(http_requests_total{status=~"5.."}[5m]))
          /
          sum by(job)(rate(http_requests_total[5m]))

recording rule是Prometheus性能优化的关键手段。将高频查询的复杂表达式预计算并存储为新的时间序列,告警规则和Grafana面板直接引用预计算序列,可以将查询延迟从秒级降低到毫秒级。对于每秒查询频率的Dashboard面板,recording rule几乎是必选项。

告警规则定义与Alertmanager配置

告警规则在Prometheus中定义,触发后推送到Alertmanager做路由和通知分发。告警设计的核心原则是:可操作性——每条告警都应该对应一个明确的处理动作,无法操作的通知只是噪声。

# rules/alerting.yml
groups:
  - name: node_alerts
    interval: 30s
    rules:
      # CPU使用率超过80%持续5分钟
      - alert: HighCpuUsage
        expr: 100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
        for: 5m
        labels:
          severity: warning
          team: ops
        annotations:
          summary: "CPU使用率过高 {{ $labels.instance }}"
          description: "实例 {{ $labels.instance }} CPU使用率 {{ $value }}% 超过80%持续5分钟"
          runbook: "https://wiki.internal/runbook/high-cpu"
      
      # 磁盘空间不足(critical级别)
      - alert: DiskSpaceCritical
        expr: |
          (node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"} 
          / node_filesystem_size_bytes{fstype!~"tmpfs|overlay"}) * 100 < 10
        for: 10m
        labels:
          severity: critical
          team: ops
        annotations:
          summary: "磁盘空间不足 {{ $labels.instance }} {{ $labels.mountpoint }}"
      
      # 服务可用性下降
      - alert: ServiceDown
        expr: up{job="app-metrics"} == 0
        for: 2m
        labels:
          severity: critical
          team: backend
        annotations:
          summary: "服务不可用 {{ $labels.instance }}"
          description: "实例 {{ $labels.instance }} 已离线超过2分钟"

# alertmanager.yml 路由配置
route:
  receiver: default
  group_by: ['alertname', 'cluster', 'service']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  routes:
    # critical级别立即发送,不分组等待
    - matchers: ['severity="critical"']
      receiver: oncall-pagerduty
      group_wait: 0s
      repeat_interval: 1h
    
    # backend团队告警路由到飞书
    - matchers: ['team="backend"']
      receiver: feishu-backend
      group_wait: 1m
    
    # 工作时间静默non-critical告警
    - matchers: ['severity="warning"']
      receiver: feishu-ops
      mute_time_intervals: ['off-hours']
      group_wait: 5m

receivers:
  - name: default
    webhook_configs:
      - url: 'http://localhost:9099/alerts'
  
  - name: oncall-pagerduty
    webhook_configs:
      - url: 'https://events.pagerduty.com/v2/enqueue'
        send_resolved: true
  
  - name: feishu-backend
    webhook_configs:
      - url: 'https://open.feishu.cn/open-apis/bot/v2/hook/xxx'
        send_resolved: true

mute_time_intervals:
  - name: off-hours
    time_intervals:
      - times:
          - start_time: '22:00'
            end_time: '09:00'
        weekdays: ['monday:friday']
      - weekdays: ['saturday', 'sunday']

告警分组(group_by)将相同alertname和cluster的告警合并为一条通知,避免告警风暴。group_wait控制首次通知的等待时间,给同组后续告警留出合并窗口。repeat_interval设置重复通知间隔,防止持续告警反复打扰。对于critical级别告警,group_wait设为0确保立即通知;对于warning级别,适当延长group_wait以合并瞬时波动。

Grafana数据可视化集成与服务发现

Grafana是Prometheus生态中最常用的可视化前端。配置Prometheus数据源后,通过变量模板实现动态面板,按服务、实例、环境等维度切换查看。

# Grafana数据源配置
# /etc/grafana/provisioning/datasources/prometheus.yml
apiVersion: 1
datasources:
  - name: Prometheus
    type: prometheus
    access: proxy
    url: http://prometheus:9090
    isDefault: true
    jsonData:
      timeInterval: '15s'
      httpMethod: POST
      manageAlerts: true  # Grafana 11+ 支持统一告警管理

# Dashboard 变量配置(JSON片段)
{
  "templating": {
    "list": [
      {
        "name": "service",
        "type": "query",
        "datasource": "Prometheus",
        "query": "label_values(http_requests_total, service)",
        "refresh": 2
      },
      {
        "name": "instance",
        "type": "query",
        "datasource": "Prometheus",
        "query": "label_values(up{service="$service"}, instance)",
        "refresh": 2
      }
    ]
  }
}

# 动态面板查询(引用变量)
# QPS by status code
sum by(status_code)(rate(http_requests_total{service="$service",instance="$instance"}[5m]))

# 延迟分布热力图
sum by(le)(rate(http_request_duration_seconds_bucket{service="$service"}[5m]))

服务发现(Service Discovery)是大规模监控体系的基础。Kubernetes环境下,通过Pod注解自动发现监控目标,新增Pod无需修改Prometheus配置。裸机环境推荐使用Consul或DNS-SD做服务发现,配置变更通过Consul KV或DNS记录动态更新,Prometheus定期轮询发现新目标。对于云环境(AWS/GCP/阿里云),Prometheus提供原生云服务发现集成,可自动发现EC2实例、ELB、RDS等云资源的监控端点。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/prometheus-jian-kong-gao-jing-ti-xi-da-jian-shi-zhan-promql/

(0)
小编小编
上一篇 2026年8月25日
下一篇 2026年8月25日

相关推荐