Skip to content

Full-Stack Monitoring 全栈监控项目

一个跑在 1.7G 小服务器上的完整监控栈:主机指标 + 业务指标 + 告警邮件 + 可视化面板。 设计目标:资源最小化、配置可复现、面试可讲清楚

在线 Demo

  • Grafana 面板http://你的阿里云IP:3000(登录 admin/admin)
  • Prometheus 查询页面http://你的阿里云IP:9090
  • Alertmanagerhttp://你的阿里云IP:9093

⚠️ 请把上面 你的阿里云IP 替换成真实公网 IP。

项目背景

解决的问题

公司有 5 个核心网站(百度/Google/GitHub/自己产品站/支付网关),需要一个"从上到下"完整的监控:

  • 主机层:CPU/内存/磁盘/网络是否健康
  • 业务层:网站能否访问、响应多快、SSL 证书是否快过期
  • 告警层:出问题立即发邮件给运维
  • 可视化层:用 Grafana 把数据画成图

设计约束

约束影响
服务器只有 1.7G 内存选 Prometheus+Grafana 而非更重的 Zabbix;自研 Exporter 不用 cAdvisor
必须能发邮件Alertmanager + QQ SMTP
必须可复现全部容器化 + 一键 docker compose up
必须可面试讲每个组件职责清晰、踩的坑都记录

架构图

┌──────────────────────────────────────────────────────────────┐
│                    Alertmanager (9093)                        │
│                  告警分组 / 抑制 / 静默 / 邮件                  │
└────────────────────▲─────────────────────────────────────────┘
                     │ firing alerts

