☰
Zabbix报错排查实战:从Access denied到告警推送全指南
2026/9/30 6:32:38 网站建设 项目流程

没有哪个运维没被Zabbix折磨过。从装好服务端那一刻的Access denied,到监控图上数据死活不出来,再到钉钉告警怎么都推不出去,这一路报错踩过去,基本就等于把Zabbix的文档手册翻了一遍。今天我不讲理论、不贴官网原话,直接把这些年攒下的Zabbix报错案例、排查思路和最终解决方案整理成一份“实战集锦”,每一个都是真实环境里滚过的坑,你照着看就行。

这篇内容适合谁?刚把Zabbix装起来准备搞监控的初学者,被“监控项不支持”“主机不可达”逼疯的新手,以及被钉钉联动、模板导入这些问题卡住的进阶用户。无论你是CentOS、Rocky Linux还是Ubuntu,只要用的是Zabbix 6.x或7.x系列,这篇都能帮你省下不少翻论坛的时间。

1. 安装部署阶段的经典报错

安装阶段的问题最多,但也最套路化。因为Zabbix依赖的组件太多——数据库、PHP、Web服务器、Agent,任何一个环节的版本或者配置对不上,都会在安装或者初始化的时候炸出来。好消息是,这类报错的排查路径非常标准,掌握了套路基本都是一次过。

1.1 Access denied for user 'zabbix'@'localhost' 数据库连接被拒

这是Zabbix Server安装后最经典的报错,没有之一。装上server包、导完数据库之后,打开前端页面或启动服务时报这个错,意思是Zabbix Server进程连不上MySQL/MariaDB。

先别急着改密码,要按顺序排查三件事。第一件事,确认数据库账号和密码是否真的创建成功。很多人用的是各种一键脚本或者照搬博客的安装命令,结果忽略了某个步骤。用下面这条命令手动验证一下:

mysql -uzabbix -p -h 127.0.0.1

如果这里直接报错,说明问题出在数据库侧,检查用户是否创建、授权是否正确:

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

第二件事,检查Zabbix Server配置文件里的数据库密码是否和实际一致。配置文件路径通常是/etc/zabbix/zabbix_server.conf,找到这几行:

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

改完配置文件一定要重启服务,并且用zabbix_server -t测试配置是否正确。

第三件事,最容易忽略的——SELinux。如果你用的是RHEL/Rocky Linux/CentOS,SELinux很可能在暗中拦截。排查命令:

getenforce

如果是Enforcing,先临时关闭测试定位:

setenforce 0

如果关闭后正常了,说明就是SELinux的锅。不要图省事直接禁用SELinux,用下面的命令放行Zabbix的相关权限:

setsebool -P zabbix_can_network 1 setsebool -P domain_kernel_load_modules 1

注意:有些老教程会让你关闭SELinux完事,但生产环境千万别这么干。正确做法是放行必要选项,安全合规和监控系统不冲突。

第三件事的场景再补充一个变种:如果配置了远程数据库,DBHost写的是IP而不是localhost,那么MySQL侧的用户授权就需要改成'zabbix'@'%'或者'zabbix'@'你的ServerIP',不然就算密码对了照样Access denied。这个坑在云服务器和Docker化部署时非常常见。

1.2 数据表导入报错或导入后前端仍提示数据库错误

另一个高频安装问题是导入create.sql.gz时报错,或者导入成功但前端初始化页面一直提示数据库版本过低、表结构缺失。这通常不是Zabbix本身的问题,而是数据库版本或者字符集不对。

Zabbix 7.0要求MySQL 8.0.x或者MariaDB 10.5以上。如果你机器上自带的是MySQL 5.7老版本,导入时大概率会碰到不兼容的语法错误。解决办法很简单,先把数据库升级,再重新导入。不要试图手动改SQL文件去匹配老版本,Zabbix官方根本不支持这么干。

字符集的问题更隐蔽。Zabbix的SQL文件明确指定了utf8mb4字符集,但如果你手动建库时用了默认的latin1或者utf8mb3,虽然导入不报错,后面前端页面中文注释、告警内容、图表标题会出现乱码,甚至是无法写入告警信息。建库时务必带上:

