关键词:Prometheus、Grafana、微服务监控、时序数据库、Exporter、Alertmanager、指标采集
摘要:本文以“搭积木”的方式,从0到1讲解如何用Prometheus+Grafana搭建微服务监控系统。通过生活比喻、实战步骤和代码示例,带你理解监控核心概念(如指标采集、可视化、告警),掌握安装配置、数据采集、图表绘制和告警设置的全流程,让你轻松为微服务“装上仪表盘”。
想象一下:你开了一家24小时便利店,货架上有100种商品,每天有上千位顾客进出。如果没有收银系统、库存监控和温度传感器,你根本不知道哪款商品卖得好、哪批牛奶快过期、空调是否正常——这就是微服务架构的现状!
微服务监控的核心目标,就是让你“看清”分布式系统的运行状态。本文聚焦Prometheus+Grafana这对“监控黄金组合”,覆盖从安装、配置到可视化的全流程,帮你为微服务集群搭建一套“数字望远镜”。
本文按“认知→搭建→实战”的逻辑展开:
术语 | 便利店类比 | 专业解释 |
---|---|---|
Prometheus | 收账员(每天固定时间查电表、点库存) | 开源监控系统,定期从目标(如服务器、服务)拉取指标数据 |
Grafana | 数据画家(把账单画成饼图、折线图) | 可视化工具,从Prometheus取数据并生成图表 |
Exporter | 电表/库存计数器(把电量/库存转成数字) | 负责将特定服务/设备的状态转成Prometheus能识别的指标 |
时序数据库(TSDB) | 时间账本(按时间记录每天的销售额) | Prometheus存储数据的格式,按“时间+指标名+标签”存储 |
Alertmanager | 警报器(牛奶快过期时响铃) | 处理Prometheus的告警规则,触发邮件/Slack通知 |
假设你开了一家连锁便利店,想知道:
为了监控这些,你需要:
这就是Prometheus+Grafana的核心逻辑:用Exporter采集数据→Prometheus存储数据→Grafana可视化数据。
Prometheus是一个“超级收账员”,它的工作方式不是等数据自己送上门(推模型),而是主动去“查表”(拉模型)。比如:
它把查到的数据存在“时间账本”(时序数据库)里,格式是:
指标名{标签}=数值 时间戳
比如:http_requests_total{service="user-service",status="200"}=100 1690000000
(用户服务返回200的请求总共有100次,时间戳是2023年7月21日)。
Grafana是一个“超级画家”,它能从Prometheus的“时间账本”里取数据,然后画成各种图表:
你甚至可以把多个图表拼在一起,做成“监控大屏”,就像飞机驾驶舱的仪表盘,所有关键指标一目了然。
Exporter是“语言翻译官”。不同的服务/设备有自己的“语言”:
top
命令的输出)。SHOW STATUS
的结果)。Exporter的作用是把这些“语言”翻译成Prometheus能听懂的“指标语言”(符合Prometheus格式的文本)。比如:
/proc
文件系统数据(CPU、内存)转成node_cpu_seconds_total
等指标。SHOW STATUS
的结果转成mysql_global_status_connections
等指标。[服务/设备] → [Exporter(翻译数据)] → [Prometheus(拉取+存储)] → [Grafana(查询+可视化)]
↑
│
[Alertmanager(处理告警规则)]
Prometheus的核心原理是拉模型(Pull-based):它主动去各个Exporter“要数据”,而不是等数据推过来。这种设计的好处是:
wget https://github.com/prometheus/prometheus/releases/download/v2.47.0/prometheus-2.47.0.linux-amd64.tar.gz
tar -zxvf prometheus-2.47.0.linux-amd64.tar.gz
cd prometheus-2.47.0.linux-amd64
./prometheus --config.file=prometheus.yml
docker run -d --name prometheus \
-p 9090:9090 \
-v /path/to/prometheus.yml:/etc/prometheus/prometheus.yml \
prom/prometheus:v2.47.0
Prometheus的核心配置文件是prometheus.yml
,它决定了:
scrape_configs
)。storage.tsdb.retention.time
)。rule_files
)。示例配置(监控本地服务器和一个Java服务):
global:
scrape_interval: 15s # 全局采集间隔:每15秒拉一次数据
evaluation_interval: 15s # 告警规则评估间隔
scrape_configs:
# 监控Linux服务器(通过Node Exporter)
- job_name: "node"
static_configs:
- targets: ["localhost:9100"] # Node Exporter的地址(假设和Prometheus同机)
# 监控Java微服务(通过Spring Boot Actuator)
- job_name: "user-service"
static_configs:
- targets: ["192.168.1.100:8080"] # 微服务的地址(需开启Actuator的Prometheus端点)
metrics_path: "/actuator/prometheus" # Actuator暴露的指标路径
Node Exporter用于监控Linux服务器的CPU、内存、磁盘等指标。
wget https://github.com/prometheus/node_exporter/releases/download/v1.6.1/node_exporter-1.6.1.linux-amd64.tar.gz
tar -zxvf node_exporter-1.6.1.linux-amd64.tar.gz
cd node_exporter-1.6.1.linux-amd64
./node_exporter # 默认端口9100
访问http://你的服务器IP:9090/targets
,如果看到node
和user-service
的状态是UP
,说明配置成功!
Prometheus的指标(Metric)有4种类型,理解它们是写查询和告警规则的关键:
定义:只增不减的数值(比如请求总数、错误总数)。
公式:counter = 初始值 + 增量
(只能累加)。
例子:http_requests_total{status="500"}=10
表示“返回500错误的请求总共有10次”。
查询技巧:用rate()
函数看“最近的增长速率”(比如rate(http_requests_total[5m])
表示最近5分钟的请求速率)。
定义:可增可减的数值(比如内存使用率、CPU空闲率)。
公式:gauge = 当前状态值
(随时变化)。
例子:node_memory_MemFree_bytes=2048000000
表示“当前空闲内存是2GB”。
查询技巧:直接取当前值(node_memory_MemFree_bytes
)或看一段时间的变化(delta(node_cpu_seconds_total[1h])
)。
定义:用于统计数据分布(比如接口响应时间的分位数)。
公式:histogram = 桶计数 + 总和 + 总数
(比如响应时间在[0.1s, 0.5s)的请求有100个)。
例子:http_request_duration_seconds_bucket{le="0.5"}=200
表示“响应时间≤0.5秒的请求有200个”。
查询技巧:用histogram_quantile()
计算分位数(比如histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))
表示95%的请求响应时间)。
定义:和Histogram类似,但直接计算分位数(不需要Prometheus聚合)。
公式:summary = 分位数值 + 总和 + 总数
(比如直接给出95%分位数是0.4s)。
例子:http_request_duration_seconds{quantile="0.95"}=0.4
表示“95%的请求响应时间≤0.4秒”。
关键区别:Histogram的分位数计算在Prometheus端(需要聚合),适合多实例统计;Summary的分位数计算在应用端(直接上报),适合低延迟场景。
假设你有一个Spring Boot微服务(user-service
),需要监控它的接口请求数、响应时间、JVM内存等指标。
pom.xml
中添加依赖:<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
<dependency>
<groupId>io.micrometergroupId>
<artifactId>micrometer-registry-prometheusartifactId>
dependency>
application.yml
中开启Actuator的Prometheus端点:management:
endpoints:
web:
exposure:
include: "prometheus,health" # 暴露prometheus和health端点
metrics:
tags:
application: user-service # 给指标加标签(方便区分不同服务)
http://localhost:8080/actuator/prometheus
,应该能看到类似http_requests_total{application="user-service",...}
的指标。scrape_configs:
- job_name: "user-service"
static_configs:
- targets: ["192.168.1.100:8080"] # 微服务的IP和端口
metrics_path: "/actuator/prometheus" # 指标路径(和Actuator配置一致)
labels:
env: prod # 给这个job加标签(比如区分生产/测试环境)
job_name
:任务名(用于标识监控目标)。static_configs.targets
:Exporter或微服务的地址(格式:IP:端口)。metrics_path
:指标暴露的路径(默认是/metrics
,Actuator是/actuator/prometheus
)。http://你的服务器IP:3000
,初始账号admin/admin
)。Configuration → Data Sources → Add data source → Prometheus
。http://你的Prometheus服务器IP:9090
(如果Prometheus和Grafana同机,填http://localhost:9090
)。Save & Test
,提示“Data source is working”即成功。Grafana的仪表盘(Dashboard)可以通过JSON文件导入,社区有很多现成的模板(比如Grafana Labs Dashboard)。
示例:导入Spring Boot监控仪表盘(ID 4701)
+ → Import → 粘贴JSON → 选择Prometheus数据源 → 导入
。http_request_duration_seconds
分位数突然升高)。Threads_connected
超过最大连接数时告警)。目标 | Exporter名称 | 用途 |
---|---|---|
Linux服务器 | Node Exporter | CPU、内存、磁盘、网络 |
Windows服务器 | Windows Exporter | 同上(Windows版) |
MySQL | MySQL Exporter | 连接数、查询速率、慢查询 |
Redis | Redis Exporter | 内存、QPS、持久化状态 |
Kafka | JMX Exporter + Kafka JMX | 消息数、延迟、消费者状态 |
Kubernetes(K8s)是微服务的“操作系统”,Prometheus通过k8s_sd_config
(K8s服务发现)自动发现Pod、Service的地址,无需手动配置targets
。未来,监控将与K8s的自动扩缩容(HPA)深度结合(比如根据CPU使用率自动增加Pod数量)。
传统告警依赖阈值(比如“CPU>80%告警”),但复杂系统中阈值难调(比如凌晨CPU高可能正常)。未来,Grafana可能集成AI模型(如时序预测、异常检测),自动识别“非预期”的指标变化(比如“某接口响应时间突然比历史均值高3倍”)。
微服务集群可能有上千个实例,每个实例每秒上报100个指标,一天的数据量可能达到TB级。如何优化存储(比如使用prometheus-remote-storage
将数据存到云存储)、加速查询(比如使用Thanos或Cortex做分布式查询),是未来的关键问题。
Exporter为Prometheus提供“原材料”(指标数据),Prometheus将数据存入“时间账本”(TSDB),Grafana从账本取数据“作画”(可视化),Alertmanager根据账本数据“拉响警报”(告警)。
rate(http_requests_total{status="500"}[5m]) > 10
”表示什么含义?如果想避免“偶发错误触发告警”,可以怎么优化?Q1:Prometheus页面显示“target is down”怎么办?
A:检查以下几点:
ps -ef | grep exporter
)。telnet 目标IP 端口
测试连通性)。targets
地址是否正确(IP和端口是否匹配)。Q2:Grafana图表不显示数据?
A:可能原因:
{}
自动补全指标名)。scrape_interval
是60s,而图表时间范围是最近5分钟,可能还没采集到数据)。Q3:如何设置告警?
A:步骤如下:
rule_files
(比如- "alerts/*.rules"
)。groups:
- name: server-alert
rules:
- alert: HighCPUUsage
expr: 100 - (avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
for: 5m # 持续5分钟触发告警
labels:
severity: critical
annotations:
summary: "服务器{{ $labels.instance }} CPU使用率过高"
description: "CPU使用率{{ $value }}%(超过80%阈值)"