☰
Zabbix + Grafana 自建监控系统实战:从部署到告警调优
2026/10/13 1:32:45 网站建设 项目流程

1. 为什么我要自己搭一套监控系统

事情得从去年说起。当时手上有三台云主机,跑着几个内部服务,平时靠 SSH 上去top、df -h看状态。结果有天凌晨一台机器磁盘写满,服务直接挂了,第二天早上才发现。那次之后我就下定决心:必须上一套正经的监控。

市面上的方案不少,云厂商自带的基础监控、各种 SaaS 化的可观测平台,用起来确实省事。但我有几个很实际的考虑:一是数据要留在自己手里,二是想怎么改面板就怎么改,三是成本可控——一台 2 核 4G 的云主机就能扛住中小规模的监控负载。所以最终选了Zabbix + Grafana这个经典组合。

Zabbix 负责采集和告警,Grafana 负责把数据画成好看的图。这套组合的好处是:Zabbix 的采集能力极其扎实,支持 Agent、SNMP、IPMI、JMX 等一大堆协议,告警逻辑成熟;Grafana 的展示能力则是天花板级别,面板灵活、插件丰富。两者通过 Zabbix 的 API 数据源对接,各司其职。

这篇文章我会把整套搭建过程完整写下来,包括环境准备、Zabbix Server 和 Agent 的部署、数据库选型、Grafana 对接、告警配置,以及我踩过的那些坑。适合有一定 Linux 基础、想自己动手搭监控的运维同学或后端开发。全程命令可直接复制,参数我会解释清楚为什么这么设。

2. 整体架构设计与选型思路

2.1 这套系统到底由哪些组件构成

先把架构讲清楚,不然后面装到一半容易懵。整套系统跑起来涉及这几个角色:

  • Zabbix Server:核心大脑,负责接收 Agent 上报的数据、执行触发器判断、发送告警。
  • Zabbix Web:前端界面,用 PHP 写的,跑在 Web 服务器上,用来配置主机、查看数据。
  • 数据库:存所有配置和采集到的历史数据,Zabbix 对数据库依赖很重。
  • Zabbix Agent:装在被监控主机上,负责采集本机指标并推送给 Server。
  • Grafana:独立的可视化平台,通过 Zabbix 数据源插件读取数据并绘图。

它们之间的关系可以这样理解:Agent 是"传感器",Server 是"大脑",数据库是"记忆",Web 是"操作台",Grafana 是"仪表盘"。传感器把数据给大脑,大脑存进记忆,操作台用来调教大脑,仪表盘把记忆里的数据画出来。

2.2 为什么数据库我最终选了 MySQL 而不是 PostgreSQL

Zabbix 官方对 MySQL 和 PostgreSQL 都支持得很好,早期版本甚至 MySQL 是默认推荐。我选 MySQL 的原因很朴素:生态熟悉、备份恢复工具链成熟、网上排错资料多。对于中小规模(几十台主机以内),MySQL 完全够用。

但这里有个关键点必须说:Zabbix 的数据库表会随着监控项数量爆炸式增长。历史数据表history、history_uint、trends这些,如果不管,几个月就能撑到几十 GB。所以我在建库阶段就规划好了分区和清理策略,后面会详细讲。

PostgreSQL 的优势在于复杂查询和并发写入场景下表现更稳,如果你的监控规模上千台,可以考虑。但对我这种规模,MySQL 8.0 的 InnoDB 完全扛得住。

2.3 版本选择:为什么不用最新版

写这篇文章时 Zabbix 已经出到 7.x,但我用的是Zabbix 6.0 LTS。原因很简单:LTS(长期支持)版本有 5 年支持周期,bug 少、文档全、社区踩坑记录多。生产环境追新是给自己找麻烦,除非新版本有你必须要的特性。

Grafana 我用的是 10.x 系列,同样避开刚发布的大版本。操作系统选Ubuntu 22.04 LTS,软件源里的包版本比较新,装 PHP 8.1、MySQL 8.0 都很顺。

2.4 服务器规格与网络规划

我用的是一台 2 核 4G、40G 系统盘的云主机作为监控服务器,单独挂了一块 100G 的数据盘给数据库用。这个配置能撑住大约 50 台主机、每台 30 个监控项的规模。

