引言:可观测性是运维的基石
在现代微服务架构下,一个用户请求可能跨越数十个服务节点。当系统出现性能瓶颈或故障时,如果缺乏完善的监控体系,排查问题如同大海捞针。Prometheus 采集指标、Grafana 可视化展示、AlertManager 告警分发,三者构成了一套业界标准的全链路监控方案。本文将从零开始,手把手搭建一套覆盖基础设施和应用层的监控体系。
一、Prometheus 架构与核心概念
Prometheus 采用拉取模式采集指标,通过服务发现或静态配置定期从各 Target 抓取数据。其核心数据模型是多维时间序列,每个数据点由指标名称、标签集合和数值组成。理解以下四种指标类型是使用 Prometheus 的基础:
# Counter:单调递增计数器,适合记录请求总数、错误总数
http_requests_total{method="GET", status="200"} 4521
# Gauge:可增可减的瞬时值,适合记录温度、内存、连接数
node_memory_MemAvailable_bytes 8589934592
# Histogram:分布统计,适合请求延迟分布
http_request_duration_seconds_bucket{le="0.1"} 1200
http_request_duration_seconds_bucket{le="0.5"} 1800
# Summary:类似 Histogram,但直接在客户端计算分位数
http_request_duration_seconds{quantile="0.95"} 0.234
以下是 Prometheus 主配置文件的核心结构:
# prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
rule_files:
- "alerts/*.yml"
alerting:
alertmanagers:
- static_configs:
- targets: ['alertmanager:9093']
scrape_configs:
# 监控 Prometheus 自身
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
# 监控 Node Exporter(主机指标)
- job_name: 'node'
static_configs:
- targets: ['node1:9100', 'node2:9100', 'node3:9100']
# 通过 Consul 服务发现自动发现微服务
- job_name: 'microservices'
consul_sd_configs:
- server: 'consul:8500'
services: ['api-gateway', 'user-service', 'order-service']
relabel_configs:
- source_labels: [__meta_consul_service]
target_label: service
- source_labels: [__meta_consul_node]
target_label: node
二、Node Exporter 与主机监控
Node Exporter 是最常用的主机指标采集器,覆盖 CPU、内存、磁盘、网络等核心维度。在所有服务器上部署后,可以通过 PromQL 查询关键指标:
# CPU 使用率(按核心分组)
100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# 内存使用率
(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100
# 磁盘使用率
1 - node_filesystem_free_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}
# 网络入站带宽
rate(node_network_receive_bytes_total{device="eth0"}[1m])
# 磁盘 IOPS
rate(node_disk_reads_completed_total[1m]) + rate(node_disk_writes_completed_total[1m])
三、应用指标埋点与 Pushgateway
对于短生命周期的批处理任务(如定时数据导入),Prometheus 拉取模式不再适用。此时需要使用 Pushgateway 作为中间缓存:
# Python 应用埋点示例
from prometheus_client import Counter, Histogram, push_to_gateway
# 定义业务指标
request_total = Counter(
'data_import_total',
'Total data import operations',
['source', 'status']
)
import_duration = Histogram(
'data_import_duration_seconds',
'Duration of data import operations',
['source'],
buckets=[0.5, 1, 5, 10, 30, 60]
)
# 在业务代码中使用
@import_duration.labels(source='mysql').time()
def import_from_mysql():
try:
# 执行数据导入逻辑
process_data()
request_total.labels(source='mysql', status='success').inc()
except Exception as e:
request_total.labels(source='mysql', status='error').inc()
raise
finally:
# 推送到 Pushgateway
push_to_gateway('pushgateway:9091', job='data-import', registry=REGISTRY)
四、Grafana 仪表盘设计
Grafana 的强大在于将 Prometheus 数据以直观的可视化方式呈现。一个高质量仪表盘应遵循"从概览到下钻"的设计原则。以下是几个关键面板的 PromQL 表达式:
# 服务健康概览面板(Stat 图)
up{job="microservices"}
# 配合值映射:1=绿色(UP),0=红色(DOWN)
# P99 延迟趋势面板(Time series 图)
histogram_quantile(0.99,
sum(rate(http_request_duration_seconds_bucket[5m])) by (le, service)
)
# 错误率热力图(Heatmap)
sum(rate(http_requests_total{status=~"5.."}[5m])) by (service) /
sum(rate(http_requests_total[5m])) by (service)
# 集群资源使用 TopN 面板(Bar gauge)
topk(5,
100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
)
五、AlertManager 告警规则与路由
告警是监控体系的价值落点。合理的告警规则能在问题影响用户前发出预警。以下是几个常用的告警规则定义:
# alerts/rules.yml
groups:
- name: infrastructure
rules:
# 实例宕机告警
- alert: NodeDown
expr: up{job="node"} == 0
for: 2m
labels:
severity: critical
annotations:
summary: "节点 {{ $labels.instance }} 已宕机"
description: "已持续 2 分钟无法采集到该节点指标"
# 磁盘空间不足告警
- alert: DiskSpaceLow
expr: |
(node_filesystem_free_bytes / node_filesystem_size_bytes) * 100 < 15
for: 5m
labels:
severity: warning
annotations:
summary: "磁盘空间不足: {{ $labels.instance }}"
# 服务 P99 延迟过高
- alert: HighLatency
expr: |
histogram_quantile(0.99,
sum(rate(http_request_duration_seconds_bucket[5m])) by (le, service)
) > 0.5
for: 3m
labels:
severity: warning
annotations:
summary: "服务 {{ $labels.service }} P99 延迟超过 500ms"
AlertManager 的路由配置可以根据告警严重程度发送到不同渠道:
# alertmanager.yml
route:
receiver: 'default'
group_by: ['alertname', 'service']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
routes:
- match:
severity: critical
receiver: 'oncall-team'
- match:
severity: warning
receiver: 'dev-team'
receivers:
- name: 'oncall-team'
webhook_configs:
- url: 'https://oapi.dingtalk.com/robot/send?access_token=xxx'
- name: 'dev-team'
webhook_configs:
- url: 'https://hooks.feishu.com/xxx'
总结
一套完整的监控体系不仅是工具的堆砌,更是一种运维方法论。从指标采集、数据存储、可视化展示到告警分发,每个环节都需要精心设计。Prometheus 生态的优势在于生态丰富、社区活跃、配置灵活。在实际落地中,建议遵循"先覆盖核心指标再逐步细化"的原则,建立从基础设施到应用层的分层监控,并通过持续的告警调优减少噪声、提升信号比,最终实现系统运行状态的全面可观测。