做运维这几年一个很深的体会:监控不是“装个工具”就结束了,而是要把数据采集、集中存储、可视化展示、告警通知这一整条链路真正跑通。很多公司一开始只是给服务器加了个 CPU、内存监控,等线上真的出故障时才发现:数据粒度太粗、告警全发到没人看的渠道、想回溯历史却保存周期太短。这篇文章把 Zabbix 和 Prometheus 两套主流监控体系完整拆解一遍,从核心概念、环境部署、基础监控、告警配置到常见坑点一次讲清楚。
内容覆盖两个方向的完整落地流程:Zabbix 负责传统服务器、网络设备、UPS 等基础设施监控;Prometheus 负责云原生、容器化、应用指标监控。无论是刚入行的运维新人,还是需要从零搭建监控体系的工程师,都能照着本文一步步操作。读者最好对 Linux 基础命令、Docker 基本使用有一定了解,但即便没接触过监控系统,也能跟着配置完成。
1. 监控体系核心概念与选型
1.1 监控到底在监控什么
监控的范畴不只是一台服务器的 CPU 是否跑满。从生产实践经验来看,监控体系通常覆盖三个层次:
- 基础设施层:服务器的 CPU、内存、磁盘、网络流量,以及交换机、路由器、防火墙等网络设备的端口状态和流量。
- 应用服务层:进程是否存在、端口是否监听、接口响应耗时、JVM 内存、数据库连接数、Redis 命中率、消息队列堆积量等。
- 业务指标层:订单量、交易成功率、支付失败数、转化率等直接反映业务健康度的指标。
监控系统的核心流程也可以概括为四步:采集数据、集中存储、可视化展示、异常告警。把这四步做好,才算是完整的监控平台。
1.2 Zabbix 是什么
Zabbix 是一个企业级开源监控系统,发展历史比 Prometheus 长很多。它的设计思路非常贴近传统运维:一台 Zabbix Server 作为中心节点,通过安装在目标机器上的 Agent 采集数据,也支持通过 SNMP 协议监控网络设备,通过 IPMI 监控服务器硬件状态,通过 JMX 监控 Java 应用。
Zabbix 的架构中通常包含 Server、数据库、Web 前端、Agent 和可选的 Proxy。Server 负责集中调度、触发器和告警判断,数据存放在 MySQL 或 PostgreSQL 中,Web 前端用于配置和查看。整体上,Zabbix 适合监控规模大、设备类型杂、网络环境复杂的传统 IT 基础设施。
1.3 Prometheus 是什么
Prometheus 是云原生计算基金会(CNCF)下的开源监控系统,在 Kubernetes 和微服务架构盛行的时代被广泛使用。它的核心设计思路是“拉模型”:被监控的应用或节点通过 HTTP 暴露一个 metrics 接口,Prometheus 定期访问这个接口拉取指标数据,并把带有时间戳的采样数据写入本地时序数据库。
Prometheus 的数据模型非常灵活,每条时间序列由指标名和一组标签(label)唯一标识。比如node_cpu_seconds_total{cpu="0", mode="idle"}就表示 0 号 CPU 的空闲时间累计值。这种维度化数据模型让透出查询变得非常方便。
1.4 Zabbix 与 Prometheus 的区别
| 对比维度 | Zabbix | Prometheus |
|---|---|---|
| 定位 | 传统 IT 基础设施监控 | 云原生、容器、应用指标监控 |
| 采集方式 | 以轮询为主,Agent 也可主动上报 | 以 Pull 为主,也支持 Pushgateway |
| 数据模型 | 监控项(Item)+ 历史数据、趋势数据 | 时间序列 + 多维标签 |
| 数据存储 | MySQL / PostgreSQL,适合历史数据归档 | 本地 TSDB,支持长期数据但通常保留有限周期 |
| 告警体系 | 触发器 + 动作,内置通知渠道丰富 | 规则文件 + Alertmanager,分组抑制能力强 |
| 可视化 | 自带 Web 界面,模板丰富 | 自带基础 UI,通常配合 Grafana 展示 |
| 自动发现 | 支持网络设备发现、低级别发现(LLD) | 支持各类服务发现,尤其适合 K8s |
| 上手成本 | 功能全面但概念较多 | 配置相对简洁,但 PromQL 需要学习 |
1.5 生产环境怎么选型
选型不是“哪个好”的问题,而是“哪个更适合你的环境”。如果公司业务主要以物理机、虚拟机、核心交换机、路由器、UPS 电源为主,Zabbix 的成熟度和内置模板会省去大量工作量。如果公司业务已经容器化、微服务化,应用部署在 Kubernetes 上,Prometheus 几乎是最自然的选择,因为 Kubernetes 生态的指标接口、服务发现机制和 Prometheus 天然契合。
现实项目中也经常出现两套并存的局面:Zabbix 管传统设备,Prometheus 管容器和应用。本文后面的实战部分会分别把两套体系跑起来,方便读者根据自己的实际场景做组合。
2. 环境准备与版本说明
2.1 操作系统与部署方式
本文实验环境以 Rocky Linux 9 为例,该系与 RHEL 9 / AlmaLinux 9 兼容,命令基本通用。Zabbix 使用 Docker Compose 方式部署,Prometheus、Grafana、Alertmanager 使用 Docker 方式部署,node_exporter 以二进制方式安装到宿主机。
采用容器化部署的原因是:服务启动快、环境隔离好、卸载干净,适合学习和测试。生产环境如果对性能要求高,也可以把 Zabbix Server 和 Prometheus 改为二进制方式部署,但核心配置思路是一致的。
2.2 端口规划与防火墙
部署前先明确各组件使用的端口,避免冲突,也方便后续排查网络问题。
| 组件 | 端口 | 说明 |
|---|---|---|
| Zabbix Web | 8080 | Web 管理界面 |
| Zabbix Server | 10051 | 接收 Agent 主动上报数据 |
| Zabbix Agent | 10050 | 被动模式下允许 Server 采集 |
| Prometheus | 9090 | Web UI 和 API |
| node_exporter | 9100 | 节点指标采集接口 |
| Alertmanager | 9093 | 告警管理 |
| Grafana | 3000 | 可视化面板 |
如果你的服务器开启了 firewalld,可以执行类似下面的命令放行端口。生产环境建议不要对公网开放这些端口,而应限制来源 IP。
firewall-cmd --permanent --add-port={8080,10051,9090,9093,3000,9100}/tcp firewall-cmd --reload更安全的做法是只允许办公网或运维跳板机 IP 访问:
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.10.0.0/24" port protocol="tcp" port="3000" accept' firewall-cmd --reload2.3 版本说明
本文示例中 Zabbix 使用当前主流的 7.0 LTS 系列镜像,Prometheus 使用 2.x 系列镜像,Grafana 使用最新稳定版镜像。具体版本以官方仓库当前提供为准。容器镜像的 tag 可以锁定版本,也可以在测试环境中先使用 latest 验证功能,生产环境建议固定 tag。
3. Zabbix 核心组件与监控模型
3.1 Zabbix 架构组成
Zabbix 的核心组件包括以下几部分:
- Zabbix Server:核心调度服务,负责数据采集调度、触发器计算、执行告警动作。
- 数据库:保存配置、历史数据、趋势数据,Zabbix 7.0 支持 MySQL 和 PostgreSQL。
- Zabbix Web:PHP 编写的管理界面,负责配置和展示。
- Zabbix Agent:部署在被监控主机上,采集本地指标后返回给 Server。
- Zabbix Proxy:可选组件,在分布式场景下代替 Server 采集数据,再批量同步给 Server。
数据流向可以简单理解为:
Agent 采集本地指标 ↓ 主动上报或被动拉取 Zabbix Server 接收数据 ↓ 写入 数据库(MySQL / PostgreSQL) ↓ 计算 触发器判断是否异常 ↓ 触发 动作发送告警通知3.2 核心对象概念
使用 Zabbix 之前,需要先理解几个核心对象。
- 主机(Host):一台被监控的服务器、交换机或其他设备。
- 监控项(Item):采集某个具体指标的定义,例如 CPU 使用率、磁盘空间剩余量。
- 触发器(Trigger):对监控项数据设置阈值表达式,返回 OK 或 PROBLEM 状态。
- 动作(Action):当触发器状态变化时执行的操作,例如发送告警邮件、调用 Webhook。
- 模板(Template):一组监控项、触发器的集合,可以批量套用到多台主机。
- 自动发现(Discovery):自动发现网络设备或主机上的新资源。
理解这几个概念后,Zabbix 的使用逻辑就清晰了:给主机套模板 -> 模板里的监控项开始采集数据 -> 触发器判断异常 -> 动作发通知。
3.3 Agent 主动模式与被动模式
Zabbix Agent 有两种工作模式。
被动模式下,Zabbix Server 主动连接 Agent 的 10050 端口,请求某个监控项的数据。这个模式适合 Server 与 Agent 网络互通、访问策略简单的场景。
主动模式下,Agent 主动连接 Zabbix Server 的 10051 端口,周期性获取需要采集的监控项列表,然后把数据批量传给 Server。这个模式适合 Agent 位于内网、Server 在外部网络,或者 Agent 数量较多、需要减轻 Server 压力的场景。
实际配置时,Agent 配置文件里的Server参数表示允许哪些 IP 被动采集,ServerActive参数表示主动上报到哪个 Server 地址。两个参数通常需要同时配置。
4. Zabbix 7.0 部署与基础监控实战
4.1 使用 Docker Compose 部署 Zabbix
在开始前,先创建项目目录并准备 docker-compose 文件。
mkdir -p /opt/zabbix cd /opt/zabbix创建docker-compose.yml:
services: zabbix-db: image: mysql:8.0 container_name: zabbix-db restart: always command: - --character-set-server=utf8mb4 - --collation-server=utf8mb4_bin environment: MYSQL_DATABASE: zabbix MYSQL_USER: zabbix MYSQL_PASSWORD: zabbix_pwd MYSQL_ROOT_PASSWORD: root_pwd volumes: - zabbix-db-data:/var/lib/mysql zabbix-server: image: zabbix/zabbix-server-mysql:7.0-ubuntu-latest container_name: zabbix-server restart: always environment: DB_SERVER_HOST: zabbix-db MYSQL_DATABASE: zabbix MYSQL_USER: zabbix MYSQL_PASSWORD: zabbix_pwd ports: - "10051:10051" depends_on: - zabbix-db zabbix-web: image: zabbix/zabbix-web-nginx-mysql:7.0-ubuntu-latest container_name: zabbix-web restart: always environment: ZBX_SERVER_HOST: zabbix-server DB_SERVER_HOST: zabbix-db MYSQL_DATABASE: zabbix MYSQL_USER: zabbix MYSQL_PASSWORD: zabbix_pwd PHP_TZ: Asia/Shanghai ports: - "8080:8080" depends_on: - zabbix-server volumes: zabbix-db-data:字段说明:
- MYSQL_DATABASE、MYSQL_USER、MYSQL_PASSWORD 是 Zabbix 数据库名和账号,生产环境务必改为强密码。
- zabbix-server 镜像里的 DB_SERVER_HOST 指向数据库容器名 zabbix-db,容器之间通过 Compose 网络互相访问。
- zabbix-web 配置 PHP_TZ 为 Asia/Shanghai,避免前端时间显示不对。
启动服务:
docker compose up -d docker compose ps等待 1 到 2 分钟,数据库初始化完成后,访问http://服务器IP:8080。默认账号为 Admin,密码为 zabbix。
首次登录后建议立即修改默认密码。
4.2 在宿主机安装 Zabbix Agent2
Zabbix 7.0 推荐使用 Agent2。在需要被监控的服务器上安装 Agent2,以 Rocky Linux 9 为例,先添加官方仓库,再安装。
rpm -ivh https://repo.zabbix.com/zabbix/7.0/rhel/9/x86_64/zabbix-release-7.0-1.el9.noarch.rpm dnf install -y zabbix-agent2如果包名或仓库路径随着版本调整,以 Zabbix 官方仓库提供的信息为准。
修改 Agent2 配置:
vi /etc/zabbix/zabbix_agent2.conf修改或确认以下内容:
Server=192.168.10.10 ServerActive=192.168.10.10 Hostname=node1.example.com其中192.168.10.10是 Zabbix Server 的 IP,替换为你自己的环境地址。Hostname建议填写全限定主机名,后续在 Web 界面添加主机时保持一致。
启动并设置开机自启:
systemctl start zabbix-agent2 systemctl enable zabbix-agent2 ss -lntp | grep 10050如果看到 10050 端口监听,说明 Agent2 已经正常运行。
4.3 在 Web 界面添加主机
登录 Zabbix Web 界面,进入菜单“数据采集 -> 主机”,点击“创建主机”。
填写主机名称,例如 node1.example.com,选择主机组,然后设置 Agent 接口,填写被监控服务器的 IP,端口保持 10050。
在模板栏输入Linux by Zabbix agent active,选择该模板。这个模板里已经预置了大量 CPU、内存、磁盘、网络、系统服务的监控项和触发器,适合直接使用。
保存后等待一两分钟,回到“监测 -> 最新数据”,筛选主机 node1.example.com,就能看到采集到的指标数据。
4.4 自定义一个触发器示例
Zabbix 模板自带的触发器已经覆盖常见场景,但有时需要自定义一个业务相关的告警。下面演示创建一个 CPU 使用率超过 90% 持续 5 分钟的触发器。
进入菜单“数据采集 -> 触发器”,点击“创建触发器”。
- 名称:CPU 使用率超过 90%
- 严重性:警告
- 表达式:
avg(/Linux by Zabbix agent active/system.cpu.util[,total],5m) > 90这个表达式的含义是:在模板Linux by Zabbix agent active下,取监控项system.cpu.util[,total]最近 5 分钟的平均值,如果大于 90,就触发 PROBLEM 状态。
保存后,可以稍后在“监测 -> 问题”中查看触发情况。
4.5 配置钉钉告警动作
Zabbix 的告警逻辑是:触发器状态发生变化后,由动作(Action)执行操作。要接入钉钉,需要先配置报警媒介类型,再分配给用户,最后创建动作。
Zabbix 7.0 的 Webhook 媒介基于 JavaScript,社区有很多钉钉适配方案。核心思路是:在“管理 -> 报警媒介类型 -> 创建媒介类型”中,选择类型为 Webhook,配置钉钉机器人的 Webhook 地址和自定义脚本。然后在“用户 -> 报警媒介”中把该媒介分配给接收告警的用户,最后在“告警 -> 动作”中创建动作,操作里选择发送消息给该用户。
钉钉机器人本身要求签名校验,因此生产环境通常由一个小服务转发 Alertmanager 或 Zabbix 的告警到钉钉。具体转发服务的实现,在后文 Prometheus 告警部分会给出一个可运行的参考脚本。
5. Prometheus + Grafana 监控部署实战
5.1 Prometheus 架构与采集模型
Prometheus 的架构可以拆成几部分:
- Prometheus Server:负责拉取指标、存储时间序列数据、执行预警规则。
- Exporter:以 HTTP 方式暴露指标,常见的 node_exporter、mysqld_exporter、redis_exporter 都是这种形态。
- Pushgateway:用于支持不适合 Pull 模式的短生命周期任务。
- Alertmanager:接收 Prometheus 推送的告警,负责分组、抑制、去重并发送通知。
- Grafana:负责可视化展示,虽然不是 Prometheus 官方组件,但已经成为事实上的标准搭配。
Prometheus 采用 Pull 模式,即 Prometheus 主动访问 exporter 的 metrics 接口。这种模式的好处是采集目标清晰,不容易对目标节点产生额外连接压力,也方便在 Kubernetes 中通过服务发现自动发现新的监控目标。
5.2 使用 Node Exporter 采集宿主机指标
先从 GitHub Releases 页面获取 node_exporter 最新稳定版,示例中使用 v1.8.2。
cd /opt wget https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-amd64.tar.gz tar xzf node_exporter-1.8.2.linux-amd64.tar.gz cp node_exporter-1.8.2.linux-amd64/node_exporter /usr/local/bin/启动 node_exporter。可以使用 systemd 管理,也可以先直接运行验证:
nohup node_exporter --web.listen-address=":9100" &然后验证指标接口:
curl http://127.0.0.1:9100/metrics | head -20如果能看到以node_开头的大量指标,说明 exporter 工作正常。
生产环境建议写成 systemd 服务,这里给一个最小配置思路:
[Unit] Description=Node Exporter After=network.target [Service] ExecStart=/usr/local/bin/node_exporter Restart=always [Install] WantedBy=multi-user.target5.3 编写 Prometheus 配置并启动
Prometheus 的配置文件采用 YAML 格式。创建/opt/prometheus/prometheus.yml:
global: scrape_interval: 15s evaluation_interval: 15s alerting: alertmanagers: - static_configs: - targets: - "127.0.0.1:9093" rule_files: - "/etc/prometheus/rules.yml" scrape_configs: - job_name: "node" static_configs: - targets: - "127.0.0.1:9100"配置说明:
- scrape_interval:采集间隔,15 秒适合大多数场景,业务指标要求高时可以调低到 10 秒。
- evaluation_interval:告警规则评估间隔,Prometheus 会定期检查规则文件中的表达式。
- rule_files:告警规则文件路径。
- alerting.alertmanagers:Alertmanager 实例地址。
- scrape_configs:抓取任务列表,这里的 job_name 是 node,targets 指向 node_exporter。
启动 Prometheus。为了让 Prometheus 容器能直接访问宿主机的 node_exporter,这里使用--network host:
docker run -d \ --name prometheus \ --restart=always \ --network host \ -v /opt/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml \ -v /opt/prometheus/rules.yml:/etc/prometheus/rules.yml \ -v prometheus-data:/prometheus \ prom/prometheus \ --config.file=/etc/prometheus/prometheus.yml \ --storage.tsdb.path=/prometheus \ --storage.tsdb.retention.time=15d--storage.tsdb.retention.time=15d表示本地数据保留 15 天。生产环境根据业务需求调整,数据量大的可以考虑接入远端存储。
浏览器访问http://服务器IP:9090,在“Status -> Targets”页面应该能看到 node 这个 job 的状态为 UP。
5.4 初识 PromQL 常用查询
PromQL 是 Prometheus 的查询语言,掌握几个常用函数后基本就能完成日常诊断。
查询当前所有采集目标的状态:
up返回值为 1 表示正常在线,0 表示目标不可达。
查询 5 分钟内的 CPU 使用率:
100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)查询可用内存:
node_memory_MemAvailable_bytes查询根分区使用率:
100 - (node_filesystem_free_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"} * 100)这里的关键是理解 rate 函数的含义。node_cpu_seconds_total是累计值,直接除以时间间隔