网络方面,安全组只放行必要端口:

端口用途是否对公网开放
22SSH 管理仅限自己的 IP
80/443Zabbix Web / Grafana建议仅内网或加认证
10051Zabbix Server 接收 Agent 数据仅内网
10050Zabbix Agent 监听仅内网
3306MySQL仅本机

注意:10051 和 10050 千万别对公网开放,否则等于把监控数据通道暴露出去。Web 端口如果必须公网访问,务必上 HTTPS 加访问控制。

3. 基础环境准备与依赖安装

3.1 系统初始化与时间同步

监控系统对时间极其敏感,时间不同步会导致数据错乱、触发器误判。第一步先把时间同步搞定:

sudo apt update && sudo apt upgrade -y sudo apt install -y chrony sudo systemctl enable --now chrony chronyc sources -v

chronyc sources输出里如果看到^*标记的源,说明同步正常。这一步别跳过,我见过因为时间漂移导致告警疯狂误报的案例。

接着设置主机名和 hosts,方便后续识别:

sudo hostnamectl set-hostname monitor-server echo "127.0.0.1 monitor-server" | sudo tee -a /etc/hosts

3.2 安装 MySQL 8.0 并做基础调优

sudo apt install -y mysql-server sudo systemctl enable --now mysql sudo mysql_secure_installation

mysql_secure_installation会引导你设置 root 密码、移除匿名用户、禁止 root 远程登录,一路选 Y 即可。

装完后要改几个关键参数,编辑/etc/mysql/mysql.conf.d/mysqld.cnf:

[mysqld] character-set-server=utf8mb4 collation-server=utf8mb4_bin default-storage-engine=InnoDB innodb_buffer_pool_size=1G innodb_log_file_size=256M innodb_flush_log_at_trx_commit=2 max_connections=300

这里解释几个关键参数:

  • innodb_buffer_pool_size:InnoDB 的缓存池,一般设为物理内存的 50%~70%。我 4G 内存设 1G,给系统和 Zabbix 留足空间。
  • innodb_log_file_size:日志文件大小,设大一点能减少 checkpoint 频率,提升写入性能。
  • innodb_flush_log_at_trx_commit=2:这个值让日志每秒刷一次盘而不是每次事务都刷,牺牲一点极端情况下的持久性换取写入性能。监控数据量大,这个取舍很值。
  • collation-server=utf8mb4_bin:Zabbix 官方要求用utf8mb4_bin,别用默认的utf8mb4_general_ci,否则建表可能报错。

改完重启 MySQL:

sudo systemctl restart mysql

3.3 创建 Zabbix 专用数据库和用户

sudo mysql -uroot -p

进入 MySQL 后执行:

CREATE DATABASE zabbix CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; CREATE USER 'zabbix'@'localhost' IDENTIFIED BY '你的强密码'; GRANT ALL PRIVILEGES ON zabbix.* TO 'zabbix'@'localhost'; SET GLOBAL log_bin_trust_function_creators = 1; FLUSH PRIVILEGES; QUIT;

log_bin_trust_function_creators = 1这行很关键。Zabbix 的建表脚本里包含存储过程和函数,如果开了 binlog 又没这个设置,会报权限错误。这个坑我踩过,卡了半小时才反应过来。

3.4 安装 PHP 及必要扩展

Zabbix Web 是 PHP 应用,需要一堆扩展:

sudo apt install -y php8.1-fpm php8.1-mysql php8.1-ldap php8.1-xml \ php8.1-mbstring php8.1-gd php8.1-bcmath php8.1-curl php8.1-zip

装完检查 PHP-FPM 状态:

sudo systemctl enable --now php8.1-fpm

然后调整 PHP 配置,编辑/etc/php/8.1/fpm/php.ini,改这几个值:

max_execution_time = 300 max_input_time = 300 memory_limit = 256M post_max_size = 32M upload_max_filesize = 32M date.timezone = Asia/Shanghai

max_execution_time设 300 秒是因为 Zabbix Web 有些操作(比如导入大模板)很耗时,默认 30 秒会超时。date.timezone不设的话 PHP 会警告,而且时间显示会乱。

