
最近有个朋友问我想把自己那几台服务器和线上小业务纳入监控体系但又不想上来就整 k8s 那套重家伙问我 Prometheus Grafana 这个黄金组合到底该怎么落地。我正好近期又完整搭过一遍从拉镜像到配告警、接 Alertmanager中间也踩了不少文档里不会明说的坑。这篇就把我实际操作的完整流程和经验沉淀下来内容包括架构选型、docker-compose 编排、指标抓取原理、Grafana 面板配置、PromQL 基础、告警规则编写和 Telegram/邮件通知接入最后附上常见问题排查。如果你正准备搭一套能真正用起来的监控系统这篇文章可以直接照着做。1. 监控架构选型为什么是 Prometheus Grafana1.1 这套组合到底解决了什么问题先说结论Prometheus 负责采集和存储指标Grafana 负责把指标画成图表并承担告警展示的入口Alertmanager 则专职处理告警的收敛和分发。三个组件各管一段职责清晰这在运维体系里非常重要——你不会希望一个工具既要存数据又要画图还要负责把告警发到钉钉一旦出问题排查起来全是耦合。我之前也用过 Zabbix它有内置的告警和绘图但说实话配置项多且偏传统图表的美观度和灵活性都不如现在的 Grafana。而 Prometheus 这套组合最吸引我的点其实是两个一是它的数据模型极其统一所有指标都是带标签label的时间序列查询语法 PromQL 一旦上手排查问题时写一条表达式就能从多个维度切数据二是生态太丰富了exporter 遍地都是从 Linux 主机到 MySQL、Redis、Nginx、Java 应用基本都有现成的采集器不用自己造轮子。Prometheus 本身是开源项目也是云原生计算基金会CNCF的毕业项目。它的核心概念是拉取模型也就是 Prometheus 服务器主动去各个目标target的 HTTP 端口上抓取指标目标只需要暴露一个符合文本格式的 /metrics 接口即可。相比推模型比如 statsd、Graphite拉模型的优势在于容易发现故障——如果抓取目标挂了Prometheus 自己就能感知到因为抓不到数据了这在告警场景里是很有价值的。1.2 我的监控数据流转路线这次搭建我采用 Docker Compose 方式在单台 Linux 服务器上部署完整链路包含的组件有node-exporter采集宿主机 CPU、内存、磁盘、网络等基础指标暴露在 9100 端口cadvisor采集容器自身的 CPU、内存、网络等指标暴露在 8080 端口Prometheus抓取上述两个 exporter 的指标存储并执行告警规则暴露在 9090 端口Alertmanager接收 Prometheus 推送过来的告警做分组、去重、抑制再转发到通知渠道Grafana从 Prometheus 查询数据并可视化暴露在 3000 端口整体数据流向是这样node-exporter/cadvisor 暴露指标Prometheus 按配置的时间间隔默认 15 秒去抓取抓回来的数据按时间序列存储在本地 TSDB 中。告警规则在 Prometheus 内评估触发后推给 Alertmanager。用户在 Grafana 里配置 Prometheus 数据源后通过 PromQL 查询这些时间序列并绘制成图表。这里我多说一句关于 k8s 环境的问题。很多人搜到的大多数教程都是讲在 K8s 集群里用 Operator 部署如果你现阶段只是想在虚拟机或物理机上做监控用 Docker Compose 是最快的方式。但如果你后续确实要迁移到 k8s这篇文章里写的 prometheus.yml 告警规则文件和 Alertmanager 配置思路是完全通用的只不过在 k8s 里多了 ServiceMonitor 等 CRD 用于自动发现目标核心原理没有变。2. 环境准备与镜像下载2.1 Docker 环境与目录规划搭建之前先把基础环境搞定。我用的是一台 4C8G 的云服务器操作系统为 Ubuntu 22.04Docker 版本为 24.0.xDocker Compose 插件为 v2 版本。检查环境可以用以下命令docker --version docker compose version如果还没有 Docker官方脚本安装最省事但网络原因在国内可能较慢可以用国内镜像源加速这里不再展开。目录规划是很多教程会忽略但实际很重要的环节。我习惯把监控相关的所有配置文件放在同一个项目目录下方便后期维护和备份。我的目录结构如下/mnt/monitor/ ├── docker-compose.yml ├── prometheus/ │ ├── prometheus.yml │ └── rules/ │ └── node_alerts.yml ├── alertmanager/ │ └── alertmanager.yml └── grafana/ └── provisioning/ ├── datasources/ │ └── datasource.yml └── dashboards/ └── dashboard.yml这样设计的好处是Prometheus 的 rules 目录可以放多个告警规则文件按业务拆开Grafana 的 provisioning 目录用于启动时自动加载数据源和面板不用登录 Web 界面手动配这在以后批量部署多套环境时非常有用。2.2 镜像选择与加速下载这次涉及的核心镜像有四个prom/prometheus、grafana/grafana、prom/alertmanager、prom/node-exporter另外容器监控还需要 google/cadvisor 镜像。先说明这里提到的都是官方镜像仓库中公开可获取的镜像在国内拉取时建议配置镜像加速器。我选择一个一个来拉docker pull prom/prometheus:v2.53.0 docker pull grafana/grafana:11.1.0 docker pull prom/alertmanager:v0.27.0 docker pull prom/node-exporter:v1.8.1 docker pull google/cadvisor:v0.49.1关于版本我多说一句。很多教程喜欢写 latest但我个人非常反对在生产环境用 latest因为镜像更新可能导致配置文件格式不兼容而且可复现性差。你应该在测试环境确认好版本之后锁定具体版本号。比如我这次锁定的 Prometheus 2.53、Grafana 11.1都是目前相对稳定且配置兼容性较好的版本。如果拉取速度很慢可以在 /etc/docker/daemon.json 里配置镜像加速地址然后重启 Docker。{ registry-mirrors: [ https://docker.m.daocloud.io ] }重启命令sudo systemctl restart docker实测下来配置加速之后拉取速度有明显提升。不过镜像加速器地址建议根据网络环境自行查找最新可用的网上分享的地址经常变化。3. 编写配置文件与服务编排3.1 通过 docker-compose.yml 一键拉起全部服务配置文件是这套监控系统的核心。我先给出 docker-compose.yml 的完整内容再逐个说明关键参数否则你不知道为什么要这么写。version: 3.8 networks: monitor: driver: bridge volumes: prometheus_data: grafana_data: services: node-exporter: image: prom/node-exporter:v1.8.1 container_name: node-exporter restart: unless-stopped command: - --path.rootfs/host ports: - 9100:9100 volumes: - /:/host:ro,rslave networks: - monitor cadvisor: image: google/cadvisor:v0.49.1 container_name: cadvisor restart: unless-stopped 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 networks: - monitor prometheus: image: prom/prometheus:v2.53.0 container_name: prometheus restart: unless-stopped command: - --config.file/etc/prometheus/prometheus.yml - --storage.tsdb.path/prometheus - --storage.tsdb.retention.time30d - --web.enable-lifecycle ports: - 9090:9090 volumes: - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro - ./prometheus/rules:/etc/prometheus/rules:ro - prometheus_data:/prometheus depends_on: - node-exporter - cadvisor networks: - monitor alertmanager: image: prom/alertmanager:v0.27.0 container_name: alertmanager restart: unless-stopped command: - --config.file/etc/alertmanager/alertmanager.yml ports: - 9093:9093 volumes: - ./alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro depends_on: - prometheus networks: - monitor grafana: image: grafana/grafana:11.1.0 container_name: grafana restart: unless-stopped environment: - GF_SECURITY_ADMIN_USERadmin - GF_SECURITY_ADMIN_PASSWORDadmin123 - GF_USERS_ALLOW_SIGN_UPfalse - GF_SERVER_ROOT_URLhttp://your-server-ip:3000 ports: - 3000:3000 volumes: - grafana_data:/var/lib/grafana - ./grafana/provisioning:/etc/grafana/provisioning:ro depends_on: - prometheus networks: - monitor几个关键参数的解释--storage.tsdb.retention.time30d表示指标数据只保留 30 天。这个必须根据你的磁盘容量来设置Prometheus 本地存储占用大致可以按“每秒抓取指标数 × 标签基数 × 24 小时”估算数据量大的时候是很吃磁盘的。--web.enable-lifecycle允许通过 HTTP 接口热加载配置修改 prometheus.yml 之后执行curl -X POST http://localhost:9090/-/reload就能生效不用重启容器。node-exporter 挂载宿主机根目录的时候用ro,rslave而不是简单的ro这是为了正确处理挂载传播不然采集出来的文件系统指标可能不准。我用的网络是自定义 bridge 网络。所有容器加入同一个 monitor 网络后互相之间可以通过容器名访问例如 Prometheus 里配置 node-exporter 的地址可以写node-exporter:9100这样就不依赖宿主机 IP也避免了端口映射冲突的问题。3.2 prometheus.yml 核心配置详解再来看 Prometheus 的配置文件。这是整个监控系统最核心的文件我一开始学 Prometheus 的时候就是没搞懂这个文件的各个 block 是干嘛的后面才慢慢摸透。下面这个是我本次使用的示例配置global: scrape_interval: 15s evaluation_interval: 15s external_labels: monitor: my-monitor alerting: alertmanagers: - static_configs: - targets: - alertmanager:9093 rule_files: - /etc/prometheus/rules/*.yml 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逐段解释scrape_interval全局抓取间隔。不是所有任务都必须用这个值每个 job 内可以单独覆盖比如某些频繁变化的指标可以设成 5 秒。evaluation_interval告警规则评估间隔。Prometheus 每 15 秒会检查一次告警规则看条件是否满足这个频率决定告警的延迟。external_labels这些标签会附加到所有指标和告警上。多套 Prometheus 环境时用这个区分来源很重要比如测试环境和生产环境监控同一个业务时告警里就能看出是哪套环境报出来的。alerting段告诉 Prometheus 把告警推给哪个 Alertmanager。这里用的alertmanager:9093是容器网络内的服务名所以之前那个自定义网络是必须的。rule_files告警规则文件路径支持通配符。scrape_configs定义了要抓取哪些目标。每个目标可以打上不同的 job 标签用于在查询时区分数据来源比如up{jobnode-exporter}可以判断该目标是否在线。配置好之后可以用promtool check config命令校验文件格式这是官方提供的工具Prometheus 镜像里自带。在容器里执行docker run --rm -v /mnt/monitor/prometheus:/etc/prometheus prom/prometheus:v2.53.0 promtool check config /etc/prometheus/prometheus.yml习惯性地做配置检查是个好习惯我见过太多因为 YAML 缩进问题导致整个服务起不来的情况。3.3 告警规则文件从规则写法到持续集成告警规则是 Prometheus 里最能体现功力的配置文件。先提供一个简单的规则文件后面第 6 节我再展开细讲高级用法。groups: - name: node_alerts rules: - alert: HostHighCpuLoad expr: 100 - (avg(rate(node_cpu_seconds_total{modeidle}[5m])) * 100) 85 for: 10m labels: severity: warning annotations: summary: Host high CPU load description: CPU load is above 85% for more than 10 minutes.这里面的逻辑是先通过rate(node_cpu_seconds_total{modeidle}[5m])计算出 5 分钟内 CPU 空闲时间的平均速率再用 100 减去它得到 CPU 使用率当使用率大于 85% 且持续 10 分钟时触发告警。for参数很重要它避免了瞬时抖动导致的误报比如某台机器编译代码时 CPU 短暂冲到 90%几分钟后就降下来了不应该触发告警。规则文件放进./prometheus/rules/后Prometheus 会通过rule_files配置加载。每次修改规则后执行热加载就会生效。实际使用中建议把规则文件纳入版本管理做好 Code Review因为告警规则写错了会产生两个严重后果要么该报的没报要么一天到晚轰炸你。4. 部署启动与验证4.1 启动服务与检查状态配置文件准备好之后进入项目目录执行docker compose up -d第一次启动会拉取镜像并创建容器如果镜像已经提前拉好了这个过程会很快。启动之后用以下命令查看容器状态docker compose ps正常情况下5 个服务的 STATUS 都是 Up端口映射也正常。如果某个容器一直处于 Restarting 状态大概率是配置文件有问题看日志是最直接的排查手段docker logs prometheus --tail 100 docker logs alertmanager --tail 1004.2 验证 Prometheus 抓取目标是否正常Prometheus 启动之后浏览器访问http://服务器IP:9090打开 Web 界面。点击顶部菜单的 Status - Targets这里会列出所有配置的抓取目标状态为 UP 表示抓取正常DOWN 表示 Prometheus 连不上目标。这里有一个非常常见的排查场景云服务器安全组没放行 9100、8080 端口或者防火墙没关导致 Prometheus 容器访问不到宿主机上的端口。因为 Prometheus 是容器运行的它通过 bridge 网络访问宿主机的映射端口时需要确保这些端口对外至少对 Docker 网段开放。验证 Prometheus 的指标确实有数据可以在 Web 界面的查询框里输入一个最简单的表达式node_memory_MemTotal_bytes如果返回了带时间戳和数值的查询结果说明 node-exporter 已经正常工作。再输入up这个指标是 Prometheus 自动生成的值为 1 表示抓取目标在线值为 0 则表示抓取失败。4.3 热加载配置不用重启就能改配置配置修改是日常操作。每次修改 prometheus.yml 或者告警规则文件后如果手动重启容器会有几秒钟的监控空窗期而且重启期间历史数据查询也会中断。更好的做法是热加载curl -X POST http://localhost:9090/-/reload前提是启动 Prometheus 时加上了--web.enable-lifecycle参数。实测这个功能非常稳定改了配置后 1 秒内就能生效。当然如果修改的是 scrape 配置之外的全局配置比如存储路径这类就需要完整重启。5. Grafana 数据源与可视化配置5.1 首次登录与添加 Prometheus 数据源Grafana 启动后浏览器访问http://服务器IP:3000默认账号密码是 admin/admin第一次登录会要求修改密码我们刚才在环境变量里已经指定了 admin123。登录后第一件事就是添加数据源。侧边栏点 Connections - Data sources - Add data source选中 Prometheus。这里只需要填一个 URL由于 Grafana 和 Prometheus 在同一个 Docker 网络中URL 写http://prometheus:9090即可。其他选项保持默认最后点 Save test如果显示 Successfully queried the Prometheus API就说明连接成功。我建议第一次搭的时候用界面配置但生产环境更推荐用 Provisioning 方式。把数据源配置文件放到./grafana/provisioning/datasources/目录下Grafana 启动时会自动加载不需要人工点鼠标。比如这样apiVersion: 1 datasources: - name: Prometheus type: prometheus access: proxy url: http://prometheus:9090 isDefault: true editable: false这样前端配置被锁定环境重建后数据源自动配好非常省心。5.2 导入现成面板与自定义面板Grafana 的一大优势就是社区里面有海量的现成 Dashboard。进入 Dashboards - New - Import输入面板 ID 就能导入。node-exporter 相关的面板 ID 常用 1860cadvisor 的常用 14282这两个面板我实测过图形布局和指标选择都比较合理导入后基本不用改就能直接看。导入面板时Grafana 会要求选择数据源选择刚才配置的 Prometheus 即可。面板导入后可以先点击右上角的刷新图标确认各图表是否有数据。如果图表显示 No data大概率是数据源选择错误或者面板里的指标名与你实际采集的指标名对不上。此时 Edit 面板查看 Query 里的 PromQL 表达式把指标名改成实际存在的。自定义面板也不难。进入 Dashboards - New - New dashboardAdd visualization然后在 Query 编辑器里输入 PromQL。比如我想看每台主机的 CPU 使用率可以这样写100 - (avg(rate(node_cpu_seconds_total{modeidle}[5m])) by (instance) * 100)这里by (instance)表示按主机维度分组否则所有主机的数据会聚合到一条线上那就看不出单台机器的负载了。选好图表类型Time series右上角设置标题和单位一个面板就建好了。5.3 PromQL 基础不是 SQL 但很好懂后台经常有人问我“Grafana 是不是用 SQL 查询监控数据”这里我统一说清楚Grafana 本身不存数据它只是把查询语句发给数据源执行。如果数据源是 Prometheus那么查询语言是 PromQL而不是 SQL。PromQL 的语法和 SQL 完全不同它操作的是时间序列数据而不是关系表。我最常用的几个 PromQL 套路整理如下需求PromQL 示例目标在线状态upCPU 使用率100 - (avg(rate(node_cpu_seconds_total{modeidle}[5m])) * 100)内存使用率(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100磁盘使用率(node_filesystem_size_bytes{fstype!~tmpfs容器 CPU 使用率sum(rate(container_cpu_usage_seconds_total[5m])) by (name)5 分钟平均负载node_load5rate()函数是最常用的它计算一段时间窗口内计数器的平均每秒增量特别适合 CPU 时间这类只会单调增长的计数器指标。avg、sum、max这些聚合函数配合by、without关键字可以灵活地在不同维度上聚合数据。入门时不需要背所有函数记住这几个核心的配合 Grafana 里写查询时弹出的函数提示完全够用。6. 告警体系规则、分组与通知6.1 告警规则写法进阶合理使用 for 与 labels前面给过一个简单的 CPU 高负载告警规则。这里我再展开说说告警规则里的几个进阶参数。for参数的作用是设置持续时间。Prometheus 会在每个评估周期检查表达式如果连续满足条件达到for值才把告警状态从 PENDING 切换为 FIRING。这个参数的设置很有讲究用默认的 0 会导致告警过于敏感但我见过有人把 CPU 告警的 for 设成 30 分钟这又太迟钝了CPU 都满负荷跑半小时了才报。一般建议CPU、内存这类持续性指标设置 5-10 分钟服务不可达类告警设置 1 分钟即可。labels参数可以为告警附加自定义标签。除了 severity严重级别之外还可以加 team、environment 这类标签后面 Alertmanager 的分组和路由可以根据标签做匹配。Annotations 是给告警补充描述信息通常会写入告警的标题和正文。我习惯在描述里把关键数值放进去比如当前 CPU 使用率、阈值是多少这样收到告警的人不用登录 Grafana 就能判断紧急程度。一个比较完整的规则组如下groups: - name: node_exporter_alerts rules: - alert: HostOutOfMemory expr: (1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 90 for: 5m labels: severity: critical team: ops annotations: summary: 主机内存使用率过高 description: {{ $labels.instance }} 内存使用率超过 90%当前值为 {{ $value | humanizePercentage }} - alert: HostDiskWillFillIn4Hours expr: predict_linear(node_filesystem_free_bytes{mountpoint/}[1h], 4 * 3600) 0 for: 5m labels: severity: warning annotations: summary: 磁盘空间预计 4 小时内耗尽 description: {{ $labels.instance }} 的根分区预计在 4 小时内写满第二个规则是我强烈推荐大家用的。predict_linear函数会根据过去 1 小时的磁盘空间变化趋势预测 4 小时后的剩余空间。如果预测值小于 0就意味着磁盘会在 4 小时内写满。这种基于趋势的告警比单纯阈值检测先进得多它能在磁盘真正满之前给你留出处理时间。6.2 Alertmanager 分组、抑制与静默Alertmanager 是告警链路中的“交通警察”它接收 Prometheus 推来的告警后会做三件事分组、抑制、静默。分组是指把相似告警合并成一条通知避免告警风暴抑制是指当某个高级别告警触发时自动屏蔽相关联的低级别告警静默是指在一段时间内忽略某些匹配的告警。我的 alertmanager.yml 配置如下global: resolve_timeout: 5m route: group_by: [alertname, instance] group_wait: 10s group_interval: 5m repeat_interval: 4h receiver: default routes: - matchers: - severity critical receiver: critical receivers: - name: default telegram_configs: - bot_token: YOUR_BOT_TOKEN api_url: https://api.telegram.org chat_id: 123456789 send_resolved: true message: {{ template telegram.default.message . }} - name: critical email_configs: - to: opsexample.com from: alertexample.com smarthost: smtp.example.com:587 auth_username: alertexample.com auth_password: YOUR_PASSWORD send_resolved: true路由策略是树状结构。默认路由负责所有告警匹配 severity critical 的告警会单独走 critical 接收人。group_by设置了分组维度比如按告警名和实例分组同一种告警发给同一个人时只发一条通知不会每个目标都轰炸一次。group_wait是同一组内的告警等待多久才发送这个值设得短一些能更快收到反馈group_interval是当组内新增告警时间隔多久再次通知repeat_interval是同一个告警在已经通知成功后隔多久再次通知。这四个时间的配合决定了告警的节奏。一个常见的告警轰炸场景是这样的某个服务挂了触发了 20 台机器的 20 条 Down 告警。如果不分组你会收到 20 条消息。分组之后把它们合并成一条消息列出 20 个实例这才是人能看的内容。6.3 使用 Alertmanager Web 界面查看状态Alertmanager 启动后访问http://服务器IP:9093可以看到它的 Web 界面。这里有两个重要页面Alerts 页面展示当前活跃的告警Silences 页面可以临时静默告警。当需要维护某台机器时临时静默比关闭 Prometheus 告警规则更安全。操作方式是在 Silences 页面点击 New silence设置匹配的标签比如 instance192.168.1.10再设置静默时长提交后这个实例相关的告警就会被抑制。这样既不会漏掉其他机器的告警也不会因为维护窗口频繁触发误报。7. 常见问题与排查技巧实录7.1 我踩过的坑和对应解决方案搭建过程中我确实踩了不少坑这些在文档里不容易直接搜到这里整理出来供参考现象可能原因解决方案容器启动后立即退出prometheus.yml 缩进错误或配置项拼写错误用 promtool check config 先校验Targets 显示 DOWN防火墙或安全组未放行目标端口在防火墙放行 9100、8080 等端口或调整安全组规则Grafana 面板全是 No data数据源 URL 写错或面板里的指标名与实际不符确认数据源 URL 是否为 http://prometheus:9090检查指标名告警一直在 PENDING 不触发for持续时间未达到或者表达式结果为 0查看告警规则的查询表达式确认指标值确实超过阈值Grafana 升级后提示 failed to upgrade legacy queries面板或数据源保存的是旧版查询格式进入面板编辑模式重新保存一次查询或删掉旧面板重新导入其中 Grafana 升级后报 failed to upgrade legacy queries 这个问题我最近碰到过几次。尤其从 Grafana 8 升级到 9 或更高版本时旧版面板中的一些查询格式无法自动迁移进入面板时会提示某个数据源im7_otuvz was not found。最有效的处理办法是在 Dashboard 设置的 JSON Model 里找到对应的 datasource 引用确认它指向的 uid 是否还存在如果数据源 uid 已改变把面板 JSON 里旧的 uid 替换成当前数据源的 uid或者直接重新导入面板。7.2 数据采集时间偏差与时钟同步问题监控系统对时间非常敏感。Prometheus 抓取数据时会附带时间戳而时序数据的查询、聚合、告警评估都依赖时间对齐。如果宿主机时钟漂移可能会出现抓取频率异常、告警误触发、图表数据段错位等问题。因此务必保证运行 Docker 的宿主机开启了 NTP 或 systemd-timesyncd 时间同步。Ubuntu 系统默认启用了 timesyncd但云服务器有时因为安全组没有放行 UDP 123 端口时间同步会失败。用以下命令检查timedatectl status如果显示 NTP synchronized: no需要手动设置比如安装 chrony 或直接配置 ntp 服务器。这个基础检查动作很多人会忽略但它对监控系统的影响非常大。7.3 数据量大时如何控制存储成本Prometheus 的本地存储会随时间持续增长默认情况下不限制空间上限只会按时间窗口清理旧数据。如果你设置了 30 天保留期但磁盘满了Prometheus 在启动时可能会因为写入失败而异常退出。除了合理设置保留期之外更有效的办法是减少采集数据的基数和数量。比如通过metric_relabel_configs丢弃不需要的标签或者使用honor_labels避免冲突。node-exporter 默认暴露的指标非常多但很多指标在实际监控中根本用不上。我自己的做法是保留常用指标把磁盘和网络相关的少数高基数标签做裁剪实测数据量能下降 30%-50%。如果业务扩容后指标量级到了上亿条时间序列就建议调研 Thanos 或 VictoriaMetrics 这类方案把数据存储和查询拆到对象存储或独立存储集群里去。这个属于后续扩展现阶段用单机 Prometheus 把监控跑起来是第一优先级。8. 这套方案后续还可以怎么扩展最后再分享几个我实际用下来觉得很有价值的扩展方向。第一个是接入 Java/Go 应用的自定义指标。如果你的业务是 Java 服务可以引入 micrometer-registry-prometheus 依赖暴露 /actuator/prometheus 端点然后在 prometheus.yml 里加一个 job 指向它。这样 Prometheus 就能采集 JVM 内存、线程池、HTTP 请求延迟等应用层指标配合 Grafana 里的 JVM 面板排查接口变慢的问题会变得非常直观。第二个是引入日志监控。Prometheus 管指标Loki 管日志两者配合能形成比较完整的可观测性体系。Loki 的部署和 Grafana 集成非常自然以后查问题再也不用登录每台机器去翻日志文件了。我当时的做法是先在 Prometheus 上把基础监控跑通再逐步接入 Loki两个系统不冲突。第三个是自动化告警分发。Alertmanager 支持 webhook 配置可以把告警转发到钉钉、企微、飞书等内部 IM 工具。实际上生产环境里很少有人真用邮件值班IM 机器人 责任人 这种模式反馈速度要快得多。配置方式就是在 receiver 里加一个 webhook_configs指向你自己的机器人地址消息内容用模板自定义即可。如果你是从零开始搭监控跟着这篇文章把 Prometheus node-exporter Grafana Alertmanager 这条链路跑通你已经具备了一套可以告警、可以看图、可以扩展的监控底座。后续无论是加应用指标、接日志还是迁移到 k8s核心架构都不会变变的只是采集目标和运维方式。我在实际使用中最大的体会是监控系统不是搭完就结束了它需要持续调优告警阈值要根据业务情况调整面板要根据关注的指标迭代存储容量要根据增长速度规划。不要想着一步到位先把最核心的跑起来再逐步完善这个节奏是最舒服的。