其实,咱们搞监控,Prometheus 和 Grafana 这对 CP 现在基本上就是业界的标配了。很多刚入门的小伙伴容易搞混,这俩到底谁是干啥的?一句话给你讲清楚:Prometheus 负责“抓数据”和“存数据”,Grafana 负责“看数据”和“报警展示”。它俩分工明确,一个像勤劳的采集工,一个像大屏设计师。
咱们先聊聊 Prometheus。它最核心的设计哲学就是 Pull 模式(拉取)。可以这么理解,就是 Prometheus 服务器会主动找你配置的那些目标(Target),比如你的 Java 应用或者 Linux 机器,每隔一段时间去问它们:“嘿,你现在的 CPU 用了多少啊?给我报个数呗。” 这种方式在云原生环境里特别舒服,因为服务实例可能会频繁重启或扩容,Prometheus 配合服务发现(Service Discovery)就能自动找到这些新实例,不用你手动去改配置。
而 Grafana 呢,它不做采集,它只做展示。它支持连接几十种数据源,当然也包括 Prometheus。你在 Grafana 里写 PromQL(Prometheus 的查询语言),它帮你去 Prometheus 里取数,然后画成漂亮的曲线图。
咱们做技术的最忌讳用老掉牙的版本。截止到 2024 年 3 月,Prometheus 的最新稳定版已经到了 v2.49.1。如果你现在去官网下,会发现它的主要分支正在向 v3.0 演进,重点都在优化存储引擎的性能。
Grafana 这边更猛,最新版已经到了 v10.4.x(2024年初发布的)。这个版本有几个很骚的新特性,咱们必须要提一下:
Prometheus 的数据模型很有意思,它不像传统数据库那样是表格,而是 多维数据模型。
http_requests_total。{method="POST", handler="/api/login"}。Labels 千万别乱用!很多新手喜欢把 user_id 这种基数特别大的东西当标签,这会导致 Prometheus 产生海量的时间序列,直接把内存撑爆。这叫 High Cardinality(高基数) 陷阱,面试的时候也经常问。
咱们看远一点,现在的监控圈有几个很火的趋势:
🔧 实战技巧:如果你是新项目,直接上 Prometheus v2.49+ 和 Grafana v10.4+。千万别为了所谓的“稳定”去用 v1.x 或者 v8.x 的 Grafana,你会错过很多 AI 辅助诊断的功能,而且新版的存储引擎对 SSD 的优化非常好,能省不少机器成本。
---
很多教程一上来就让你 wget 一堆二进制文件,手动敲启动命令,那叫一个麻烦。作为过来人,我强烈建议你直接用 Docker Compose 来起环境。打个比方,咱们是为了学监控,不是为了学怎么配置 Linux 系统服务,能一键启动就别折腾。
首先你得有个 Docker 环境。如果你本地没装,赶紧去装一个 Docker Desktop(Windows/Mac)或者直接在 Linux 上装 Docker Engine。
咱们直接上代码。我会把版本号写死,确保你跑起来和我写的一样。咱们不仅要起 Prometheus 和 Grafana,顺便把 Node Exporter(监控主机用的)也一起带上,这样一会儿直接就能看到数据。
创建一个文件夹,比如叫 monitoring-stack,在里面新建一个 docker-compose.yml 文件。
注意上面 Compose 文件里挂载了 ./prometheus.yml。咱们得在同一目录下创建这个配置文件,告诉 Prometheus 去哪儿抓数据。
代码写好了,直接启动。在 monitoring-stack 目录下打开终端,运行:
等几秒钟,容器就跑起来了。
http://localhost:9090,这是 Prometheus 的界面。点击顶部的 Status -> Targets,你应该能看到 node_exporter 的状态是 UP。http://localhost:3000,这是 Grafana。账号是 admin,密码是咱们在 Compose 里设的 admin123。避雷经验提醒:很多新手在配置 Prometheus 的 targets 时,喜欢写 localhost:9100。在 Docker Compose 环境里,这是大忌!因为 Prometheus 容器里的 localhost 指的是它自己那个容器,而不是你宿主机。所以一定要写成服务名,比如 node_exporter:9100,利用 Docker 的内网 DNS 去解析。
🔧 实战技巧:记得加上 --web.enable-lifecycle 这个启动参数。加了它之后,你修改了 prometheus.yml 配置,不用重启容器,直接发一个 HTTP POST 请求 curl -X POST http://localhost:9090/-/reload 就能热加载配置,这在生产环境里非常有用,避免监控中断。
---
环境搭好了,现在咱们来干点实事。监控 Linux 主机是最基础的需求,但很多教程只教你怎么装 Node Exporter,不教你怎么在 Grafana 里看。咱们这一章直接打通任督二脉,从采集到可视化,一条龙搞定。
Node Exporter 是 Prometheus 官方提供的,专门用来暴露 *NIX 内核(Linux/Unix)硬件和操作系统指标的。它跑起来后会监听 9100 端口。
咱们上一章已经用 Docker 把 Node Exporter 跑起来了。如果你没用 Docker,直接下载二进制包运行也行,但记得要暴露 /proc 和 /sys 目录,因为 CPU、内存、磁盘这些数据全在这两个内核伪文件系统里读出来的。
有了 Node Exporter 采集数据,Prometheus 也抓到了,现在咱们得让 Grafana 去读这些数据。
http://localhost:3000)。http://prometheus:9090。- *注意:还是那个 Docker 网络的问题,Grafana 容器访问 Prometheus 容器,必须用服务名 prometheus,不能用 localhost。*
配置好数据源后,咱们得画图。简单来说,没人会自己从零开始画 CPU、内存的图,太累了。社区有现成的 JSON 模板。
瞬间,一个包含 CPU、内存、磁盘 IO、网络流量的高大上监控面板就出来了。
光看机器不够,咱们的数据库也得盯着。监控 MySQL,咱们得用 mysqld_exporter。
#### 1. 配置 MySQL 权限
首先得在 MySQL 里给 Exporter 一个只读账号,别给它 root 权限,这是安全规范。
#### 2. 修改 Docker Compose
咱们继续修改之前的 docker-compose.yml,把 MySQL 和 mysqld_exporter 加进去。
#### 3. 修改 Prometheus 配置
再去 prometheus.yml 里加一个 job,让 Prometheus 去抓 MySQL 的指标。
重启一下 Prometheus 或者热加载配置,去 Targets 页面确认 mysql 这个 job 是 UP 状态。
#### 4. 导入 MySQL Dashboard
同样在 Grafana 里 Import,这次用 ID:7362(这是 Percona 出品的一个很详细的 MySQL 监控模板)。
咱们看面板不能只看热闹,得看门道。
node_memory_MemAvailable_bytes(可用内存)和 node_filesystem_avail_bytes(磁盘剩余)。如果磁盘满了,服务必挂。mysql_global_status_threads_connected(当前连接数)和 mysql_slave_status_seconds_behind_master(主从延迟,如果有主从的话)。mysqld_exporter 默认不会抓取所有指标,有些需要通过启动参数开启,比如 collect.info_schema.processlist。如果你发现有些面板没数据,先去 Exporter 的启动参数里看看是不是没开启对应的采集项。
📌 要点提醒:不要盲目导入所有的 Dashboard。Node Exporter 的 1860 模板非常重,包含了几百个指标。对于生产环境,建议你根据“黄金四指标”(延迟、流量、错误、饱和度)精简一下面板,只保留你真正关心的。不然 Grafana 渲染起来也很吃资源,而且看着眼晕。
搞监控如果不懂 PromQL,那你基本上就是用 Prometheus 做了个高级版的“看图说话”。可以这么理解,PromQL 就是 Prometheus 的 SQL,它是让你从海量时序数据里捞出你想要的东西的核心武器。咱们现在用的 Prometheus 最新稳定版是 v2.49.1(2024年3月发布),这版本在查询引擎上做了不少性能优化,跑复杂查询时比老版本快不少。
PromQL 的强大之处在于它的多维数据模型。你不要把它当成简单的 Key-Value,它其实是 Metric Name + Labels 的组合。
比如你有一个指标叫 http_requests_total,它后面可能跟了 job="web", status="200" 这样的标签。
核心要点:PromQL 分为即时查询(Instant Query)和范围查询(Range Query)。
up,看看现在是 0 还是 1。rate(http_requests_total[5m]),看过去 5 分钟的增长率。这里有个新手必踩的坑:直接对着 Counter 类型的指标(比如请求总数)做算术运算是没意义的,因为它只增不减。你必须要对它做 rate 或者 increase 处理,后面章节会细讲。
光会查还不够,咱们得把数据“秀”出来。现在 Grafana 最新版都 v10.4.x 了,这版本在 AI 可视化和交互上做得挺丝滑的。咱们在构建面板时,千万别把 IP 写死,要用 Variables(变量)。
举个实战例子,我们想做一个通用的主机监控面板,能切换不同的主机。
🔧 实战技巧:在 Grafana 里配置变量时,一定要用 label_values() 函数去自动抓取 Prometheus 里的标签,这样以后加了新机器,面板自动更新,不用手动改。
Grafana Dashboard 变量配置示例(以监控 Node Exporter 为例):
在 Dashboard 设置 -> Variables 里新建一个变量:
instanceQuerylabel_values(node_uname_info, instance)这样,你就能在 Panel 里引用 $instance 了。
Panel 配置代码示例(PromQL):
假设你要在 Grafana 里展示某台机器的 CPU 使用率,PromQL 得这么写(注意这里的 $instance 引用了上面的变量):
这段代码的原理是:抓取所有 CPU 模式的时间片,减去空闲(idle)的,剩下的就是干活的时间。用 rate 计算 5 分钟内的速率,最后算个占比。
现在的 Grafana v10.4 已经开始集成 AI 能力了(虽然还在发展中)。比如它内置的 Sift 异常检测功能,能帮你自动识别指标里的毛刺,不用你死盯着阈值调来调去。如果你在云原生环境下折腾,这种智能分析能省不少事儿。
---
监控做完了,不能光看不叫啊。半夜服务器挂了,你还在梦乡里,这就不行了。所以告警集成是重头戏。同时,Prometheus 默认是单机存储,数据存本地磁盘,撑死也就存个把月,想看去年的数据?没门。这就引出了高可用和长期存储的话题。
Prometheus 抓到数据后,如果触发了告警规则,会把告警发给 Alertmanager。这玩意儿负责“去重、分组、抑制和发送”。
实战经验预警:很多新手直接把邮件配置写在 Prometheus 里,这是不对的。Prometheus 只负责产生告警,Alertmanager 负责发通知。
咱们来看个最经典的配置:通过企业微信或者钉钉发告警,并且做一下分组,别一股脑全发过来把群聊炸了。
Alertmanager 配置文件 (alertmanager.yml) 示例:
📌 要点提醒:一定要配置 inhibit_rules(抑制规则)。比如你的机器宕机了,上面跑的 10 个服务肯定也挂了,如果不抑制,你会收到 11 条告警(1条机器+10条服务)。配了抑制,你只会收到 1 条机器挂了的告警,清爽多了。
Prometheus 的本地 TSDB 虽然快,但没法做集群。现在社区里吵得最凶的就是 Thanos 和 VictoriaMetrics 的选型。
我的个人建议:
如果你是小团队或者追求极简运维,直接上 VictoriaMetrics。它的 vmstorage + vminsert + vmselect 架构比 Thanos 的组件堆砌好维护多了,而且它兼容 Prometheus 的 Remote Write 协议,接入成本几乎为零。
如果你已经在用 Kubernetes,且对对象存储有强依赖,Thanos 可能更合适。但换个角度看,对于绝大多数中小规模集群,VictoriaMetrics 是性价比之王。
---
这一章咱们聊聊那些让你面试卡壳、排错头大的细节。特别是 PromQL 里那几个函数,长得像但意思完全不同。
这是常见面试问题,也是实际工作中最容易算错数据的点。
场景:你有一个 Counter 类型的指标 http_requests_total,记录了从开机到现在的总请求数。
你想知道过去 5 分钟,平均每秒有多少个请求(QPS)。
误区:很多人直接写 increase(http_requests_total[5m]),以为这就是 QPS。
真相:
rate(http_requests_total[5m]):计算的是每秒的增长率。它是 increase 除以时间(秒)。increase(http_requests_total[5m]):计算的是过去 5 分钟内总共增加了多少请求(是个总量)。代码示例与对比:
假设你 5 分钟前请求数是 1000,现在是 1600。
rate(...[5m]) 的结果大概是 (1600-1000) / 300秒 = 2。意思是每秒 2 个请求。increase(...[5m]) 的结果大概是 600。意思是 5 分钟内一共增加了 600 个请求。注意:
rate。increase。rate 会自动处理 Counter 的重置(比如服务重启计数器归零),所以放心用,别自己瞎写脚本去算差值。面试官问这个,其实是想看你懂不懂云原生。
env=prod,Prometheus 瞬间就能筛选出来,Zabbix 可能得重新建一套模板。面试时如果聊到数据持久化和高可用,别只说“加磁盘”。
现在主流方案是 Thanos 或者 Grafana Mimir(前身是 Cortex)。
🔧 实战技巧:如果你在面试中被问到“Prometheus 怎么保证数据不丢且高可用”,标准的回答套路是:
这样一来,既解决了单机故障问题,又解决了数据长期存储问题。
最后,别忘了 Prometheus v2.49.1 已经开始向 v3.0 演进了,未来的趋势是 OpenTelemetry 融合 和 eBPF 深度集成。这意味着以后你写代码抓指标,可能不用埋点,直接用 eBPF 在内核层就把数据抓出来了,这才是真正的“黑科技”。