4. Zabbix Server 与 Web 前端部署

4.1 添加官方源并安装 Zabbix 组件

wget https://repo.zabbix.com/zabbix/6.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_6.0-4+ubuntu22.04_all.deb sudo dpkg -i zabbix-release_6.0-4+ubuntu22.04_all.deb sudo apt update sudo apt install -y zabbix-server-mysql zabbix-frontend-php zabbix-apache-conf zabbix-sql-scripts zabbix-agent

这里一次装齐了 Server、Web 前端、Apache 配置、SQL 脚本和 Agent。Agent 装在 Server 本机是为了让 Server 也能监控自己。

4.2 导入初始数据库结构

zcat /usr/share/zabbix-sql-scripts/mysql/server.sql.gz | mysql --default-character-set=utf8mb4 -uzabbix -p zabbix

这条命令会把 Zabbix 的建表脚本解压后直接灌进数据库。数据量不小,执行时耐心等,中途别中断。导入完成后可以验证一下:

mysql -uzabbix -p -e "USE zabbix; SHOW TABLES;" | head -20

看到一堆表名就说明成功了。

4.3 配置 Zabbix Server 连接数据库

编辑/etc/zabbix/zabbix_server.conf,改这几行:

DBHost=localhost DBName=zabbix DBUser=zabbix DBPassword=你的强密码

其他参数保持默认即可。启动服务:

sudo systemctl restart zabbix-server zabbix-agent apache2 sudo systemctl enable zabbix-server zabbix-agent apache2

检查状态:

sudo systemctl status zabbix-server

如果看到active (running)就对了。如果起不来,八成是数据库连接问题,看/var/log/zabbix/zabbix_server.log里的报错。

4.4 完成 Web 前端初始化

浏览器访问http://你的服务器IP/zabbix,会进入安装向导。一路 Next,到数据库配置页填入之前的信息,最后设置一个管理员账号(默认是 Admin / zabbix,登录后立刻改密码)。

登录进去后,第一件事是检查Reports → System information,确认 Server 运行状态正常,没有红色告警。

4.5 在 Server 本机添加第一个被监控主机

进入Configuration → Hosts → Create host:

  • Host name 填Zabbix server
  • 在 Templates 里关联Linux by Zabbix agent
  • 在 Interfaces 里添加 Agent 接口,IP 填127.0.0.1,端口 10050

保存后等一两分钟,去Monitoring → Latest data就能看到 CPU、内存、磁盘等数据了。这一步成功意味着整条采集链路打通了。

5. 被监控主机的 Agent 部署

5.1 批量安装 Agent 的通用流程

每台被监控主机都要装 Agent。以 Ubuntu 为例:

wget https://repo.zabbix.com/zabbix/6.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_6.0-4+ubuntu22.04_all.deb sudo dpkg -i zabbix-release_6.0-4+ubuntu22.04_all.deb sudo apt update sudo apt install -y zabbix-agent

编辑/etc/zabbix/zabbix_agentd.conf:

Server=监控服务器内网IP ServerActive=监控服务器内网IP Hostname=本机主机名

Server是允许谁来拉取数据,ServerActive是主动上报的目标。两个都填监控服务器 IP。Hostname必须和 Zabbix Web 里配置的 Host name 完全一致,否则会报"host not found"。

启动并开机自启:

sudo systemctl restart zabbix-agent sudo systemctl enable zabbix-agent

5.2 自定义监控项:用 UserParameter 采集业务指标

内置模板只能采系统指标,业务指标得自己加。比如我想监控某个服务的进程数,在 Agent 配置里加:

UserParameter=myapp.process.count,pgrep -c myapp || echo 0

重启 Agent 后,在 Zabbix Web 里新建监控项,Key 填myapp.process.count,类型选 Zabbix agent,就能采到了。

提示:UserParameter 里的脚本一定要保证有输出且退出码为 0,否则 Zabbix 会标记为 unsupported。|| echo 0就是防止 pgrep 找不到进程时返回非零退出码。

5.3 主动模式与被动模式的取舍

