目录
监控这事,就像开车要看仪表盘。想象一下:你开着没有仪表盘的车在高速上飙到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依赖:
<!-- 开启监控端点,提供指标 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- 处理指标转换为Prometheus兼容的格式 -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
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策略,强调打破开发和运维之间的隔阂,加强团队之间的协作和沟通。对于开发而言,掌握运维相关的知识,主动扩展我们的知识面,更有利于工作的开展和职业发展。

1369

被折叠的 条评论
为什么被折叠?



