运维老鸟的监控秘籍:Prometheus抓数据+Grafana画大屏,故障再也藏不住
目录
1. Prometheus
1.1. 核心组件
1.2. 实现微服务应用监控及告警
1.2.1. 安装docker
1.2.2. Spring Boot应用配置暴露监控指标
1.2.3. 部署Prometheus
1.2.4. Alertmanager实现告警
2. Grafana
2.1. 使用Docker安装Grafana
2.2. 配置数据源
2.3. 配置监控面板
3. 扩展监控
3.1. 主机监控
3.2. 数据库监控
3.3. 缓存监控
4. 小结
监控这事,就像开车要看仪表盘。想象一下:你开着没有仪表盘的车在高速上飙到120码,看不见油量、不知道水温、连车速都靠猜。这时候要是发动机冒烟了,可能得等到车子抛锚才发现问题——这就是没有监控的微服务系统日常。没有监控加持,每次排查问题都像在黑灯瞎火的房间里找钥匙,比如查日志查到凌晨三点,最后发现竟是因为数据库连接不够用。
企业面对监控需求通常两条路:要么砸钱自研,从零写一套监控系统。这就像自家盖房子连砖都自己烧,虽然能完全按需求定制,但人力成本高、开发周期长,往往只有大厂玩得起。更多团队选择第二条路:用开源方案搭积木。这里头Prometheus + Grafana这对黄金组合,就像监控界的"瑞士军刀",十家企业有八家都在用,下面按章节展开说明。
1. Prometheus
1.1. 核心组件
Prometheus的核心组件有Prometheus Server、Exporters、 Pushgateway、Alertmanager,除此之外还有内置功能Service discovery、客户端库Client Libraries和扩展存储Long-term Storage。
组件/库/三方扩展分类与归属:
组件名称 | 类型 | 是否必需 | 功能描述 |
---|---|---|---|
Prometheus Server | 核心组件(官方维护) | 必需 | 数据采集、存储、查询的核心引擎,负责拉取指标、执行告警规则 |
Exporters | 官方/社区组件(生态扩展) | 可选 | 将第三方系统(如主机、数据库)的指标转换为Prometheus格式 |
Pushgateway | 官方组件(独立) | 可选 | 临时存储短生命周期任务的指标,供 Prometheus拉取 |
Alertmanager | 官方组件(独立) | 可选 | 接收告警、去重、分组并发送通知(邮件、Webhook等) |
Service discovery | 内置功能(非独立组件) | 可选 | 用于动态发现并管理监控目标(targets),解决监控环境中目标实例动态变化的问题,例如云原生场景下容器的频繁扩缩容或微服务实例的动态注册。通过服务发现,Prometheus 可以自动识别新增或变更的监控目标,无需手动修改配置文件。 |
Client Libraries | 官方/社区库 | 可选 | 在应用中埋点暴露自定义指标(如 Java的Micrometer) |
Long-term Storage | 第三方扩展(如 Thanos) | 可选 | 解决本地存储容量限制,支持长期数据保留和全局查询 |
基于官方架构图基础上简化后的核心组件交互图:
1.2. 实现微服务应用监控及告警
以企业常用的CentOS 7部署环境为例,先安装docker,再容器化部署Spring Boot应用并配置暴露监控指标,然后部署Prometheus Server,最后通过Alertmanager实现告警。
1.2.1. 安装docker
登录服务器,按步骤执行以下命令:
# 安装依赖包
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# 添加阿里云Docker CE镜像源
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 安装Docker CE
sudo yum install -y docker-ce docker-ce-cli containerd.io
# 启动Docker并设置开机自启
sudo systemctl start docker
sudo systemctl enable docker
# 验证安装
sudo docker --version
成功安装输出docker版本:
设置三方仓库镜像地址,加速镜像下载,按顺序执行以下命令:
# 创建Docker配置文件目录
sudo mkdir -p /etc/docker
# 编辑Docker配置文件
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://do.nark.eu.org",
"https://dc.j8.work",
"https://docker.m.daocloud.io",
"https://dockerproxy.com",
"https://docker.mirrors.ustc.edu.cn",
"https://docker.nju.edu.cn"
]
}
EOF
# 重新加载配置文件
sudo systemctl daemon-reload
# 重启Docker服务
sudo systemctl restart docker
1.2.2. Spring Boot应用配置暴露监控指标
a. 创建一个Spring Boot项目,在pom.xml中添加Prometheus和Actuator依赖:
org.springframework.boot
spring-boot-starter-actuator
io.micrometer
micrometer-registry-prometheus
b. 在application.yml中启用Prometheus端点:
management:
endpoints:
web:
exposure:
include: health,info,prometheus
metrics:
export:
prometheus:
enabled: true
c. idea中执行package打包项目为JAR文件,执行完target目录下生成jar
d. 按以下内容新建一个Dockerfile文件
# 使用OpenJDK 8官方镜像作为基础
FROM openjdk:8-jre-alpine
# 设置容器内部的工作目录
WORKDIR /app
# 将宿主机上的JAR文件复制到容器内
COPY springboot-demo-0.0.1-SNAPSHOT.jar app.jar
# 暴露应用端口(根据实际端口修改)
EXPOSE 8080
# 启动命令
ENTRYPOINT ["java", "-jar", "app.jar"]
e. 将Dockerfile和jar通过Filezilla上传到服务器自定义目录home/service/app
f. 在服务器目录home/service/app下执行以下命令构建Docker镜像
sudo docker build -t springboot-demo:0.0.1 .
g. 执行以下命令运行Docker容器
# 运行容器(映射宿主机端口到容器端口)
sudo docker run -d -p 8080:8080 --name myapp springboot-demo:0.0.1
h. 执行docker ps确认容器正常运行
i. 验证指标暴露
启动应用后,访问http://<微服务IP>:<端口>/actuator/prometheus,确认能看到Prometheus格式的指标数据:
1.2.3. 部署Prometheus
a. 创建配置文件prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'spring-boot'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['微服务1_IP:端口', '微服务2_IP:端口', ...] # 填写所有微服务的IP和端口
- job_name: 'prometheus' # 监控Prometheus自身
static_configs:
- targets: ['localhost:9090']
b. 通过Filezilla上传prometheus.yml
到服务器自定义目录home/service/prometheus
c. 拉取最新版本Prometheus镜像
docker pull prom/prometheus
d. 获取当前用户的UID和GID(替换username为你的用户名)
id username
e. 启动Prometheus容器(-u指定上面获取的UID和GID,比如1000,目的是指定用户运行,否则启动容器会报错无法向宿主机目录/home/service/prometheus/data写入数据)
docker run -u 1000:1000 -d --name prometheus -p 9090:9090
-v /home/service/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
-v /home/service/prometheus/data:/prometheus
prom/prometheus
f. 用docker ps命令验证容器是否启动成功
g. 访问http://你的ip:9090/targets
,确认所有微服务状态为“UP”
1.2.4. Alertmanager实现告警
a. 创建alertmanager.yml用于配置告警路由
route:
receiver: 'email-alert' # 路由到名为 email-alert 的接收器
receivers:
- name: 'email-alert'
email_configs:
- to: '接收人邮箱@163.com' # 告警接收人邮箱
from: '发送人邮箱@163.com' # 发送邮箱
smarthost: 'smtp.163.com:465' # SMTP 服务器地址和端口
auth_username: '发送人邮箱@163.com' # 邮箱账号
auth_password: '授权码' # 客户端授权密码(非邮箱登录密码)
require_tls: false # 禁用显式 TLS(STARTTLS)
hello: '163.com' # 设置 HELO 域名
以163邮箱为例,上面的客户端授权密码需要去163邮箱页面开启POP3/SMTP服务后会弹窗显示授权码:
b. 上传alertmanager.yml到自定义目录/home/service/alertmanager
c. 启动alertmanager容器
docker run -d
--name alertmanager
-p 9093:9093
-v /home/service/alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml
prom/alertmanager:latest
--config.file=/etc/alertmanager/alertmanager.yml
d. 验证是否启动成功及alertmanager.yml配置
docker ps查看容器状态正常:
访问
http://宿主机ip:9093查看配置是否正确:
e. 创建Prometheus的规则文件(如 alertrules.yml)用于
定义告警规则
比如微服务应用停止时触发告警:
groups:
- name: example
rules:
- alert: SpringBootAppDown
expr: up{job="spring-boot"} == 0
for: 10s
labels:
severity: critical
annotations:
summary: "Spring Boot 应用 {{ $labels.instance }} 已停止"
description: "Spring Boot 应用 {{ $labels.instance }} 在过去 10 秒内无法访问,请立即检查应用状态。"
f. 上传alertrules.yml到服务器
自定义目录/home/service/prometheus
g. 修改prometheus.yml,增加
Alertmanager地址配置和规则文件
alerting:
alertmanagers:
- static_configs:
- targets: ['宿主机ip:9093'] # Alertmanager 服务地址
rule_files:
- "/etc/prometheus/alertrules.yml" # 告警规则容器文件路径
h. 重新挂载规则文件并重启容器
# 1. 停止当前容器
docker stop prometheus
# 2. 删除容器
docker rm prometheus
# 3. 重新启动容器并挂载规则文件
docker run -u 1000:1000 -d --name prometheus -p 9090:9090
-v /home/service/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
-v /home/service/prometheus/alertrules.yml:/etc/prometheus/alertrules.yml
-v /home/service/prometheus/data:/prometheus
prom/prometheus
i. 访问http:/你的ip:9090/alerts验证规则是否配置成功
j. 停止微服务应用容器模拟触发告警
# 停止微服务应用容器
docker stop myapp
等待满足触发告警时间后(上面alertrules.yml配置的是10s),prometheus的Alerts页面对应的告警规则状态会先变为Pending,最终变为Firing通知Alertmanager,然后Alertmanager的Alerts页面也可以看到生成了一条告警:
接着查看邮箱成功收到告警邮件:
2. Grafana
Prometheus自带的Web UI也能直接查询数据但功能较基础,一般搭配Grafana做可视化,通过Grafana丰富的图表(折线图、仪表盘、热力图等)展示 Prometheus 或其他数据源(如 MySQL、Elasticsearch)的数据。
2.1. 使用Docker安装Grafana
docker run -d --name grafana -p 3000:3000 grafana/grafana:10.2.0
2.2. 配置数据源
访问http://宿主机ip:3000
,默认账号密码为admin/admin,登录Grafana:
按以下步骤添加prometheus数据源:
2.3. 配置监控面板
在Grafana中点击Import,输入社区仪表板ID(如11378,适用于Spring Boot应用监控)
3. 扩展监控
除了应用监控外,通过Prometheus的Exporters组件可以将非Prometheus原生支持的第三方系统指标(如主机、数据库、中间件)转换为Prometheus可抓取的格式,下面将常用的主机监控、数据库监控和缓存监控整合到我们的监控系统中。
3.1. 主机监控
a. 部署 Node Exporter
docker run -d
--name node-exporter
--net="host"
--pid="host"
-v "/:/host:ro,rslave"
quay.io/prometheus/node-exporter:latest
--path.rootfs=/host
b. 修改prometheus.yml,添加主机监控任务
scrape_configs:
- job_name: 'node'
static_configs:
- targets: ['宿主机IP:9100'] # 替换为主机实际IP
c. 重启Prometheus容器
docker restart 容器id或名称
d. 导入主机监控仪表盘
跟上面2.3步骤一样输入模板ID(比如1860)导入仪表盘,导入后Grafana正常展示指标:
3.2. 数据库监控
a. 创建配置文件.my.cnf,配置MySQL连接信息,内容如下:
[client]
user=登录mysql的用户名
password=登录mysql的用户名对应密码
host=mysql服务器ip
port=mysql端口
b. 通过Filezilla上传到服务器自定义目录/home/service/prometheus/mysqlexporter
c. 部署MySQL Exporter
docker run -d --name mysqld-exporter -p 9104:9104 -v /home/service/prometheus/mysqlexporter/.my.cnf:/.my.cnf prom/mysqld-exporter --web.list-address=:9104
d. 修改prometheus.yml,添加MySQL监控任务
scrape_configs:
- job_name: 'mysql'
static_configs:
- targets: ['宿主机ip:9104']
e. 重启Prometheus容器
docker restart 容器id或名称
f. 导入主机监控仪表盘
跟上面2.3步骤一样输入模板ID(比如7362)导入仪表盘,导入后Grafana正常展示指标:
3.3. 缓存监控
a. 部署Redis Exporter
docker run -d
--name redis-exporter
-p 9121:9121
-e REDIS_ADDR="redis://宿主机ip:6379"
-e REDIS_PASSWORD="redis密码"
oliver006/redis_exporter:latest
b. 修改prometheus.yml,添加Redis监控任务
scrape_configs:
- job_name: 'redis'
static_configs:
- targets: ['宿主机ip:9121']
c. 重启Prometheus容器
docker restart 容器id或名称
d. 导入主机监控仪表盘
跟上面2.3步骤一样输入模板ID(比如11835)导入仪表盘,导入后Grafana正常展示指标:
4. 小结
虽然监控这块一般企业里面属于运维的工作内容,开发只是借助监控工具排查问题,但是不妨碍我们多了解些,毕竟现在企业都在有效地执行DevOps策略,强调打破开发和运维之间的隔阂,加强团队之间的协作和沟通。对于开发而言,掌握运维相关的知识,主动扩展我们的知识面,更有利于工作的开展和职业发展。