Zabbix Agent 有两种工作模式:

  • 被动模式:Server 主动来拉数据,Agent 监听 10050 端口。
  • 主动模式:Agent 主动把数据推给 Server 的 10051 端口。

主机少的时候被动模式简单直接。但主机一多,Server 的轮询压力会很大。我的做法是:核心主机用被动模式保证实时性,边缘主机用主动模式减轻 Server 负担。切换主动模式只需在监控项里把类型改成 "Zabbix agent (active)",并在 Agent 配置里确保ServerActive正确。

6. Grafana 对接 Zabbix 数据源

6.1 安装 Grafana 并装 Zabbix 插件

sudo apt install -y software-properties-common sudo add-apt-repository "deb https://packages.grafana.com/oss/deb stable main" wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add - sudo apt update sudo apt install -y grafana sudo systemctl enable --now grafana-server

装 Zabbix 数据源插件:

sudo grafana-cli plugins install alexanderzobnin-zabbix-app sudo systemctl restart grafana-server

这个插件是社区里最成熟的 Zabbix 数据源实现,支持直接读取 Zabbix 的监控项、触发器和历史数据。

6.2 配置数据源连接

浏览器访问http://你的服务器IP:3000,默认账号密码都是admin,首次登录会要求改密码。

进入Configuration → Data Sources → Add data source,搜索 Zabbix,填:

  • URL:http://127.0.0.1/zabbix/api_jsonrpc.php
  • Access:Server (default)
  • Username / Password:Zabbix 的登录账号

点 Save & Test,如果显示 "Data source is working" 就成功了。

注意:URL 一定要指向api_jsonrpc.php这个文件,不是 Zabbix 首页。我第一次填了首页地址,一直报 404,排查半天。

6.3 导入现成面板快速出图

Grafana 官方面板库里有大量 Zabbix 面板。进入Dashboards → Import,输入面板 ID(比如 5363 是 Zabbix 主机概览面板),选好数据源就能导入。

导入后如果图是空的,检查两点:一是数据源选对了没,二是面板里的主机名和 Zabbix 里的 Host name 是否匹配。这两个是最常见的空图原因。

6.4 自己动手做一个业务监控面板

现成面板看系统指标够用,但业务指标得自己画。新建 Dashboard,Add panel,Query 里选 Zabbix 数据源,Mode 选 Metrics,然后:

  • Group:选主机组
  • Host:选具体主机
  • Item:选你要画的监控项,比如myapp.process.count

在 Options 里可以设置单位、阈值线、图例。我习惯给关键指标加一条红色阈值线,一眼就能看出是否越界。

7. 告警配置与数据清理策略

7.1 配置邮件告警媒介

进入Administration → Media types,找到 Email,配置 SMTP 服务器信息。国内用企业邮箱或自建邮件服务都行,填好 SMTP 地址、端口、发件账号密码。

然后在User settings → Media里给管理员账号绑定邮箱,勾选要接收的告警级别。

7.2 触发器与动作的配合逻辑

告警的核心是"触发器 + 动作":

  • 触发器(Trigger):定义什么条件算异常,比如"CPU 使用率连续 5 分钟超过 90%"。
  • 动作(Action):定义异常后干什么,比如"发邮件给运维组"。

新建触发器时,表达式可以这样写:

avg(/host/system.cpu.util,5m)>90

意思是 5 分钟平均值超过 90% 就触发。这里用avg而不是瞬时值,是为了避免毛刺误报。我建议所有告警都加时间窗口,否则半夜被单次抖动吵醒是常事。

7.3 数据库历史数据清理

这是最容易被忽视、也最容易出事的地方。Zabbix 默认保留历史数据 90 天、趋势数据 365 天。如果不清理,数据库会无限膨胀。

进入Administration → Housekeeping,可以调整保留天数。但光靠 Housekeeping 删除大表数据会很慢,甚至锁表。更好的做法是给大表做分区。

以history_uint表为例,按月分区:

ALTER TABLE history_uint PARTITION BY RANGE (clock) ( PARTITION p202401 VALUES LESS THAN (UNIX_TIMESTAMP('2024-02-01')), PARTITION p202402 VALUES LESS THAN (UNIX_TIMESTAMP('2024-03-01')), PARTITION p202403 VALUES LESS THAN (UNIX_TIMESTAMP('2024-04-01')) );

