简介:这份PDF技术合集完整收录了Zabbix监控系统360个常见问题及解答,由乐维社区整理,面向Zabbix运维工程师、监控平台管理员及企业IT支撑人员。内容以问答形式深入解析数据展示不完整、agent主动/被动模式切换、图形单位修改、数据入库延时、告警触发与登录告警设置、仪表盘URL调用、交换机光衰监控、SNMP Trap收发、Web端SNMP不通以及PostgreSQL+TimescaleDB备份等高频场景,覆盖从数据采集、告警配置到存储备份的完整链路;每个问题均给出具体排查思路、配置命令或官方文档指引,例如触发器中count函数的使用、agent配置文件中Server与ServerActive的区别等,可直接对照生产环境操作。资源为PDF电子书,共1个文件,包体大小2.96MB,便于通勤或现场应急查阅。目前已有544人学习使用;对于正在搭建或维护Zabbix平台、需要快速定位告警与数据异常的技术人员,这份合集能显著缩短排错时间。
1. 为什么 Zabbix 总在“看着正常却查不出问题”:360 个坑位背后的拆解思路
Zabbix 是开源监控里少见的集采集、告警、可视化于一体的全家桶,但凡是生产环境跑上一年的人,几乎都经历过这样的场景:主机列表全绿,昨晚的磁盘告警却没人收到;明明配了触发器,恢复通知却迟到了半小时;数据库每天都在涨,手工清理完没两天又膨胀。这些问题单个看都是小毛病,串起来却让人怀疑人生。这份“360 个 Zabbix 常见问题详解”不是泛泛的 FAQ,而是把安装部署、模板配置、告警路由、性能调优、API 自动化等环节的真实故障按场景拆开,每一条都带着现象、原因和解决路径。适合刚接手 Zabbix 的运维,也适合被历史包袱折磨的资深用户——你可以把它当字典翻,也能顺着分类自查手头的监控环境。
2. 从装到跑通:部署阶段的高频问题与参数调整
2.1 安装阶段:数据库字符集与时区这两个隐形杀手
很多人的 Zabbix 装完页面能开,但过几天就出现中文乱码、图形时间偏移 8 小时,追根溯源基本都是安装时埋的雷。
先说数据库字符集。Zabbix 官方文档要求 MySQL 使用 utf8mb4,但很多一键安装脚本默认还是 utf8。生产环境里,一旦监控项名称、主机名或告警消息里出现 emoji 或者生僻字,写入就会报错。更隐蔽的是,如果库表已经建好,中途改库级字符集不会自动转换已存在的表。我一般用这条命令检查:
SELECT TABLE_NAME, TABLE_COLLATION FROM information_schema.TABLES WHERE TABLE_SCHEMA='zabbix' AND TABLE_COLLATION != 'utf8mb4_general_ci';执行后如果返回非空结果,说明有表没对齐。常见做法是先把整个库 dump 成 SQL 文件,替换掉所有 CHARSET=utf8 为 utf8mb4,再重新导入。注意备份要带--default-character-set=utf8mb4,否则导出时中文就会被转坏。数据库层面改完后,前端配置文件zabbix.conf.php里不需要额外设置,但 PHP 的default_charset建议保持 UTF-8。
时区问题则分成两层:系统时区、PHP 时区。如果系统是 UTC,前端设定的时区显示正确,但历史数据抓取时间戳会是 UTC,导致图形曲线的峰值时间偏移。排查步骤是先统一所有 Zabbix Server、Proxy 和前端所在的服务器时区到同一个值,再改 PHP-FPM 的php.ini:
date.timezone = Asia/Shanghai改完重启 php-fpm 和 zabbix-server。这里有个坑:如果只有前端改了时区,而 server 端没改,就会出现告警时间正常、但图形横轴时间错位的割裂现象。判断该问题最快的方法,是在前端“最新数据”里看同一个监控项的时间戳,和服务器date输出对比,相差超过 5 分钟就要查时区配置。
2.2 前端登录后白屏:PHP 参数与 SELinux 的联动排查
登录 Zabbix 前端没报错,但页面全白,这是部署期最容易让人抓狂的问题。有次某开发者在 CentOS 7 上装了 5.0,点击登录后直接白屏,Apache 错误日志里什么也没有。后来才发现是 PHP 的mysqli扩展没装全,但页面没直接提示,而是静默失败。
先检查基础依赖:
php -m | grep -E 'bcmath|ctype|gd|libxml|mbstring|mysqli|gettext|socket'输出里缺失任何一项,都可能导致前端白屏。另一个常见原因是 PHP 的max_execution_time设得太短,恰好卡在登录时执行初始化 SQL 的步骤超时。建议装完初期先放宽:
max_execution_time = 300 memory_limit = 256M post_max_size = 16M如果这些都对,再看 SELinux。CentOS 7 上 Apache 被 SELinux 限制导致 PHP 无法连接数据库,或无法写 session 目录,白屏就会间歇性出现。临时验证方法是执行setenforce 0,刷新页面。能进去的话,再用ausearch -m avc -ts recent看具体拒绝日志。长期方案是给 httpd 打开正需要的布尔值,而不是直接关 SELinux:
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_network_connect_db=12.3 采集不到数据:先看内置 Key 的返回值
主机列表显示“已启用”,但最新数据永远是空白。这种情况 70% 出在 agent 端 key 写错或返回格式不对。先在 Zabbix Server 上用zabbix_get直接测,比前端看状态直观得多:
zabbix_get -s 192.168.1.10 -k system.cpu.util[,iowait]如果返回ZBX_NOTSUPPORTED,说明 key 不支持。常见原因是 agent 版本跟 server 不匹配,比如 server 5.0 默认给 agent 发的是新 key,旧 agent 不认识。还有一类是权限问题,agent 配置里Server=127.0.0.1而实际 server IP 不在允许列表内,结果就是zabbix_get能通但返回空。注意Server和ServerActive要一起改,前者对应被动模式,后者对应主动模式。我见过最奇葩的情况是防火墙放行了 10050 端口,但 agent 监听在 IPv6 的::上,Server 用 IPv4 连接失败,这种用ss -tlnp | grep 10050一看便知。
3. 模板和触发器:把误报率降下来的关键配置实操
3.1 模板继承与宏覆盖:理解作用域才能少踩坑
模板是 Zabbix 的灵魂,但也是误报和漏报的重灾区。新手常犯的错误是直接在主机上改模板里的监控项,结果模板一更新,手工改的就丢了。正确做法是善用宏覆盖。
模板里定义宏{$THRESHOLD},主机上可以重新赋值,这不影响模板本身。但有个深层逻辑:如果模板里的触发器表达式直接用了数值,主机上就没法按需调整阈值。我习惯所有阈值都通过宏传递,即使是默认值。
例如在模板里定义触发器表达式:
last(/MySQL by Zabbix agent/queries.per_second,5m) > {$MYSQL_MAX_QPS}然后在模板宏里设置{$MYSQL_MAX_QPS}=1000,具体某台高负载主机覆盖为5000。这样既能统一管理,又能差异化调整。
宏的优先级是:主机级宏 > 模板级宏 > 全局宏。这里有个坑:如果主机同时链接了多个模板,两个模板都定义了同名宏,Zabbix 会按模板链接顺序取第一个,而不是后者覆盖前者。改链接顺序的方法是在主机“模板”标签页里上下拖动模板名称,但很多人不清楚这个机制。
3.2 触发器表达式:针对抖动数据的灵活阈值写法
监控 CPU 使用率时,一个瞬间的 100% 就会触发告警,但实际业务没受任何影响。这时频繁告警比不告警更讨厌,因为运维会对告警脱敏。
常见优化是加时间窗口:
min(/Linux by Zabbix agent/system.cpu.util[,idle],5m) < 20这表示 5 分钟内最小值都低于 20% 才触发。如果想连续三次检测都超标才告警,可以用 count 函数:
count(/Linux by Zabbix agent/system.cpu.util[,idle],5m,lt,20) > 2这个表达式统计 5 分钟内 idle 小于 20 的样本个数,超过 2 次才触发。适合 CPU 尖刺明显的场景。
另一个高频问题是进程监控里的重启告警。监控某个 Java 进程是否存在,进程一重启就会触发“进程不存在”告警,然后再次恢复,但运维只关心是否持续不恢复。解决方法是配合nodata函数:
nodata(/App/service_status,10m)=1这表示数据源连续 10 分钟没有上报,才判定进程异常。相比直接判断进程数等于 0,这种方式能容忍监控 agent 和进程的瞬时抖动,减少假告警。
3.3 告警升级与恢复通知:避免半夜被无意义告警吵醒
告警媒介配置好之后,升级策略往往被忽略。我把告警升级分为两级:问题持续 5 分钟发邮件给值班人,持续 30 分钟发短信给主管。但 Zabbix 默认没有按问题持续时间自动升级的能力,需要借助“动作”里的多操作步骤。
在“告警动作”里配置步骤,第一步 0 秒发送邮件给用户组 A,第二步 1800 秒发送给用户组 B。注意这里的秒数是触发动作后经过的时间。坑在于如果问题恢复发生在第一步和第二步之间,两步都会执行,导致已经恢复后主管还会收到一条升级短信。
解决办法实在动作条件里加上“问题事件”的持续时间判断,更稳妥的做法是第二步的条件设置为“问题未恢复且持续时间超过 1800 秒”。虽然 Zabbix 的表达式里没有“持续时间”直接字段,但可以通过维护时间或手动关闭动作解决。更实用的是把升级消息内容设成“问题仍在处理中”,而不是当作新告警。
恢复通知也有坑:默认情况恢复通知只在动作里配置了“操作消息”时才会发。如果只想让某些人收到恢复消息,需要单独配置恢复操作步骤,而不是复用问题消息。我一般把恢复消息的标题写成“【恢复】”,方便邮件过滤器分流。
4. 常见问题排查避坑:现象、原因、解决三连
4.1 历史数据堆积导致数据库暴涨
现象:Zabbix 数据库目录占了 200GB,前端打开“最新数据”都要转圈超过 10 秒。
原因:housekeeper 进程每周清理历史表,但删除速度跟不上写入速度;或者设置了“不删除历史数据”,导致表无限增长。检查方式:
SELECT table_name, ROUND(data_length/1024/1024, 2) AS data_mb FROM information_schema.TABLES WHERE table_schema='zabbix' ORDER BY data_mb DESC LIMIT 5;大概率是history、history_uint、trends这几个膨胀。解决三步走:第一步修改前端“历史”保留时间到 7 天、趋势保留时间到 365 天;第二步手动执行一次 housekeeper 的清理 SQL 作为应急;第三步重启 zabbix-server 让 housekeeper 拿到新配置。如果清理速度还是跟不上,考虑分区表——把 history 表按天分区,删除时直接DROP PARTITION,比 DELETE 快几个数量级。这个操作有现成脚本,但千万别在生产库直接跑没验证过的分区脚本。
4.2 中文乱码与图形字体问题
现象:图形里的中文标题变成方框,或告警通知的中文显示问号。
原因:Zabbix 前端用的是 DejaVu Sans 字体,这套字体对中文支持很差。解决方法是给 Zabbix 前端指定中文字体路径。先把一个开源中文字体文件如AlibabaPuHuiTi-Regular.ttf放到/usr/share/zabbix/assets/fonts/,然后编辑/usr/share/zabbix/include/defines.inc.php:
define('ZBX_FONTPATH', '/usr/share/zabbix/assets/fonts'); define('ZBX_GRAPH_FONT_NAME', 'AlibabaPuHuiTi-Regular');改完刷新图形页。注意文件名不带.ttf后缀。另一个坑是如果浏览器本身没问题,但图片里中文仍乱码,就要检查这个字体文件是否完整加载,用fc-list | grep -i "$(php -r 'echo ZBX_GRAPH_FONT_NAME;')"来验证。
4.3 主动模式与被动模式混用导致数据断档
现象:部分主机数据正常,部分主机数据每隔一段时间跳空 5 到 10 分钟。
原因:前端“数据收集方法”配置了主动 + 被动两种模式,但 agent 配置文件里ServerActive指向的地址通不通,或者主动模式刷新间隔和被动模式间隔不一致。
如果两种模式都在收集同一个 key,可能出现数据重复。Zabbix 对相同 key 的主动与被动采集,会以最新时间戳覆盖,但也可能因为 agent 主动上报延迟造成临时不连续。我一般建议统一为被动模式,除非主机数量超过 500 或网络分区明显。若必须主动模式,检查zabbix_agentd.conf里ServerActive必须是 server 或 proxy 的 IP,同时防火墙放开 10051 端口。验证主动模式通不通,在 agent 端执行:
zabbix_agentd -t agent.ping返回1只代表本机 agent 活着,要看主动上报是否成功,需要实时看/var/log/zabbix/zabbix_agentd.log里有没有failed to send字样。
4.4 权限配置不当引起告警静默
现象:用户收不到任何告警,但 zabbix 前端中“报告”显示告警已经发送成功。
原因:用户被分配到多个用户组,告警动作里指定了某个用户组,但该用户在另一个组里被禁用了“接收告警”权限。Zabbix 的权限控制里,用户组权限是“取并集”还是“取交集”取决于用户组的配置。默认是取并集,但如果有任意一个组设置了“禁用通知”,那么该用户实际上会被禁用通知,即使其他组赋予接收权限。
处理方式是在用户属性里查看“发送消息”开关,还要逐个检查所属用户组的“通知”权限。更隐蔽的是,媒介配置里“启用”时间没有勾选,或者用户的媒介地址填错了,比如填了不存在的邮箱。排查顺序:先确认动作操作里勾选了“发送消息”,再确认用户媒介列表的状态是“已启用”,最后看问题事件的消息是否在“报表”里生成。如果报表里事件状态是“已发送”,但用户没收到,那就是媒介配置或权限问题。
5. 性能与容量:从单机到分布式部署的边界在哪
5.1 单节点性能瓶颈指标与估算方法
很多团队直接用 1C2G 的虚拟机跑 Zabbix,先不说能支持多少监控项,单是前端页面切换都卡。Zabbix 官方资料给出过一个大致的参考:单台服务器建议最多支持 5000 到 10000 个监控项,但实际瓶颈往往不在 CPU 而在磁盘 IO。
判断现有环境是不是瓶颈,先看三个指标:zabbix_server.log里有没有housekeeper process耗时过长;top看到 mysqld 的%wa是否超过 20%;vmstat 1里bi和bo是否长期几千。如果磁盘 IO 持续高,优先考虑把 history 表放到单独的磁盘,或者用固态盘。还有一个容易忽略的配置是CacheSize,默认 8MB 是给 agent 数据缓存用的。当主机数超过 200,且大量使用 agent 主动模式,这个值建议提升到 128M 甚至 256M。修改后重启 server,看日志里的“cache values: 100% used”是否消失。
5.2 分区与保留策略:历史数据管理的真正解法
数据保留策略不只是设一个数字那么简单。Zabbix 前端“历史”页签填的保留天数,本质是写入 housekeeper 的删除条件,但在千万级数据量的表上执行 DELETE 是灾难。分区的价值在于把删除变成瞬时操作。
常见的做法是让 history 表按天分区,并提供分区维护脚本。以 MySQL 8.0 为例,给history_uint表添加举例分区:
ALTER TABLE history_uint PARTITION BY RANGE (YEAR(clock)*100 + MONTH(clock)) ( PARTITION p202401 VALUES LESS THAN (202402), PARTITION p202402 VALUES LESS THAN (202403) );这里用clock字段的月份作为分区键。接下来每个月末新增下个月分区,并删除两个月前的分区。这个操作要用 cron 或计划任务自动执行。需要注意,分区字段必须是主键的一部分,如果原表主键不是(itemid, clock),需要重建主键。这个动作非常谨慎,建议先在测试库执行。
趋势表trends和trends_uint可以按周分区。分区后,Zabbix 自带的 housekeeper 仍然会执行 DELETE,但会对跨分区操作造成额外开销。最好在配置文件里关闭对应表的 housekeeper,完全依赖分区维护脚本。这个度要自己把握,我建议至少保留一份 housekeeper 作为兜底,再配合分区脚本的双保险。
5.3 API 与自动化:用脚本批量接入的常见坑
Zabbix 的 API 比较规范,但实践中踩坑最多的就是 token 认证和 JSON-RPC 的数据类型。以 5.0 版本为例,登录获取 token 的简单脚本:
curl -s -X POST http://zabbix.example.com/api_jsonrpc.php \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "method": "user.login", "params": {"username": "Admin", "password": "zabbix"}, "id": 1 }' | python3 -m json.tool返回值里的result就是 token,后续请求要在请求头发Authorization: Bearer <token>。坑就在于版本差异:4.4 之前用的是auth字段,5.0 之后改用Authorization头,旧文档例子直接拿过来会报Not authorized。
批量创建主机时,另一个隐蔽的坑是接口参数类型。params.host必须是字符串,而interfaces里的port也必须是字符串,有人传成数字导致创建失败。建议参数全部用引号包起来,再配合逐个返回值校验。还有对groupids的判断,如果传入不存在的组 ID,API 会报错而不是自动忽略,用之前先查询组 ID 列表。
6. 一个实操技巧:把 360 个问题变成你自己的排查手册
6.1 如何快速检索问题库
这份资料拿到手,先别从头看到尾,除非你时间充裕。我建议先按目录分类扫一遍,把自己环境里现有的配置清单列一个 Excel:主机数、监控项数量、使用的模板、告警媒介、数据库大小。然后带着这些实际数字去翻问题库的相关章节,比漫无目的地读效率高得多。
读的时候,别光记答案。我习惯在问题库的基础,建立自己的索引表:问题关键词、对应章节、实际验证日期、是否踩到同款坑。比如翻到“history 表膨胀”这条,就顺手在自己的环境执行一次 4.1 节里的 SQL,确认一下 history 表的占比。这样过一遍,等于给生产环境做了一次体检。
6.2 用问题日志反向校准监控项
我的习惯是每次生产事故处理完后,把手动排查过的命令和结果追加到这份问题库的对应条目旁边。比如那天某个进程挂掉,手动执行了systemctl status、tail -n 100 /var/log/app.log、zabbix_get,每一步返回什么,最终定位到什么,都补上。这样三个月后你再翻到这个条目,就能直接复用当时的排查路径。
具体做法是拿 Markdown 维护一个“补充分节”,每个标题下写三行:现象摘要、实际定位过程、最终配置更改。等收集完二三十条,再回头对应问题库里的标准答案,会发现自己环境里根本不是缺文档,而是缺一本“排错过什么”的记录。把那 360 个问题当作底料,叠加自己的踩坑日志,才是真正属于你的 Zabbix 排障手册。从那以后,我每次新接一个监控环境,都会强制走一遍“对照问题库 - 逐项验证 - 补录日志”的流程,再没被同样的坑绊倒过。希望帮到你。
本文还有配套的精品资源,点击获取