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 个监控项的规模。
网络方面,安全组只放行必要端口:
| 端口 | 用途 | 是否对公网开放 |
|---|---|---|
| 22 | SSH 管理 | 仅限自己的 IP |
| 80/443 | Zabbix Web / Grafana | 建议仅内网或加认证 |
| 10051 | Zabbix Server 接收 Agent 数据 | 仅内网 |
| 10050 | Zabbix Agent 监听 | 仅内网 |
| 3306 | MySQL | 仅本机 |
注意: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 -vchronyc sources输出里如果看到^*标记的源,说明同步正常。这一步别跳过,我见过因为时间漂移导致告警疯狂误报的案例。
接着设置主机名和 hosts,方便后续识别:
sudo hostnamectl set-hostname monitor-server echo "127.0.0.1 monitor-server" | sudo tee -a /etc/hosts3.2 安装 MySQL 8.0 并做基础调优
sudo apt install -y mysql-server sudo systemctl enable --now mysql sudo mysql_secure_installationmysql_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 mysql3.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/Shanghaimax_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-agent5.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 显示 unsupported | Key 写错/脚本无输出 | 用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 的组合,规模不大时一台机器就能跑,规模上来了也能横向扩展。它不是什么时髦的方案,但胜在稳定、可控、生态成熟。如果你也在纠结要不要自己搭监控,我的建议是:只要你有超过三台服务器,就值得动手搞一套。