分区后删除旧数据只需DROP PARTITION,秒级完成,不影响其他数据。这个优化我强烈建议在数据量上来之前就做好,等表几十 G 了再改会很痛苦。

7.4 监控系统自身的健康检查

监控系统自己挂了却没人知道,是最尴尬的事。我加了几条自监控:

  • Zabbix Server 进程是否存在
  • 数据库连接数是否接近上限
  • 磁盘剩余空间是否低于 20%
  • Zabbix 队列积压是否过多(zabbix[queue]监控项)

队列积压是 Server 性能不足的早期信号,一旦持续增长就要考虑加资源或优化监控项了。

8. 常见问题与排查实录

8.1 高频问题速查表

现象可能原因排查方向
Web 报数据库连接失败密码错/权限不足检查 zabbix_server.conf 和 MySQL 授权
Agent 显示 unsupportedKey 写错/脚本无输出用zabbix_agentd -t key手动测试
数据不更新时间不同步/网络不通检查 chrony 和 10050/10051 端口
Grafana 图空白数据源或主机名不匹配核对 Host name 和 API 地址
告警不发送媒介未绑定/动作未启用检查用户 Media 和 Action 状态
数据库暴涨未做清理/分区检查 Housekeeping 和表分区

8.2 几个我踩过的坑

坑一:字符集不匹配导致建表失败。一开始数据库用了默认的utf8mb4_general_ci,导入 SQL 时报 collation 冲突。必须用utf8mb4_bin,这是 Zabbix 的硬性要求。

坑二:Agent 主机名大小写敏感。Zabbix 里 Host name 是区分大小写的。我在 Web 里写WebServer,Agent 配置里写webserver,结果一直连不上。统一成小写最省心。

坑三:主动模式忘了改监控项类型。只改了 Agent 配置,没改 Web 里监控项的类型,数据一直采不到。主动模式必须在监控项层面也切换。

坑四:告警风暴。一台机器网络抖动,几十个触发器同时报警,邮箱瞬间被刷爆。解决办法是配置告警依赖和抑制规则,比如网络不可达时抑制其上层的服务告警。

8.3 性能调优的几个实操心得

Zabbix Server 的StartPollers、StartTrappers这些进程数参数,默认值偏保守。主机多了之后,如果队列积压,可以适当调大。我的经验是:先看队列,再调参数,别盲目加进程,加多了反而抢 CPU。

数据库层面,定期ANALYZE TABLE和OPTIMIZE TABLE能保持查询性能。但OPTIMIZE TABLE会锁表,要在低峰期做,或者干脆用分区方案替代。

Grafana 查询大时间范围的数据时容易超时,可以在数据源配置里调大 timeout,或者用 Zabbix 的 trend 数据(趋势数据是小时级聚合,查询快得多)而不是原始 history 数据。

9. 我个人的几点体会

整套系统从零搭到稳定运行,我大概花了两个周末。真正装软件的时间不多,大部分精力花在调参、排错和设计告警规则上。这里分享几个我觉得最有价值的经验。

第一,监控项不在多而在精。一开始我恨不得把所有能采的指标都加上,结果数据量爆炸、面板眼花缭乱、告警噪音不断。后来砍掉一大半,只留真正影响服务的核心指标,反而更实用。

第二,告警规则要反复打磨。好的告警应该是"该响的时候一定响,不该响的时候绝不响"。我现在的做法是:新规则先只记录不发送,观察一周,确认阈值合理后再开启通知。

第三,文档和备份比什么都重要。监控系统的配置(模板、触发器、面板)一定要定期导出备份。我有次误删了一个主机组,连带几十个监控项没了,幸好有备份,十分钟就恢复了。

这套 Zabbix + Grafana 的组合,规模不大时一台机器就能跑,规模上来了也能横向扩展。它不是什么时髦的方案,但胜在稳定、可控、生态成熟。如果你也在纠结要不要自己搭监控,我的建议是:只要你有超过三台服务器,就值得动手搞一套。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询