CREATE DATABASE zabbix CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;

导入命令用zcat /usr/share/zabbix-sql-scripts/mysql/server.sql.gz | mysql -uzabbix -p zabbix这种方式执行,一次性导入完成。导入之后用mysql -uzabbix -p -e "USE zabbix; SHOW TABLES;"检查表是否完整,Zabbix 7.0在全新安装时应该有180张左右的表,如果数量明显偏少,说明导入过程被中断了,重来一次。

1.3 前端页面显示PHP环境不满足要求

装完Zabbix服务端,浏览器打开前端页面,最常见的报错是“PHP option max_execution_time should be set to 300”这一类。Zabbix对PHP的各种参数有硬性要求,统统在/etc/php.ini或者PHP-FPM的配置里调整。

建议直接把下面这些参数一次性改到位:

max_execution_time = 300 max_input_time = 300 memory_limit = 128M post_max_size = 16M upload_max_filesize = 2M date.timezone = Asia/Shanghai

改完之后别忘了重启PHP-FPM:

systemctl restart php-fpm

这里面最坑的是date.timezone。如果你不设置时区,Zabbix前端能打开,但所有图表、告警时间都会比本地时间慢8小时,监控数据的时间轴全是错的。我也见过有人把 date.timezone 写在PHP的某个配置文件里,但没写对位置,PHP-FPM加载的其实是另一个配置文件。排查时可以新建一个info.php放到Web根目录,访问后查看Loaded Configuration File那一行,确认自己改的是不是真正生效的配置文件。

1.4 前端打开404、页面空白或权限报错

前端页面404大多和Web服务器的配置有关。如果你用Nginx + PHP-FPM部署Zabbix,Nginx的root路径配置不对就404。Zabbix的前端文件通常装到了/usr/share/zabbix,Nginx配置里应该写:

root /usr/share/zabbix;

而且location ~ \.php$里的fastcgi_param SCRIPT_FILENAME要配合root路径来写,不然PHP文件解析不到。

页面空白则可能是PHP的opcache扩展冲突或者PHP版本太高。Zabbix 5.0之后的版本对PHP 8.1支持良好,但如果你用的是非常老的Zabbix 4.x配上PHP 8.1,前端就会白屏。我在实际中遇到一次,参考IBM的推荐方案,降级PHP到7.4才解决。

权限报错就简单了,多半是/etc/zabbix/web/下的zabbix.conf.php文件不可写。Zabbix安装完成后这个文件需要可写权限才能保存配置,安装完成后又要改回只读。用chmod 644设置后,再给php-fpm用户(通常是apache或nginx)加读权限即可。

2. 主机添加与监控项获取数据时报错

服务端装好只是第一步,真正开始干活是往里面加主机、配置监控项。这里报错的密集度比安装阶段更高,而且错误提示往往看不懂,比如主机状态是灰色、监控项显示“Not supported”、数据一直没值。这个阶段需要理解Zabbix的数据采集模型,不然很容易被表象带偏。

2.1 添加其他主机时状态为灰色或红色

在Zabbix前端添加了一台新主机,列表里显示红色(不可达)或者灰色(从未连接)。首先要分清楚这台主机是被Agent监控还是SNMP/IPMI监控,不同方式排查路径不一样。

以最常见的Agent监控为例,先排除网络层面的问题。在Zabbix Server所在机器上执行:

telnet 目标主机IP 10050 nc -vz 目标主机IP 10050

如果端口不通,检查目标主机的防火墙:

firewall-cmd --permanent --add-port=10050/tcp firewall-cmd --reload

端口通了但还是灰色,就要考虑Zabbix Agent的配置。Agent的配置文件/etc/zabbix/zabbix_agentd.conf里有几个关键项:

Server=ZabbixServer的IP ServerActive=ZabbixServer的IP Hostname=主机名(必须与前端的Host name一致)

这里最坑的就是Hostname。很多人在前端填主机名时随手写了一个“web-server-01”,Agent配置里的Hostname却还是默认的Zabbix server,结果是Agent起来了、端口也通了,但Server不认这个主机名,状态就一直灰色。前端的主机名和Agent的Hostname必须完全一致,这是新手最容易忽略的。

