读完本文,你将学会:5 分钟配好监控告警,让服务挂了第一时间知道,甚至自动恢复。
半夜三点的夺命连环 call
周六凌晨三点,小禾被电话吵醒。
“喂?”
“小禾!你那个 AI 生成图片的服务挂了!用户投诉都炸了!”
小禾一个激灵爬起来,打开电脑,SSH 连上服务器:
$curlhttp://localhost:8000/health curl:(7)Failed to connect to localhost port8000: Connection refused服务确实挂了。
他翻了翻日志:
2025-12-06 01:23:45 | ERROR | CUDA out of memory 2025-12-06 01:23:45 | INFO | 服务已关闭服务在凌晨一点就挂了,但直到三点用户投诉,他才知道。
整整两个小时,服务处于宕机状态。
小禾重启服务后,躺在床上睡不着了。
“如果服务挂了能立刻通知我就好了……”
监控的三个层次
第二天,小禾开始研究监控方案。
他发现监控有三个层次:
小禾决定从最基础的开始:存活检测。
“至少服务挂了要第一时间知道。”
方案一:UptimeRobot(5 分钟搞定)
小禾搜了一圈,发现最简单的方案是 UptimeRobot——一个免费的在线监控服务。
第一步:暴露健康检查端点
# app/api/endpoints/health.pyfromfastapiimportAPIRouterfromdatetimeimportdatetime router=APIRouter()@router.get("/health")asyncdefhealth_check():"""健康检查端点"""return{"status":"healthy","timestamp":datetime.now().isoformat()}第二步:注册 UptimeRobot
- 打开 https://uptimerobot.com,注册账号
- 点击 “Add New Monitor”
- 填写配置:
Monitor Type: HTTP(s) Friendly Name: AI Image Service URL: https://your-domain.com/health Monitoring Interval: 5 minutes- 设置告警方式:邮件、Telegram、Slack 都支持
第三步:等着收通知
配置完成后,UptimeRobot 每 5 分钟会请求一次/health。
如果连续失败,你会收到这样的邮件:
🔴 AI Image Service is DOWN URL: https://your-domain.com/health Reason: Connection Timeout Date/Time: 2024-01-20 01:25:00 UTC服务恢复后,还会收到:
🟢 AI Image Service is UP URL: https://your-domain.com/health Was down for: 2 hours 5 minutes Date/Time: 2024-01-20 03:30:00 UTC小禾设置完毕,测试了一下:手动停掉服务,5 分钟后果然收到了告警邮件。
“这也太简单了吧!”
健康检查要检查什么?
小禾用了几天,发现一个问题:
有时候/health返回 200,但实际上服务已经"半死不活"了——API 能响应,但 AI 模型挂了。
他决定升级健康检查:
# app/api/endpoints/health.pyimporttorchfromfastapiimportAPIRouter,Responsefromapp.services.model_managerimportmodel_manager router=APIRouter()@router.get("/health")asyncdefhealth_check(response:Response):"""深度健康检查"""checks={"api":True,"model":False,"gpu":False}# 检查模型是否加载try:checks["model"]=model_manager.pipeisnotNoneexceptException:pass# 检查 GPU 是否可用try:iftorch.cuda.is_available():# 尝试分配一小块显存,确认 GPU 正常test_tensor=torch.zeros(1).cuda()deltest_tensor checks["gpu"]=TrueexceptException:pass# 综合判断all_healthy=all(checks.values())ifnotall_healthy:response.status_code=503# Service Unavailablereturn{"status":"healthy"ifall_healthyelse"unhealthy","checks":checks,"gpu_memory":get_gpu_memory()ifchecks["gpu"]elseNone}defget_gpu_memory():"""获取 GPU 显存信息"""ifnottorch.cuda.is_available():returnNonereturn{"allocated_gb":round(torch.cuda.memory_allocated()/1024**3,2),"reserved_gb":round(torch.cuda.memory_reserved()/1024**3,2),"total_gb":round(torch.cuda.get_device_properties(0).total_memory/1024**3,2)}现在健康检查会真正检查:
{"status":"healthy","checks":{"api":true,"model":true,"gpu":true},"gpu_memory":{"allocated_gb":9.87,"reserved_gb":10.12,"total_gb":24.0}}如果模型没加载或 GPU 挂了,会返回 503:
{"status":"unhealthy","checks":{"api":true,"model":false,"gpu":true},"gpu_memory":{...}}UptimeRobot 只要收到非 2xx 响应,就会触发告警。
方案二:自建 Prometheus + Grafana
UptimeRobot 够用了,但小禾想要更多:
- 想看历史数据趋势
- 想知道每个接口的响应时间
- 想监控 GPU 显存使用率
这就需要自建监控系统了。
架构图
第一步:暴露 Prometheus 指标
安装依赖:
pipinstallprometheus-client prometheus-fastapi-instrumentator添加指标端点:
# app/main.pyfromprometheus_fastapi_instrumentatorimportInstrumentatorfromprometheus_clientimportGauge,Counter,Histogram# 自定义指标GPU_MEMORY_GAUGE=Gauge('gpu_memory_allocated_bytes','GPU memory allocated in bytes')GENERATION_COUNTER=Counter('image_generation_total','Total image generations',['status']# success / failed)GENERATION_LATENCY=Histogram('image_generation_latency_seconds','Image generation latency in seconds',buckets=[1,2,5,10,30,60,120])# 初始化 instrumentatorInstrumentator().instrument(app).expose(app)在业务代码中记录指标:
# app/api/endpoints/generate.pyimporttime@router.post("/shot-image")asyncdefgenerate_shot_image(request:GenerateShotImageRequest):start_time=time.time()try:result=awaitadapter.generate(...)# 记录成功GENERATION_COUNTER.labels(status="success").inc()returnresultexceptExceptionase:# 记录失败GENERATION_COUNTER.labels(status="failed").inc()raisefinally:# 记录耗时latency=time.time()-start_time GENERATION_LATENCY.observe(latency)# 更新 GPU 显存iftorch.cuda.is_available():GPU_MEMORY_GAUGE.set(torch.cuda.memory_allocated())访问/metrics看看效果:
# HELP gpu_memory_allocated_bytes GPU memory allocated in bytes # TYPE gpu_memory_allocated_bytes gauge gpu_memory_allocated_bytes 1.0598932e+10 # HELP image_generation_total Total image generations # TYPE image_generation_total counter image_generation_total{status="success"} 156.0 image_generation_total{status="failed"} 3.0 # HELP image_generation_latency_seconds Image generation latency in seconds # TYPE image_generation_latency_seconds histogram image_generation_latency_seconds_bucket{le="1.0"} 0.0 image_generation_latency_seconds_bucket{le="2.0"} 12.0 image_generation_latency_seconds_bucket{le="5.0"} 89.0 image_generation_latency_seconds_bucket{le="10.0"} 142.0 ...第二步:部署 Prometheus + Grafana
用 Docker Compose 一键部署:
# docker-compose.monitoring.ymlversion:'3.8'services:prometheus:image:prom/prometheus:latestports:-"9090:9090"volumes:-./prometheus.yml:/etc/prometheus/prometheus.yml-prometheus_data:/prometheuscommand:-'--config.file=/etc/prometheus/prometheus.yml'-'--storage.tsdb.retention.time=30d'grafana:image:grafana/grafana:latestports:-"3000:3000"volumes:-grafana_data:/var/lib/grafanaenvironment:-GF_SECURITY_ADMIN_PASSWORD=your_passwordalertmanager:image:prom/alertmanager:latestports:-"9093:9093"volumes:-./alertmanager.yml:/etc/alertmanager/alertmanager.ymlvolumes:prometheus_data:grafana_data:Prometheus 配置:
# prometheus.ymlglobal:scrape_interval:15salerting:alertmanagers:-static_configs:-targets:['alertmanager:9093']rule_files:-'alert_rules.yml'scrape_configs:-job_name:'ai-service'static_configs:-targets:['host.docker.internal:8000']# 你的 AI 服务地址第三步:配置告警规则
# alert_rules.ymlgroups:-name:ai-service-alertsrules:# 服务宕机-alert:ServiceDownexpr:up{job="ai-service"}== 0for:1mlabels:severity:criticalannotations:summary:"AI 服务宕机"description:"服务已经宕机超过 1 分钟"# GPU 显存超过 90%-alert:GPUMemoryHighexpr:gpu_memory_allocated_bytes / (24 * 1024 * 1024 * 1024)>0.9for:5mlabels:severity:warningannotations:summary:"GPU 显存使用率过高"description:"显存使用率超过 90%,持续 5 分钟"# 生成失败率超过 10%-alert:HighFailureRateexpr:|rate(image_generation_total{status="failed"}[5m]) / rate(image_generation_total[5m]) > 0.1for:5mlabels:severity:warningannotations:summary:"图片生成失败率过高"description:"最近 5 分钟失败率超过 10%"# 响应时间过长-alert:HighLatencyexpr:|histogram_quantile(0.95, rate(image_generation_latency_seconds_bucket[5m])) > 60for:5mlabels:severity:warningannotations:summary:"图片生成响应时间过长"description:"P95 响应时间超过 60 秒"第四步:配置告警通知
AlertManager 支持多种通知方式。小禾配置了邮件和飞书:
# alertmanager.ymlglobal:smtp_smarthost:'smtp.example.com:587'smtp_from:'alertmanager@example.com'smtp_auth_username:'alertmanager@example.com'smtp_auth_password:'your_password'route:receiver:'default'group_wait:30sgroup_interval:5mrepeat_interval:4hroutes:# 严重告警立即通知-match:severity:criticalreceiver:'critical-alerts'repeat_interval:15mreceivers:-name:'default'email_configs:-to:'dev-team@example.com'-name:'critical-alerts'email_configs:-to:'oncall@example.com'webhook_configs:# 飞书机器人-url:'https://open.feishu.cn/open-apis/bot/v2/hook/xxxxx'第五步:Grafana 看板
启动后访问http://localhost:3000,配置 Prometheus 数据源,然后创建看板。
小禾看着漂亮的图表,心情舒畅。
“终于有可视化了!”
方案对比:怎么选?
| 方案 | 复杂度 | 成本 | 功能 | 适合场景 |
|---|---|---|---|---|
| UptimeRobot | 低 | 免费 | 存活检测 + 告警 | 个人项目、MVP |
| Prometheus + Grafana | 高 | 服务器资源 | 完整监控 + 可视化 | 生产环境 |
| 云厂商方案 | 中 | 按量付费 | 开箱即用 | 预算充足 |
小禾的建议:
个人项目 → UptimeRobot,5 分钟搞定 小团队 → UptimeRobot + 简单 Prometheus 正式环境 → Prometheus + Grafana + AlertManager 土豪 → 直接用云厂商的监控服务监控配置清单
小禾整理了一份清单:
| 检查项 | 方法 | 告警阈值 |
|---|---|---|
| 服务存活 | HTTP 健康检查 | 连续失败 2 次 |
| GPU 显存 | nvidia-smi / torch | > 90% 持续 5 分钟 |
| 响应时间 | Prometheus Histogram | P95 > 60s |
| 失败率 | Counter 比率 | > 10% 持续 5 分钟 |
| 磁盘空间 | node_exporter | > 85% |
还有一件事:自动重启
监控告警解决了"知道挂了"的问题,但还有一个问题:凌晨三点收到告警,难道要爬起来重启?
小禾加了个自动重启机制:
# 使用 systemd 管理服务# /etc/systemd/system/ai-service.service[Unit]Description=AI Image Generation ServiceAfter=network.target[Service]Type=simpleUser=deployWorkingDirectory=/opt/ai-serviceExecStart=/opt/ai-service/venv/bin/python run.pyRestart=alwaysRestartSec=10[Install]WantedBy=multi-user.target关键配置:
Restart=always:无论什么原因退出,都自动重启RestartSec=10:重启前等待 10 秒
这样服务挂了会自动重启,告警只是通知你"发生过故障"。
小禾的感悟
那个凌晨三点的电话, 让我明白了一个道理: 服务会挂, 这是墨菲定律。 问题不是"会不会挂", 而是"挂了你知不知道"。 UptimeRobot 五分钟搞定, Prometheus 一天能跑起来, 没有借口不做监控。 告警是保险, 自动重启是兜底, 两样都有才能睡好觉。 现在我终于可以说: "服务挂了?让我看看告警…… 哦,已经自动恢复了。" 然后翻个身,继续睡。 这才是生活该有的样子。小禾看着 Grafana 上绿油油的曲线,终于睡了个安稳觉。
系列完结
恭喜你读完了「AI 基础设施部署」系列的全部 6 篇文章!
回顾一下我们走过的路:
① 环境配置 → CUDA、PyTorch 一次配对 ② 模型部署 → vLLM 高性能推理 ③ 应用平台 → Dify 快速搭建 ④ 自动化 → n8n 工作流 ⑤ GPU 原理 → CUDA Tile 科普 ⑥ 监控告警 → 服务挂了第一时间知道从一台裸机,到稳定运行的 AI 服务,这就是完整的链路。
有了这套基础设施,你就可以专注于业务开发,不用再担心"服务又挂了"。
收藏 AI 基础设施部署合集(超详细导读),遇到问题随时回来查。
欢迎关注我
我将持续分享 AI 应用开发的实战经验。
有问题欢迎留言,我会尽量回复。