实时检测系统资源监控:Prometheus+Grafana对GPU/内存/请求量实时看板
1. 项目背景与监控需求
当你部署了一个像手机检测这样的AI应用后,最怕遇到什么情况?服务器突然卡死,用户访问不了,或者GPU跑满了却不知道原因。这时候,一个清晰的监控看板就像汽车的仪表盘,能让你一眼看清系统的“健康状况”。
我们之前介绍的手机检测系统,基于DAMO-YOLO和TinyNAS技术,主打“小、快、省”,专门为手机端低算力场景设计。但再轻量的系统,运行久了也会遇到资源瓶颈。GPU使用率是不是一直很高?内存有没有泄漏?用户请求量有没有突增?这些都需要实时掌握。
今天要分享的,就是如何用Prometheus+Grafana这套黄金组合,为你的AI应用搭建一个专业的资源监控看板。这不是那种简单的命令行查看,而是像下面这样的可视化仪表盘:
┌─────────────────────────────────────────────────────────────┐ │ 系统资源监控看板 │ ├──────────────────────┬──────────────────────────────────────┤ │ GPU使用率: 85% │ 内存使用: 4.2GB/8GB (52%) │ │ ┌────────────┐ │ ┌────────────┐ │ │ │█████████░░░│ │ │██████░░░░░░│ │ │ └────────────┘ │ └────────────┘ │ │ │ │ │ 请求量/分钟: 120 │ CPU使用率: 45% │ │ ┌────────────┐ │ ┌────────────┐ │ │ │ ▲ │ │ │████░░░░░░░░│ │ │ │ │ │ │ └────────────┘ │ │ └────────────┘ │ │ └──────────────────────┴──────────────────────────────────────┘有了这个看板,你就能:
- 实时看到GPU、内存、CPU的使用情况
- 监控用户请求量和响应时间
- 设置告警,在问题发生前收到通知
- 分析历史数据,优化系统性能
2. 监控方案选型:为什么是Prometheus+Grafana?
市面上监控工具很多,为什么偏偏选这套组合?让我用大白话给你解释一下。
Prometheus就像个“数据收集员”。它定时去各个系统组件那里“问一问”:GPU现在用了多少?内存还剩多少?请求处理了几个?然后把数据存起来。它的特点是:
- 主动拉取数据:不用你推,它自己会去拿
- 时间序列数据库:专门存带时间戳的数据,比如“今天下午3点,GPU使用率85%”
- 灵活的查询语言:你可以用类似SQL的语句查数据
Grafana则是个“数据展示员”。它从Prometheus那里拿到数据,然后画成漂亮的图表。它的特点是:
- 丰富的图表类型:折线图、柱状图、仪表盘、热力图...
- 可定制的看板:你想看什么数据,就放什么图表
- 告警功能:数据异常时发邮件、发微信通知你
这套组合的优势很明显:
- 开源免费:不用花一分钱
- 生态成熟:社区活跃,问题好解决
- 扩展性强:想监控什么就加什么
- 部署简单:几个命令就能跑起来
对于我们的手机检测系统来说,这套方案再合适不过了。系统本身轻量,监控也要轻量但够用。
3. 环境准备与快速部署
3.1 系统要求
在开始之前,先确认你的环境:
- 操作系统:Ubuntu 20.04或更高版本(其他Linux发行版也类似)
- 内存:至少2GB空闲内存
- 存储:至少5GB空闲空间
- 网络:能访问互联网下载安装包
我们的手机检测系统已经在运行了,假设它的访问地址是http://你的服务器IP:7860。
3.2 一键安装脚本
为了简化安装,我准备了一个一键安装脚本。你只需要复制粘贴就能完成大部分工作。
#!/bin/bash # 监控系统一键安装脚本 # 保存为 install_monitor.sh,然后运行: bash install_monitor.sh echo "开始安装监控系统..." # 1. 安装Docker(如果还没安装) if ! command -v docker &> /dev/null; then echo "安装Docker..." curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh sudo usermod -aG docker $USER echo "Docker安装完成" else echo "Docker已安装" fi # 2. 创建监控目录 echo "创建监控目录..." mkdir -p ~/monitoring/{prometheus,grafana} cd ~/monitoring # 3. 创建Prometheus配置文件 cat > prometheus/prometheus.yml << 'EOF' global: scrape_interval: 15s # 每15秒收集一次数据 evaluation_interval: 15s scrape_configs: - job_name: 'prometheus' static_configs: - targets: ['localhost:9090'] - job_name: 'node_exporter' static_configs: - targets: ['node_exporter:9100'] - job_name: 'cadvisor' static_configs: - targets: ['cadvisor:8080'] EOF # 4. 创建Docker Compose文件 cat > docker-compose.yml << 'EOF' version: '3.8' services: prometheus: image: prom/prometheus:latest container_name: prometheus ports: - "9090:9090" volumes: - ./prometheus:/etc/prometheus - prometheus_data:/prometheus command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' - '--web.console.libraries=/etc/prometheus/console_libraries' - '--web.console.templates=/etc/prometheus/consoles' - '--storage.tsdb.retention.time=200h' - '--web.enable-lifecycle' restart: unless-stopped grafana: image: grafana/grafana:latest container_name: grafana ports: - "3000:3000" volumes: - grafana_data:/var/lib/grafana environment: - GF_SECURITY_ADMIN_PASSWORD=admin123 restart: unless-stopped node_exporter: image: prom/node-exporter:latest container_name: node_exporter ports: - "9100:9100" volumes: - /proc:/host/proc:ro - /sys:/host/sys:ro - /:/rootfs:ro command: - '--path.procfs=/host/proc' - '--path.rootfs=/rootfs' - '--path.sysfs=/host/sys' - '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)' restart: unless-stopped cadvisor: image: gcr.io/cadvisor/cadvisor:latest container_name: cadvisor ports: - "8080:8080" volumes: - /:/rootfs:ro - /var/run:/var/run:ro - /sys:/sys:ro - /var/lib/docker/:/var/lib/docker:ro - /dev/disk/:/dev/disk:ro privileged: true devices: - /dev/kmsg restart: unless-stopped volumes: prometheus_data: grafana_data: EOF echo "安装脚本创建完成!" echo "请运行以下命令启动监控系统:" echo "cd ~/monitoring && docker-compose up -d"运行这个脚本:
# 给脚本执行权限 chmod +x install_monitor.sh # 运行脚本 bash install_monitor.sh3.3 启动监控服务
脚本运行完后,进入监控目录启动服务:
cd ~/monitoring docker-compose up -d等个几十秒,用下面的命令检查服务状态:
# 查看所有容器状态 docker-compose ps # 应该看到类似这样的输出: # Name Command State Ports # ------------------------------------------------------------------------------- # cadvisor /usr/bin/cadvisor -logtostderr Up 0.0.0.0:8080->8080/tcp # grafana /run.sh Up 0.0.0.0:3000->3000/tcp # node_exporter /bin/node_exporter --path. ... Up 0.0.0.0:9100->9100/tcp # prometheus /bin/prometheus --config.f ... Up 0.0.0.0:9090->9090/tcp如果所有服务都是“Up”状态,恭喜你,监控系统的基础部分已经部署成功了!
4. 配置手机检测系统的监控
现在监控系统跑起来了,但还没监控我们的手机检测应用。我们需要让Prometheus能收集到应用的数据。
4.1 为手机检测系统添加监控端点
手机检测系统是用Gradio做的Web应用,我们需要给它加个“健康检查”接口,让Prometheus能获取到应用的状态信息。
修改手机检测系统的app.py文件,添加监控相关代码:
# 在原有代码基础上添加以下内容 import psutil import time from prometheus_client import Counter, Gauge, Histogram, generate_latest, CONTENT_TYPE_LATEST from flask import Flask, Response import threading # 创建监控指标 REQUEST_COUNT = Counter('phone_detection_requests_total', 'Total number of detection requests') REQUEST_LATENCY = Histogram('phone_detection_request_latency_seconds', 'Request latency in seconds') GPU_MEMORY_USAGE = Gauge('phone_detection_gpu_memory_usage_mb', 'GPU memory usage in MB') SYSTEM_MEMORY_USAGE = Gauge('phone_detection_system_memory_usage_percent', 'System memory usage percentage') CPU_USAGE = Gauge('phone_detection_cpu_usage_percent', 'CPU usage percentage') # 创建Flask应用用于提供监控数据 monitor_app = Flask(__name__) @monitor_app.route('/metrics') def metrics(): """提供Prometheus格式的监控数据""" # 更新系统指标 update_system_metrics() # 返回所有指标数据 return Response(generate_latest(), mimetype=CONTENT_TYPE_LATEST) def update_system_metrics(): """更新系统资源指标""" # 获取系统内存使用率 memory = psutil.virtual_memory() SYSTEM_MEMORY_USAGE.set(memory.percent) # 获取CPU使用率 CPU_USAGE.set(psutil.cpu_percent(interval=1)) # 这里简化处理,实际GPU监控需要根据你的环境调整 # 如果你有NVIDIA GPU,可以安装nvidia-ml-py3库 try: import pynvml pynvml.nvmlInit() handle = pynvml.nvmlDeviceGetHandleByIndex(0) info = pynvml.nvmlDeviceGetMemoryInfo(handle) GPU_MEMORY_USAGE.set(info.used / 1024 / 1024) # 转换为MB pynvml.nvmlShutdown() except: # 如果没有GPU或库不存在,设置一个默认值 GPU_MEMORY_USAGE.set(0) def start_monitor_server(): """启动监控服务器""" monitor_app.run(host='0.0.0.0', port=5000) # 在Gradio应用启动后,启动监控服务器 if __name__ == "__main__": # 启动监控服务器(在后台线程中运行) monitor_thread = threading.Thread(target=start_monitor_server, daemon=True) monitor_thread.start() # 原有的Gradio应用启动代码 demo.launch(server_name="0.0.0.0", server_port=7860)还需要修改requirements.txt,添加新的依赖:
# 在原有依赖基础上添加 prometheus-client==0.20.0 psutil==5.9.8 flask==3.0.2 # 如果有NVIDIA GPU,可以添加 # nvidia-ml-py3==7.352.0然后重启手机检测服务:
# 进入手机检测目录 cd /root/phone-detection # 安装新的依赖 pip install -r requirements.txt # 重启服务 supervisorctl restart phone-detection4.2 配置Prometheus收集应用数据
现在手机检测系统有了监控接口(在5000端口),我们需要告诉Prometheus去收集这个数据。
编辑Prometheus的配置文件:
cd ~/monitoring nano prometheus/prometheus.yml在文件末尾添加新的job配置:
# 在scrape_configs部分添加 scrape_configs: # ... 原有的配置 ... - job_name: 'phone_detection' static_configs: - targets: ['你的服务器IP:5000'] metrics_path: '/metrics' scrape_interval: 10s # 每10秒收集一次重启Prometheus使配置生效:
cd ~/monitoring docker-compose restart prometheus4.3 验证监控数据
现在可以检查监控数据是否正常收集了。
首先访问手机检测的监控端点:
http://你的服务器IP:5000/metrics你应该能看到类似这样的数据:
# HELP phone_detection_requests_total Total number of detection requests # TYPE phone_detection_requests_total counter phone_detection_requests_total 0 # HELP phone_detection_system_memory_usage_percent System memory usage percentage # TYPE phone_detection_system_memory_usage_percent gauge phone_detection_system_memory_usage_percent 45.2 # HELP phone_detection_cpu_usage_percent CPU usage percentage # TYPE phone_detection_cpu_usage_percent gauge phone_detection_cpu_usage_percent 12.7然后访问Prometheus的Web界面(http://你的服务器IP:9090),在查询框输入phone_detection_,应该能看到我们定义的监控指标。
5. 配置Grafana监控看板
数据收集好了,现在我们来创建漂亮的监控看板。
5.1 登录Grafana
打开浏览器,访问:
http://你的服务器IP:3000用以下信息登录:
- 用户名:admin
- 密码:admin123(这是我们在一键脚本里设置的)
第一次登录会要求改密码,你可以改,也可以先用默认的。
5.2 添加数据源
- 点击左边菜单的Configuration(小齿轮图标)→Data Sources
- 点击Add data source
- 选择Prometheus
- 配置Prometheus地址:
- URL:
http://prometheus:9090(注意:这里用服务名,因为都在Docker网络内)
- URL:
- 点击Save & Test,应该显示“Data source is working”
5.3 导入预置的监控看板
Grafana社区有很多现成的看板模板,我们直接导入一个适合的。
- 点击左边菜单的Dashboards(四个方块图标)→New→Import
- 在“Import via grafana.com”框输入:1860 (这是Node Exporter的看板ID)
- 点击Load
- 选择Prometheus数据源,点击Import
现在你就有了一个系统资源监控看板,可以看到CPU、内存、磁盘、网络等基本信息。
5.4 创建手机检测专属看板
系统监控有了,我们还需要一个专门看手机检测应用状态的看板。
点击Dashboards→New→New Dashboard,然后添加以下面板:
面板1:请求量监控(折线图)
- 标题:检测请求量(每分钟)
- 查询语句:
rate(phone_detection_requests_total[1m]) - 可视化:选择Time series(时间序列图)
- 单位:req/min(请求/分钟)
面板2:系统内存使用率(仪表盘)
- 标题:系统内存使用率
- 查询语句:
phone_detection_system_memory_usage_percent - 可视化:选择Gauge(仪表盘)
- 单位:percent(百分比)
- 阈值:设置警告线(比如80%)和危险线(比如90%)
面板3:CPU使用率(折线图)
- 标题:CPU使用率
- 查询语句:
phone_detection_cpu_usage_percent - 可视化:选择Time series
- 单位:percent
面板4:GPU内存使用(统计面板)
- 标题:GPU内存使用
- 查询语句:
phone_detection_gpu_memory_usage_mb - 可视化:选择Stat(统计面板)
- 单位:bytes(会自动转换为MB/GB)
面板5:服务状态(状态面板)
- 标题:服务状态
- 查询语句:
up{job="phone_detection"} - 可视化:选择Stat
- 值映射:设置1=正常,0=异常
排列好这些面板后,你的看板大概长这样:
┌─────────────────┬─────────────────┬─────────────────┐ │ 请求量/分钟 │ 系统内存使用率 │ GPU内存使用 │ │ [折线图] │ [仪表盘] │ [统计面板] │ ├─────────────────┼─────────────────┼─────────────────┤ │ CPU使用率 │ 服务状态 │ │ │ [折线图] │ [状态面板] │ │ └─────────────────┴─────────────────┴─────────────────┘点击右上角的Save,给看板起个名字,比如“手机检测系统监控”。
6. 高级监控配置
基础监控有了,我们再来加点高级功能,让监控更智能。
6.1 设置告警规则
当系统出现问题时,我们希望能自动收到通知。Grafana的告警功能可以帮我们做到。
在Grafana中创建告警规则:
- 进入刚才创建的看板
- 点击面板标题 →Edit
- 在右侧找到Alert标签页
- 点击Create alert rule from this panel
以内存使用率为例,设置告警:
- 规则名称:内存使用率过高
- 评估间隔:1m
- 条件:当
phone_detection_system_memory_usage_percent> 80 持续 5分钟 - 通知渠道:可以配置邮件、Slack、微信等
6.2 监控请求延迟
除了请求量,响应速度也很重要。我们需要在代码中添加延迟监控。
修改手机检测系统的监控代码,添加请求延迟记录:
import time from functools import wraps def track_request_latency(func): """装饰器:记录请求延迟""" @wraps(func) def wrapper(*args, **kwargs): start_time = time.time() result = func(*args, **kwargs) latency = time.time() - start_time # 记录延迟 REQUEST_LATENCY.observe(latency) # 记录请求次数 REQUEST_COUNT.inc() return result return wrapper # 在检测函数上使用装饰器 @track_request_latency def detect_phone(image): # 原有的检测逻辑 # ... return result6.3 监控模型推理性能
对于AI应用,模型推理的性能是关键指标。我们可以监控:
# 添加模型推理相关的监控指标 MODEL_INFERENCE_TIME = Histogram( 'phone_detection_model_inference_seconds', 'Model inference time in seconds', buckets=[0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1.0, 5.0] ) DETECTION_CONFIDENCE = Histogram( 'phone_detection_confidence', 'Detection confidence distribution', buckets=[0.1, 0.3, 0.5, 0.7, 0.9, 1.0] ) def track_inference_performance(func): """装饰器:记录模型推理性能""" @wraps(func) def wrapper(*args, **kwargs): start_time = time.time() result = func(*args, **kwargs) inference_time = time.time() - start_time MODEL_INFERENCE_TIME.observe(inference_time) # 如果有置信度信息,也记录下来 if result and 'confidence' in result: DETECTION_CONFIDENCE.observe(result['confidence']) return result return wrapper7. 实际效果展示
配置完成后,让我们看看监控看板在实际运行中是什么样子。
7.1 正常情况下的监控看板
当系统运行平稳时,看板显示:
- 请求量:平稳的波浪线,每分钟大约50-100个请求
- 内存使用率:保持在40-60%之间
- CPU使用率:平时30%左右,请求来时短暂升高
- GPU内存:稳定在1.2GB左右(模型加载后)
- 服务状态:绿色“正常”状态
7.2 压力测试时的监控看板
当我们模拟大量用户同时访问时:
- 请求量:突然飙升到每分钟500+请求
- 内存使用率:逐渐上升到75%
- CPU使用率:冲到80-90%
- 响应延迟:从平均200ms增加到800ms
- 服务状态:仍然绿色,但各项指标接近阈值
7.3 异常情况告警
当内存使用超过80%持续5分钟时:
- Grafana检测到异常
- 触发告警规则
- 发送邮件通知管理员
- 看板上内存面板变黄色(警告)或红色(严重)
管理员收到通知后,可以立即查看监控看板,快速定位问题。
8. 监控数据的使用技巧
监控数据不只是用来看的,还能帮我们优化系统。这里分享几个实用技巧。
8.1 通过监控发现性能瓶颈
看监控数据时,要特别关注这些模式:
内存缓慢增长:可能是有内存泄漏
- 现象:内存使用率随时间缓慢上升,重启后恢复
- 解决方法:检查代码中的缓存、大对象是否及时释放
CPU使用率与请求量不匹配:
- 现象:请求量没变,但CPU使用率突然升高
- 可能原因:某个请求处理异常,陷入死循环
GPU内存使用异常:
- 现象:GPU内存占满,但请求量不大
- 可能原因:模型重复加载,或显存没释放
8.2 设置合理的监控阈值
阈值设得太低,整天收到误报;设得太高,真出问题才发现。建议这样设置:
- 内存使用率:警告80%,严重90%
- CPU使用率:警告85%,严重95%
- 请求延迟:警告500ms,严重1000ms
- 错误率:警告1%,严重5%
8.3 定期查看监控报告
Grafana可以生成监控报告,定期发送到邮箱。设置方法:
- 在看板页面,点击Share→Report
- 配置报告名称、频率(每天/每周)、接收邮箱
- 点击Send test测试,然后保存
这样你每周都能收到系统的“体检报告”,了解系统运行趋势。
9. 总结
9.1 监控系统带来的价值
通过这一套监控方案,我们为手机检测系统装上了“眼睛”和“警报器”。现在你可以:
- 实时掌握系统状态:不用登录服务器,打开网页就能看到所有指标
- 快速定位问题:出问题时,看监控数据就能知道是CPU、内存还是网络的问题
- 预防性维护:在问题发生前收到告警,提前处理
- 性能优化依据:通过历史数据,找到系统的瓶颈点
- 容量规划参考:根据使用趋势,决定什么时候需要升级服务器
9.2 关键配置回顾
整个监控系统的核心配置:
- Prometheus配置:定义了收集哪些数据、多久收集一次
- 应用监控端点:在代码中添加
/metrics接口暴露数据 - Grafana看板:把数据变成直观的图表
- 告警规则:设置阈值,异常时自动通知
9.3 下一步建议
如果你还想进一步优化监控系统,可以考虑:
- 监控更多指标:磁盘IO、网络流量、数据库连接数等
- 设置分级告警:不同级别的问题,通知不同的人
- 集成更多通知渠道:除了邮件,还可以加微信、钉钉、Slack
- 历史数据分析:用监控数据做容量规划,预测什么时候需要扩容
监控不是一次性的工作,而是持续的过程。随着系统的发展,监控也需要不断调整和优化。
9.4 遇到问题怎么办
如果在配置过程中遇到问题,可以:
- 检查服务状态:
docker-compose ps看所有服务是否正常 - 查看日志:
docker-compose logs -f 服务名看具体错误信息 - 验证数据:直接访问
http://IP:5000/metrics看是否有数据 - 检查配置:确认Prometheus配置中的IP和端口是否正确
记住,好的监控系统不是一蹴而就的。先从核心指标开始,慢慢完善。最重要的是,监控数据要真正用起来,为你的决策提供依据。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。