还有Agent的被动模式默认监听10050,主动模式要连Server的10051端口。如果你只想用主动模式(Agent主动上报),那防火墙要放行的不是10050,而是Server端的10051。这两个模式如果搞反了,主机状态照样是灰色,日志里会出现连接被拒绝的记录。排查时先看Agent日志/var/log/zabbix/zabbix_agentd.log,里面有明确线索。

2.2 监控项状态Not supported的处理方法

监控项添加了,但状态从“已启用”变成了“不支持”(Not supported),这是Zabbix使用过程中最多的问题。

所谓Not supported,就是Server在获取某个监控项的值时,Agent返回了错误或者根本没有这个key。点开监控项的“最后一次数据”或者最近的“问题”,通常会有具体的错误信息,比如Cannot obtain item value,或者更详细的zabbix_agentd [10050]: Check of parameter ... failed。

最常见的场景是自定义key写错了。Zabbix自定义key的格式是key[参数1,参数2],在Agent配置文件里用UserParameter定义:

UserParameter=mytask.check,/usr/local/bin/check_task.sh

然后前端监控项写mytask.check。问题出在几个地方:

第一,Agent配置改了有没有重启?systemctl restart zabbix-agent必须执行,很多人改完配置不重启,怎么折腾都是Not supported。第二,脚本路径对不对?UserParameter定义的是绝对路径,脚本的可执行权限有没有?chmod +x漏掉的话,脚本根本跑不起来。第三,脚本是否依赖了环境变量?Agent跑脚本是在非登录环境下,脚本里如果用了source ~/.bashrc或者某个只有登录用户才有的环境变量,执行就会失败。这个坑我踩过很多次,解决方法是脚本开头写全/usr/bin/之类的绝对路径,并且不依赖当前Shell环境变量。

内建监控项Not supported也有规律:

  • agent.pingNot supported:说明Agent进程挂了或者端口不通,先重启Agent。
  • system.cpu.load这类内建项也Not supported:大概率是Agent版本和Server版本差太多,比如Server是7.0,Agent是4.0,内建key的格式新版改了,旧Agent不认识。
  • vfs.fs.size[/]获取不到:多半是权限问题,某些系统需要Agent以root运行才能读取完整的文件系统信息。

实操心得:排查Not supported问题,永远先看监控项最近一次的“错误信息”,Zabbix会把失败原因写在里面。不要猜,不要凭经验,每次都直接点进去看,基本问题就在错误信息里写得明明白白。

2.3 SNMP设备监控超时或获取不到数据

如果监控的是交换机、路由器、防火墙这类设备,走的是SNMP协议。最常见的报错是Timeout while connecting to 192.168.1.1:161或者No Such Instance currently exists at this OID。

超时的原因有四种可能。第一种,设备的SNMP服务没开,或者Community String写错了。Zabbix前端里主机类型要选择SNMP,并填对Community,比如public,另外要注意SNMP版本选择v2c还是v3,写错了也会超时。第二种,防火墙拦了UDP 161端口。注意防火墙放行时要指定UDP协议,只放TCP是不行的:

firewall-cmd --permanent --add-port=161/udp firewall-cmd --reload

第三种,监控项的OID写错了。先在服务器上手动用snmpwalk验证:

snmpwalk -v 2c -c public 192.168.1.1 .1.3.6.1.2.1.1.1

如果手动能取到值,Zabbix里配置却超时,那就是监控项的参数问题。

第四种,某些设备不走标准MIB,厂商自定义的OID需要用snmpget验证。比如华为、H3C的设备,CPU和内存的OID跟标准MIB不一样,直接用标准模板会匹配不到。

2.4 主动模式和被动模式的报错差异

Zabbix Agent有主动、被动两种模式。被动模式是Server去连Agent的10050端口,主动模式是Agent周期性地去Server的10051端口拉取监控项列表并上报数据。

被动模式出问题,上面的排查都覆盖了。主动模式容易出的报错是:Agent日志里反复出现no server或connection refused。这通常意味着Agent配置里的ServerActive没有指向Server端地址,或者Server端的10051端口没放行。

