一、先讲结论:没有银弹,只有场景匹配
我的经验总结成一句话:动态云原生环境优先 Prometheus,传统 IDC 混合环境选 Zabbix,纯网络设备轮询才考虑 Nagios。 但真实情况往往更复杂,下面逐一说。
二、Nagios:我的起点,也是我最早告别的工具
2015 年我第一次接触监控,用的是 Nagios Core 4.x。它的插件机制非常经典——退出码决定状态:
#!/bin/bash# check_disk.shUSED=$(df -h / | awk 'NR==2 {print $5}' | tr -d '%')if [ $USED -gt 90 ]; thenecho"CRITICAL: disk usage ${USED}%"exit 2elif [ $USED -gt 80 ]; thenecho"WARNING: disk usage ${USED}%"exit 1elseecho"OK: disk usage ${USED}%"exit 0fi
设置写在 objects.cfg 里:
define host { use linux-server host_name web-01 address 192.168.1.10}define service { use generic-service host_name web-01 service_description Disk Usage check_command check_nrpe!check_disk notification_interval 30}
痛点很直接:主机和服务的设置文件是手工维护的,机器一多就崩。我们当时 200 台机器,设置文件 4000 多行,加一台机器要改 3 个文件。阈值变更没有版本控制,改错了只能靠备份回滚。更致命的是,Nagios 本身不存储历史指标,只能看当前状态和告警,做容量趋势分析得另接 Graphite。
适用场景:网络设备 SNMP 轮询、少量静态服务器、对历史数据无要求的场景。如果你的环境十年不变,Nagios 依然稳如老狗。
三、Zabbix:传统运维的“全能选手”
2018 年我跳槽到一家制造业公司,300 台物理机 + 50 台网络设备。我选了 Zabbix 4.0,原因很简单:开箱即用,Web 界面友好,Agent 自动注册。
安装很直接,以 CentOS 7 为例:
rpm -Uvh https://repo.zabbix.com/zabbix/4.0/rhel/7/x86_64/zabbix-release-4.0-1.el7.noarch.rpmyum install -y zabbix-server-mysql zabbix-web-mysql zabbix-agent
数据库初始化:
CREATE DATABASE zabbix CHARACTERSET utf8 COLLATE utf8_bin;GRANTALL PRIVILEGES ON zabbix.*TO zabbix@localhost IDENTIFIED BY'StrongPass!2024';
Agent 端设置自动注册:
# /etc/zabbix/zabbix_agentd.confServer=10.0.0.100ServerActive=10.0.0.100Hostname=web-01HostMetadata=Linux
服务端开启自动注册动作,新机器上线 5 分钟内自动纳入监控。
Zabbix 的优势:
- 内置几百个模板,SNMP、IPMI、JMX 全覆盖
我踩过的坑:
- 数据库膨胀。默认 Housekeeper 清理慢,历史数据表半年涨到 200GB。后来调优:
-- 调整历史数据保留周期UPDATE housekeeper SET history_global =30, trends_global =365;
同时把 housekeeper 进程调大,并改用分区表。
API 性能瓶颈。当主机超过 2000 台,Web 前端查询明显变慢。解决方案是读写分离 + 前端加缓存。
自定义监控项写起来啰嗦。一个简单的 Redis 监控要写 UserParameter、Item、Trigger 三层设置。
适用场景:传统 IDC、混合云、需要统一 Web 界面、团队运维习惯偏“点击式”的环境。
四、Prometheus:云原生时代的默认答案
2020 年我进入一家互联网公司,K8s 集群 500+ 节点,微服务 200+。Zabbix 在这种动态环境下完全跟不上——Pod 一天重启几百次,IP 天天变,Zabbix 的主机模型根本没法玩。
Prometheus 的 pull 模型 + 服务发现完美解决这个问题。核心设置:
# prometheus.ymlglobal:scrape_interval:15sevaluation_interval:15sscrape_configs:-job_name:'kubernetes-pods'kubernetes_sd_configs:-role:podrelabel_configs:-source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]action:keepregex:true-source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]action:replacetarget_label:__metrics_path__regex:(.+)
告警规则用 PromQL 写,比 Zabbix 触发器灵活太多:
groups:-name:node-alertsrules:-alert:NodeHighCPUexpr:100-(avgby(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m]))*100)>85for:10mlabels:severity:warningannotations:summary:"节点 {{ $labels.instance }} CPU 使用率过高"
配合 Alertmanager 做告警分组、抑制、静默:
route:group_by: ['alertname', 'cluster']group_wait:30sgroup_interval:5mrepeat_interval:4hreceiver:'webhook-default'
Prometheus 的优势:
- 生态丰富,Grafana 可视化、Thanos 长期存储
我踩过的坑:
基数爆炸。有人把 user_id 做成标签,导致时间序列从 10 万涨到 800 万,内存直接打满。后来强制 code review,禁止高基数标签。
长期存储。本地 TSDB 默认保留 15 天,超过就得接 Thanos 或 VictoriaMetrics。我们最终选了 Thanos,设置 sidecar:
-name:thanos-sidecarimage:thanosio/thanos:v0.32.0args:-sidecar---tsdb.path=/prometheus---objstore.config-file=/etc/thanos/bucket.yml---prometheus.url=http://localhost:9090
- 告警风暴。初期没做抑制,一个网络抖动触发 500 条告警。后来用 Alertmanager 的
inhibit_rules 按 severity 分层抑制。
适用场景:K8s、微服务、动态扩缩容、需要强大查询能力的场景。
五、我的选型决策树
经过多次实战,我总结出这套判断逻辑:
- 环境是否动态? 是 → Prometheus;否 → 下一步
- 是否需要统一 Web 界面和开箱即用? 是 → Zabbix;否 → 下一步
- 是否只监控网络设备且无需历史趋势? 是 → Nagios;否 → Zabbix
补充几点:
- 混合环境可以 Prometheus + Zabbix 并存,各管一摊,Grafana 统一展示
- 团队技能很关键,PromQL 学习曲线陡,Zabbix 上手快
- 成本方面,Prometheus 存储成本高但灵活,Zabbix 数据库维护成本高但省心
六、最后的建议
不要迷信“最流行”的工具。我见过用 Zabbix 管 5000 台机器跑得很稳的团队,也见过 Prometheus 搭建 50 台机器就天天救火的。工具是死的,场景和团队才是活的。
如果让我给一个刚起步的团队建议:先用 Zabbix 快速覆盖基础监控,等 K8s 和微服务规模上来后,逐步引入 Prometheus 做补充,最终形成“Zabbix 管基础设施 + Prometheus 管应用”的双层体系。这套组合拳,我在三家公司都用过,稳。
👨💻 运维老兵经验:根据实际生产环境,以上步骤建议先在测试环境验证,并做好备份。参数值需根据服务器设置调整,不要盲目照搬。