┌────────────────────┴─────────────────────────────────────────┐
│                  Prometheus (9090)                            │
│         抓取 / 存储 / 告警规则评估 (15s 周期)                  │
│         ┌──────────┬──────────┬──────────┐                   │
│         │ 主机规则  │ 业务规则  │ 自研规则  │  (alerts/*.yml)  │
│         └──────────┴──────────┴──────────┘                   │
└──────▲──────────────▲──────────────▲─────────────────────────┘
       │ scrape       │ scrape        │ scrape
       │ 15s          │ 15s           │ 30s
       │              │               │
┌──────┴──────┐  ┌────┴────┐  ┌───────┴────────┐
│node-exporter│  │ Grafana │  │ site_check     │
│   (9100)    │  │ (3000)  │  │  自研 Exporter │
│  主机指标   │  │ 可视化  │  │  业务指标 (9877)│
│             │  │         │  │  + SSL 检查    │
└─────────────┘  └────┬────┘  └────────────────┘
                      │ query
                      │ PromQL

                ┌──────────┐
                │  邮件发送  │ ← smtp.qq.com:465
                │  QQ 邮箱  │
                └──────────┘

数据流:Exporter 暴露指标 → Prometheus 15s 抓一次 → 评估告警规则 → 触发后推给 Alertmanager → 按 receiver 发送邮件 → Grafana 同时拉数据画图。

技术栈

组件版本镜像内存作用
Prometheus2.55prom/prometheus:v2.55.1~256M时序数据库 + 告警规则
Alertmanager0.28.1prom/alertmanager:v0.28.1~32M告警分组/抑制/邮件
Grafana11.2grafana/grafana:11.2.0~128M可视化面板
node-exporter1.8.2prom/node-exporter:v1.8.2~32M主机指标
site_check自研python:3.9-slim~50M业务指标(站点可用性)

总内存开销:~500M / 1.7G 可用(30% 占用率)

核心组件说明

1. site_check 自研 Exporter(亮点)

为什么自研:node-exporter 只抓主机指标,不能告诉我"百度能不能访问""SSL 还有几天过期"。这些业务指标是 node-exporter 给不出来的,所以自己写。

4 个核心指标

指标类型含义
site_upgauge1=可达, 0=不可达
site_response_time_secondsgaugeHTTP 响应时间(秒)
site_status_codegaugeHTTP 状态码(0=连接失败)
site_ssl_expiry_daysgaugeSSL 证书剩余天数(负数=已过期)

采集流程

scheduler_loop():
    for target in targets.json:
        site_up = HEAD target.url
        site_response_time_seconds = (time_after - time_before)
        site_status_code = response.status_code
        if target.check_ssl:
            site_ssl_expiry_days = (cert.not_after - now).days
        sleep(target.interval)

2. textfile 容器指标

为什么不用 cAdvisor:cAdvisor 多吃 50-100M 内存,我们 1.7G 扛不住。

怎么做的

  1. shell 脚本 collect_container_metrics.sh 每分钟跑一次
  2. docker inspect 抓所有容器的 RestartCountState.Running
  3. 写成 Prometheus 文本格式写到 node-exporter-textfile/ 目录
  4. node-exporter 通过 --collector.textfile.directory 自动读

3. 告警邮件链路

关键点:必须用 smtp.qq.com:465域名,不是 IP)。
QQ 邮箱的 SSL 证书只签发给域名,IP 直连会触发 x509: cannot validate certificate 错误。

告警规则

5 条业务告警

#告警名触发条件严重度含义
1SiteDownsite_up == 0 持续 2mincritical站点完全不可达
2SiteSlowsite_response_time_seconds > 3 持续 5minwarning站点响应太慢
3SiteHttpErrorsite_status_code != 200 持续 2minwarningHTTP 状态码非 200
4SslCertExpiringSoonsite_ssl_expiry_days < 30 持续 1hwarning证书 30 天内过期
5SslCertExpiringCriticalsite_ssl_expiry_days < 7 持续 10mincritical证书一周内过期

10 条主机告警

#告警名触发条件严重度
1HighCPUUsageCPU > 80% 持续 5minwarning
2CriticalCPUUsageCPU > 95% 持续 2mincritical
3HighMemoryUsage内存 > 85% 持续 5minwarning
4HighDiskUsage根分区 > 85%warning
5DiskWillFillIn24h预测 24h 内写满warning
6HighLoadAverage5min load > CPU 核数 × 2warning
7NetworkInterfaceDownnode_network_up == 0 且不是 lo/dockerwarning
8HostUnreachablePrometheus 抓不到 node-exportercritical
9ContainerRestarting容器 5min 内重启 ≥ 3 次warning
10DockerDaemonDowndocker.sock 不可达critical

Grafana 面板

启动后自动加载 2 个面板:

Host Overview(主机面板)

  • CPU 使用率(时序图)
  • 内存使用率(时序图)
  • 根分区使用率(stat)
  • 网络接收速率(时序图)
  • 系统 Load (5min avg)(stat)
  • 容器启动次数(时序图)← textfile 采集

Site Overview(业务面板)

  • 站点可用性(5min 平均)
  • 站点响应时间趋势
  • SSL 证书剩余天数(最紧急)
  • HTTP 状态码分布
  • 容器启动次数
  • Active 告警数

踩过的坑

1. 镜像源问题

症状docker pull 极慢或超时。
原因:docker.io 在国内被限速。
正解:用 docker.m.daocloud.io/<image> 前缀(DaoCloud 镜像加速)。

2. alertmanager 0.27 静默失败

症状:配置看起来全对,日志完全沉默,邮件发不出。
原因:0.27 SMTP 发送存在静默 bug。
正解:升级到 0.28.1+,并加 --log.level=debug

3. TLS 证书 IP SAN 验证失败

症状x509: cannot validate certificate for IP
原因:QQ SMTP 465 的 SSL 证书只签发给 smtp.qq.com 域名。
正解:用域名 smtp.qq.com:465
口诀TLS 用域名,IP 绕道是雷区

4. docker compose restart 不重读 compose

症状:改了 healthcheck,restart 完没生效。
原因restart 是 stop + start,不重新解析 compose。
正解:改 compose 文件后必须用 docker compose up -d --force-recreate

5. exporter 启动读一次 config

症状:改了 targets.json,exporter 内存里还是旧目标。
原因:只在启动时读一次。
正解:改 targets.json 后必须 force-recreate 容器。

6. restart: unless-stopped 导致重复告警

症状:容器挂了被拉起来,alertmanager 不停发"重启"邮件。
正解:alertmanager 邮件用 repeat_interval: 4h(不是 30s)。

后续可优化点

  • [ ] 用 cAdvisor 替代 textfile(要看容器 CPU/内存历史曲线时再上)
  • [ ] Alertmanager 加 Webhook 推送到企业微信
  • [ ] Prometheus 远程存储(解决 15 天数据保留期问题)
  • [ ] exporter 加上 site_content_hash 指标,检测页面内容被篡改
  • [ ] Grafana 加告警(直接在面板上设阈值)

相关文件

  • README.md:项目完整说明
  • docker-compose.yml:5 服务编排
  • prometheus/alerts/*.yml:告警规则
  • exporters/site_check/exporter.py:自研 Exporter 源码
  • collect_container_metrics.sh:textfile 容器指标采集脚本
  • grafana/provisioning/dashboards/*.json:面板 JSON

Powered by VitePress