还有一种是主动模式下监控项能取到数据,但主机状态依然显示不可达。这个要分几个层面看:主动模式下,Agent是主动上报数据,所以主机网络可达性检查(icmp ping)依然是Server独立执行的。如果主机禁ping,状态就会显示红色,但监控数据是正常的。解决办法是在前端主机配置里把“状态”和“可用性”分开判断,或者主机配置里把这个IP的ICMP检查换成Agent ping(agent.ping)。

3. 监控数据异常与数据库维护

数据获取正常了,接下来就是长期运维的事情。Zabbix跑久了,数据库会变大,监控项可能出现数据空洞,图表偶尔会断线。这些问题不处理,起初只是数据不好看,时间长了整个监控平台可能直接崩掉。

3.1 监控数据断断续续或历史数据丢失

监控图表上数据时不时出现空白,或者历史记录今天存在明天没有,这通常是两类原因。

第一类,Agent主动模式下Server端处理能力不足。当监控的主机数量超过500台,或者监控项总数超过2万,默认配置可能扛不住。Zabbix Server的日志里会出现history syncer相关的耗时过高,或者preprocessing worker繁忙。这时候需要调大 Zabbix Server 的StartPollers、StartPollersUnreachable、StartTrappers参数,并合理设置CacheSize。这些参数调整后要重启Server才生效:

StartPollers=160 StartPollersUnreachable=40 StartTrappers=20 CacheSize=128M

第二类,数据库的InnoDB缓冲池太小。Zabbix对MySQL的压力大头在写入,如果innodb_buffer_pool_size只有默认的128M,数据量大一点就频繁刷盘,导致写入延迟,图表就会出现空洞。在/etc/my.cnf.d/zabbix.cnf里配置:

[mysqld] innodb_buffer_pool_size=2G innodb_flush_log_at_trx_commit=2 sync_binlog=0

注意innodb_flush_log_at_trx_commit=2牺牲了极小的数据安全性换取了大幅度的写入性能提升,对监控数据来说完全够用。这套配置改完重启MySQL,图表断线的现象会明显改善。

3.2 MySQL表碎片膨胀与housekeeper失效

Zabbix跑几个月之后,MySQL里的history和trends表会变得非常庞大,即使设置过历史数据保留时间,数据也没被及时清理。这通常不是Zabbix的bug,而是MySQL的delete操作留下了大量碎片。

Zabbix自带的housekeeper进程在Server的配置里控制:

HousekeepingFrequency=1 MaxHousekeeperDelete=5000

但housekeeper再勤劳,MySQL表碎片该整理还是要整理。长期运行的监控库,建议定期执行:

OPTIMIZE TABLE history_log; OPTIMIZE TABLE history_str; OPTIMIZE TABLE history_text; OPTIMIZE TABLE history_uint; OPTIMIZE TABLE trends_uint;

这些表都很大,执行时间会很长,建议放在凌晨低峰期跑,而且一定是针对InnoDB表,MyISAM表在OPTIMIZE期间会锁表。

注意:如果history表已经非常大(几十GB),直接执行OPTIMIZE会带来巨大的IO压力,建议分两步:第一步先删除过期数据,第二步再执行OPTIMIZE。不要同时对所有大表操作,一张一张来。

3.3 磁盘空间被监控数据塞爆

Zabbix的数据增长速度是很多运维没预料到的。一台主机几十个监控项,每30秒采集一个值,一天就是几万条记录。如果监控的主机多、保留时间长,磁盘空间很快告急。

判断是不是Zabbix数据占满磁盘,用:

