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/