du -sh /var/lib/mysql/*

如果history相关表占了几十个G,说明保留周期设置太长或者采集频率太高。解决办法是调整前端“管理-常规-历史记录保留时间”,把历史数据从默认的90天缩减到30天,趋势数据可以保留365天不动。趋势数据是聚合过的,占空间小得多。

另外要养成习惯,把MySQL的数据目录单独挂载到大容量磁盘,别跟系统盘放在一起。Zabbix Server日志(/var/log/zabbix/)在调试模式下也会暴涨,调试完记得把DebugLevel改回3,我之前调试问题后忘了改回来,150G日志把磁盘写满了,差点把整个系统搞崩。

3.4 时区导致监控数据时间轴偏移

前面提到过PHP的时区问题,但如果你用的是Docker方式部署,时区问题还有另一层坑。Zabbix Server容器默认是UTC时区,即使前端页面显示的是北京时间,数据写入数据库的时间戳依然是UTC。排查这个问题的表现是:告警时间和实际时间差了8小时,图表横轴的时间也偏移。

Docker部署时,在docker-compose里设置环境变量:

environment: - PHP_TZ=Asia/Shanghai - TZ=Asia/Shanghai

同时确保宿主机的/etc/localtime正确挂载进容器:

volumes: - /etc/localtime:/etc/localtime:ro - /etc/timezone:/etc/timezone:ro

改完重建容器,然后到前端确认右上角用户设置里的时区也改成Asia/Shanghai。这一层是独立的,用户设置默认可能是UTC,需要单独改。

4. 告警通知联动的排错经验

Zabbix报警如果不能及时推出去,监控系统等于白装。很多公司用钉钉、企业微信或者邮件接收告警,这部分配置虽然有文档,但实际踩坑率极高。尤其是7.0版本之后,告警媒介的实现方式变化不小,按老教程配置就很容易出问题。

4.1 钉钉机器人收不到告警

Zabbix 7.0开始,官方推荐用Webhook方式来对接钉钉。用老版本的脚本方式(alertscripts里调python脚本)在新版本里还能用,但已经不是最佳实践。

最常见的“收不到告警”问题出现在自定义Webhook脚本的场景。如果你的告警动作配置正确、问题也触发了,但钉钉群就是没消息,按这个顺序排查:

第一,看Zabbix Server的告警日志,定位是否执行了脚本、执行是否报错。日志路径/var/log/zabbix/zabbix_server.log,搜关键字alert或escalator,会有很详细的记录。

第二,钉钉自定义机器人的安全设置。钉钉群里添加自定义机器人时,可以选择“自定义关键词”、“加签”和“IP地址段”三种安全校验方式。Zabbix的默认Webhook脚本只支持加签方式,而且需要把密钥填到Zabbix的媒介配置里。如果钉钉那边选了自定义关键词,你的消息内容里没包含这个关键词,消息就会被钉钉拦截。我遇到过一个人,钉钉设置的是关键词“告警”,但Zabbix发出的消息是纯英文和数字,没有“告警”二字,结果消息全被吞了。

第三,出方向网络问题。Zabbix Server必须能访问到钉钉的开放平台API。如果服务器在专线内网,外网访问受限,Webhook请求发出去了但没回包,脚本在执行时表现为“无响应但未报错”。测试方法:

curl -X POST -H "Content-Type: application/json" \ -d '{"msgtype": "text", "text": {"content": "测试"}}' \ "你的钉钉机器人WebhookURL"

如果curl也没反应,那就是网络层面的问题,跟Zabbix无关。想办法通过代理或者HTTP代理放行钉钉API的访问。

4.2 告警脚本执行成功但消息内容为空

钉钉消息能到,但内容是一堆空变量或者乱码,多半是告警脚本里引用的宏没有在Zabbix动作中正确传递。Zabbix的告警消息模板里有很多内置宏,比如{ALERT.SUBJECT}、{ALERT.MESSAGE}、{ITEM.NAME}、{ITEM.LASTVALUE}等。

在“管理-告警媒介类型-钉钉-消息模板”里,要确保消息模板的“事件标题”和“事件内容”两个部分都填内容,而且要用正确的大括号宏格式。有个经典Bug:Zabbix 6.0之后,动作里的“默认标题”如果为空,Webhook脚本收到的就是空值,钉钉群自然显示空白。解决办法是手动在消息模板里写完整内容:

主机:{HOST.NAME} 告警:{TRIGGER.NAME} 状态:{TRIGGER.STATUS} 时间:{DATE} {TIME} 当前值:{ITEM.LASTVALUE}

另外,钉钉的markdown消息对空格和换行敏感。如果脚本里用的是markdown格式,要检查消息内容里是否包含了不合法的制表符,会被钉钉解析成特殊结构。遇到这种情况,把消息格式改成text试试,能定位是内容问题还是格式问题。

4.3 邮件告警发不出去

邮件告警是Zabbix最基础的告警方式,但也是最让人头疼的。大部分Zabbix Server部署后没有本地的邮件服务(sendmail/postfix没装),告警脚本就报错sendmail: command not found。

解决方案是使用外部SMTP服务器,比如公司的企业邮箱SMTP,或者用QQ邮箱、163邮箱的SMTP授权码。Zabbix 6.0以上版本自带了SMTP媒介,不需要额外装sendmail。“管理-告警媒介类型-电子邮件”里配置SMTP服务器、端口、TLS方式和账号密码即可。

如果配置了SMTP还是发不出去,最常见的错误是525/535这类认证失败。原因是现在这些邮箱服务商都要求使用“授权码”而不是直接使用登录密码。你需要去邮箱设置里开启SMTP服务,获取一串授权码,填到Zabbix里。这个问题在163和QQ邮箱上极其常见,几乎每一个因为我帮过的同事都会在这里卡住。

还有一个小细节:SMTP HELO字段不要留空,填一个合法的域名,有些服务器会因为HELO信息不合法而拒绝连接。比如填zabbix.yourdomain.com。

5. 常见问题排查速查表

到这里,我把Zabbix安装、配置、使用中遇到的高频报错都拆解了一遍。为了方便你以后排错,我把问题的现象、可能原因、解决思路做成一个速查表,遇到问题先来这里对照。

报错现象可能原因快速排查方法
Access denied for user 'zabbix'MySQL用户授权、密码错误、SELinux拦截手动用mysql命令登录验证,再看zabbix_server.conf,最后查SELinux日志
前端页面404Nginx/Apache的root路径或PHP解析配置不对检查Web服务器配置,确认root指向/usr/share/zabbix
主机状态灰色Agent未连上、主机名不一致telnet 10050端口,确认Agent配置中的Hostname与前端的Host name一致
监控项Not supported自定义key错误、Agent未重启、版本不兼容点开监控项查看具体错误信息,从Agent日志倒着查
SNMP超时Community错误、UDP端口被墙、OID不匹配用snmpwalk手动验证OID是否能取到值
告警脚本执行失败Webhook配置错误、网络不通、钉钉安全设置不匹配用curl测试webhook接口,修复后再检查Zabbix告警日志
数据空洞Poller数量不够、数据库写入瓶颈调整StartPollers参数,优化MySQL的InnoDB配置
时间偏移8小时PHP时区、Server容器时区、前端用户时区三层时区设置逐一检查
历史数据不清理housekeeper效率低、表碎片调整HousekeepingFrequency,定期OPTIMIZE大表
邮件发不出去没有本地MTA、SMTP认证失败、HELO缺失配置外部SMTP,使用授权码,检查SMTP端口和认证方式

6. 最后分享一点个人建议

我处理Zabbix报错的经验里,有一条最值钱:永远先看日志。不管是/var/log/zabbix/zabbix_server.log、/var/log/zabbix/zabbix_agentd.log还是MySQL的错误日志,报错信息永远比前端页面的提示更具体、更真实。Zabbix前端有时候只显示一个笼统的状态,但日志里已经把根因写在第一行了。

另一个建议是,如果你在Zabbix 6.x和7.x之间版本跨度比较大,很多旧教程里的配置就不再适用了。7.0之后媒介设置、模板机制、Agent配置文件都有些变化,遇到问题先确认自己的版本,再针对性搜索,能少走很多弯路。

这套报错集锦是基于我自己维护多套Zabbix监控环境的实际经验整理的,没有覆盖你遇到的每一个问题(毕竟Zabbix的报错形态实在太多),但核心排查思路是通用的:先确认链路通不通,再看配置对不对,最后查权限和版本兼容性。按这个顺序来,绝大多数问题都能在半小时内定位到根因。

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

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

立即咨询