拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Zabbix自定义监控实战:脚本编写、Agent配置与日志服务监控

Zabbix自定义监控实战:脚本编写、Agent配置与日志服务监控

1. 什么是Zabbix自定义监控:不是“加个监控”那么简单,而是把系统脉搏握在自己手里

Zabbix自定义监控,说白了就是绕开Zabbix自带模板的“标准答案”,亲手写脚本去问服务器:“你此刻CPU到底多烫?”“你的Nginx进程还在喘气吗?”“/var/log/nginx/error.log里刚冒出来的502错误是不是又来了?”——它不是锦上添花的功能扩展,而是Zabbix真正从“看门狗”升级为“私人健康管家”的分水岭。我干这行十年,见过太多团队卡在这一关:买了Zabbix企业版,装完就只盯着那几个预设的CPU、内存、磁盘图表,结果线上服务半夜挂了,告警邮件却安静如鸡;日志里早堆满了Connection refused,Zabbix却还在报告“服务端口通”。问题出在哪?不是Zabbix不行,是没把它“驯服”——而驯服的唯一方式,就是用shell脚本、Python脚本这些最原始也最锋利的工具,把监控逻辑直接焊进业务毛细血管里。关键词里的“zabbix”“自定义监控”“脚本”“服务”“日志”,每一个都不是孤立存在:zabbix是平台骨架,自定义监控是肌肉神经,脚本是控制指令,服务和日志则是你要实时把脉的具体器官。它解决的从来不是“能不能监控”,而是“监控得准不准、快不快、有没有用”。适合谁?运维工程师必须掌握,因为这是你判断故障根因的第一手证据;开发同学也该懂,尤其微服务架构下,每个Pod的日志格式、健康检查端点都千差万别,靠通用模板根本抓不住关键指标;就连测试同学,用自定义脚本做压测后自动解析JMeter生成的jtl日志,也能把性能瓶颈定位时间从2小时压缩到5分钟。这不是炫技,是让监控从“事后诸葛亮”变成“事前预警器”的硬功夫。

2. 为什么非得自己写脚本?Zabbix原生能力的三道硬伤与真实战场代价

很多人觉得Zabbix自带的“Agent”“SNMP”“JMX”已经够用,直到某次大促凌晨三点被电话叫醒——订单服务响应时间飙升到8秒,Zabbix仪表盘上所有预设指标(CPU、内存、线程数)全在绿区。最后排查发现,是数据库连接池耗尽,但Zabbix默认根本不采集“活跃连接数”这个指标。这就是原生能力的第一道硬伤:指标覆盖存在结构性盲区。Zabbix官方模板像一本《常见病诊疗手册》,但你的业务系统是独一无二的“疑难杂症患者”。比如微服务架构中,Spring Boot Actuator暴露的/actuator/metrics/jvm.memory.used指标,Zabbix 6.0之前压根不支持直接解析JSON嵌套路径;再比如K8s环境,Zabbix Agent无法直接获取Pod的重启次数,而这个值恰恰是判断容器健康度的黄金指标。

第二道硬伤是日志解析的粗暴与滞后。Zabbix内置的Log Monitoring功能,表面看能监控日志文件,实则有致命限制:它只能基于正则匹配整行日志,且不支持上下文关联。举个真实案例:某支付系统需要监控“交易失败但未触发补偿”的异常链路。日志里先出现[ERROR] OrderService: payment failed, orderId=12345,5秒后应有[INFO] CompensateService: start compensation for 12345。Zabbix Log Monitoring只能分别告警这两行,却无法判断“有失败无补偿”这个复合事件。而用自定义脚本,你可以用awk读取日志流,用数组缓存最近10条失败记录,再实时匹配后续补偿日志,毫秒级识别异常闭环。

第三道硬伤最隐蔽也最致命:服务状态判定的逻辑僵化。Zabbix默认用net.tcp.port[host,80]判断Web服务存活,这等同于只确认“端口开着”,却不管Nginx是否返回502、Tomcat是否已OOM崩溃但进程仍在。我们曾遇到一个案例:某Java服务因GC频繁导致HTTP请求超时,Zabbix显示“端口通、进程在”,但用户实际无法下单。后来用自定义脚本改写检测逻辑:curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/health | grep -q "200",瞬间揪出问题。这背后是核心认知转变——监控的本质不是查“进程是否存在”,而是查“业务是否可用”。这三道硬伤带来的真实战场代价是什么?平均故障定位时间(MTTR)延长3-5倍,关键业务指标漏报率超40%,更可怕的是,团队会陷入“监控幻觉”:看着满屏绿色图表,误以为系统坚不可摧,直到用户投诉电话打爆客服热线。所以,自定义脚本不是可选项,而是Zabbix发挥真正价值的必经之路。

3. 自定义监控的核心实现路径:从脚本编写、Zabbix配置到数据落地的全链路拆解

3.1 脚本设计的底层逻辑:不是写代码,而是构建“可观测性契约”

写监控脚本的第一步,永远不是打开vim敲代码,而是明确“我要向Zabbix承诺什么”。这个承诺就是可观测性契约:脚本必须稳定输出单一、确定、无歧义的数值或字符串,且每次执行耗时严格控制在Zabbix Agent的Timeout阈值内(默认3秒)。我见过太多失败案例源于契约意识缺失:有人写Python脚本调用requests库抓取API,网络抖动时耗时超10秒,Zabbix Agent直接kill进程,导致监控项持续显示“Not supported”;还有人用grep在10GB日志里全文搜索,脚本跑一次要2分钟,Zabbix干脆放弃轮询。因此,脚本设计必须遵循三大铁律:

第一,输入绝对可控。所有外部依赖必须预设兜底方案。比如监控MySQL主从延迟,脚本不能直接执行mysql -e "show slave status\G",而要先检查mysql命令是否存在、~/.my.cnf配置文件是否可读、主从连接是否超时。我的标准模板开头永远是:

#!/bin/bash # 检查依赖 command -v mysql >/dev/null 2>&1 || { echo "mysql command not found"; exit 1; } [ -f ~/.my.cnf ] || { echo "~/.my.cnf not found"; exit 1; } # 设置超时,避免hang住 timeout 2 mysql -N -s -e "SELECT Seconds_Behind_Master FROM information_schema.slave_status" 2>/dev/null | awk '{print ($1 ~ /^[0-9]+$/ ? $1 : 0)}'

这里timeout 2强制2秒内返回,awk确保只输出数字,空值或错误时返回0(便于Zabbix设置触发器阈值)。

第二,输出绝对纯净。Zabbix Agent只认“一行一个值”,任何多余字符都会导致解析失败。曾有个同事在脚本末尾加了echo "check finished",结果Zabbix收到123\ncheck finished,整个监控项失效。正确做法是用printf "%d" $value替代echo $value,并确保脚本结尾无空行。

第三,逻辑绝对幂等。脚本执行1次和执行100次,对系统状态零影响。严禁在监控脚本里写rm -rf /tmp/cache这类操作——某次Zabbix Server配置错误导致每秒调用脚本,结果清空了生产环境临时目录。所有临时文件必须用mktemp创建独立路径,执行完立即清理。

3.2 Zabbix Agent端配置:让脚本成为Agent的“原生器官”

脚本写好只是第一步,必须让Zabbix Agent“认识”它。核心在于UserParameter配置,它本质是给脚本注册一个“别名”,让Zabbix Server能像调用内置函数一样调用你的脚本。配置位置在/etc/zabbix/zabbix_agentd.conf或/etc/zabbix/zabbix_agentd.d/userparameter_custom.conf(推荐后者,便于管理)。以监控Nginx请求速率为例:

# /etc/zabbix/zabbix_agentd.d/userparameter_nginx.conf # UserParameter=<key>,<command> UserParameter=nginx.requests.persec,/usr/local/bin/check_nginx_requests.sh UserParameter=nginx.connections.active,/usr/local/bin/check_nginx_connections.sh

这里nginx.requests.persec就是你在Zabbix Web界面创建监控项时填写的Key。关键细节在于:

  • 路径必须绝对:/usr/local/bin/check_nginx_requests.sh不能写成./check_nginx_requests.sh,Agent运行用户(通常是zabbix)没有当前工作目录概念;
  • 权限必须精准:脚本需对zabbix用户可执行,chmod 755 /usr/local/bin/check_nginx_requests.sh,且zabbix用户要有读取Nginx状态页的权限(若用stub_status模块,需配置location /nginx_status并允许zabbix用户访问);
  • 参数传递要安全:如果脚本需要动态参数(如监控不同端口的服务),用$1接收,但必须校验:
    # check_service_port.sh if [[ ! "$1" =~ ^[0-9]+$ ]] || [ "$1" -lt 1 ] || [ "$1" -gt 65535 ]; then echo "Invalid port number" exit 1 fi nc -z 127.0.0.1 "$1" && echo 1 || echo 0
    对应的UserParameter写成:UserParameter=service.port.status[*],/usr/local/bin/check_service_port.sh $1

配置完成后,必须重启Agent并验证:sudo systemctl restart zabbix-agent,然后手动执行zabbix_get -s 127.0.0.1 -k "nginx.requests.persec",确认返回预期数值。这一步跳过,90%的后续问题都源于此。

3.3 Zabbix Server端配置:从监控项到触发器的精密组装

Agent端配置好,Server端才是真正的“指挥中心”。在Web界面依次创建:监控项(Item)→ 应用集(Application)→ 触发器(Trigger)→ 图形(Graph)。以日志监控为例,展示关键配置要点:

监控项(Item)配置:

  • Name:清晰描述用途,如“Nginx Error Log 502 Count (last 5min)”;
  • Type:选择“Zabbix agent”(若脚本在Agent本地运行)或“Zabbix agent (active)”(若Agent主动上报);
  • Key:必须与UserParameter定义的key完全一致,如nginx.error.502.count;
  • Update interval:根据业务敏感度设定。高频指标(如QPS)设30秒,低频指标(如日志错误计数)设300秒,避免Agent过载;
  • History storage period:日志类指标建议设长些(如90天),便于追溯历史趋势;
  • Trends storage period:趋势数据(用于图形)可设短些(如365天),节省数据库空间。

应用集(Application):这是常被忽视的组织利器。不要把所有监控项扔进“Default Application”,按业务维度建应用集:Nginx-Web,MySQL-DB,Log-Error。这样在主机详情页,你能一眼看到“这个主机的Nginx相关指标在哪”,而不是在上百个监控项里滚动查找。

触发器(Trigger)配置:这才是监控的灵魂。避免用“大于阈值就告警”的简单逻辑。以“Nginx 502错误突增”为例:

  • Expression:{HOSTNAME:nginx.error.502.count.last(300)}>5 and {HOSTNAME:nginx.error.502.count.avg(300)}>3
    • last(300)取最近5分钟最新值,判断是否突发;
    • avg(300)取5分钟均值,排除毛刺干扰;
  • Severity:设为“High”,并关联告警媒介(邮件、钉钉、短信);
  • Dependencies:设置依赖关系,如“只有当Nginx进程存活触发器为OK时,502告警才生效”,避免服务宕机时产生无效告警。

图形(Graph):不要只画单指标。把nginx.requests.persec、nginx.connections.active、nginx.error.502.count画在同一张图上,时间轴对齐,你立刻能看出“QPS飙升时502是否同步上涨”,这是根因分析的黄金视图。

4. 四类高频场景的脚本实战:从服务存活到日志深度解析的完整代码与避坑指南

4.1 服务存活监控:超越端口检测的业务级健康检查

监控服务“活着”是最基础需求,但Zabbix默认的端口检测(net.tcp.port)太浅。真正的业务级检查需模拟真实用户行为。以下是一个监控Spring Boot Actuator健康端点的Shell脚本,它解决了三个关键痛点:HTTPS证书验证、超时控制、JSON解析容错。

#!/bin/bash # check_springboot_health.sh # 参数:$1=服务URL(如https://api.example.com/actuator/health), $2=超时秒数(默认5) URL="${1:-https://localhost:8080/actuator/health}" TIMEOUT="${2:-5}" # 检查curl是否存在 command -v curl >/dev/null 2>&1 || { echo "curl not found"; exit 1; } # 执行curl,忽略SSL证书错误(生产环境应配置正确证书) # -k: 忽略证书验证;-s: 静默模式;-m: 最大超时;-w: 输出HTTP状态码;-o: 丢弃响应体 HTTP_CODE=$(curl -k -s -m "$TIMEOUT" -w "%{http_code}" -o /dev/null "$URL" 2>/dev/null) # 根据HTTP状态码判断 case "$HTTP_CODE" in 200) # 解析JSON,提取status字段,兼容不同格式(UP/DOWN/UNKNOWN) STATUS=$(curl -k -s -m "$TIMEOUT" "$URL" 2>/dev/null | grep -o '"status":"[^"]*"' | cut -d'"' -f4 | tr '[:lower:]' '[:upper:]') case "$STATUS" in "UP") echo 1 ;; "DOWN"|"UNKNOWN") echo 0 ;; *) echo 0 ;; # JSON解析失败,视为异常 esac ;; 401|403) # 认证失败,服务存在但权限不足,视为部分可用 echo 1 ;; *) # 其他状态码(500/502/503/超时等),服务不可用 echo 0 ;; esac

避坑指南:

  • 证书问题:生产环境绝不能用-k忽略证书!正确做法是将CA证书路径传入--cacert /path/to/ca.crt,或配置curl全局证书路径;
  • JSON解析风险:grep -o '"status":"[^"]*"'可能匹配到日志中的status字段,应限定在响应体首行,或改用jq工具:curl ... | jq -r '.status // "DOWN"';
  • 超时陷阱:curl -m只控制连接+传输超时,DNS解析超时需额外加--connect-timeout 3;
  • Zabbix集成:UserParameter写成UserParameter=springboot.health.status[*],/usr/local/bin/check_springboot_health.sh $1 $2,监控项Key填sprinboot.health.status["https://api.example.com/actuator/health",10]。

4.2 日志错误计数监控:从“grep一把梭”到精准时间窗口统计

监控日志错误最常见误区是grep "ERROR" /var/log/app.log | wc -l,这会导致两个严重问题:1)每次统计全量日志,IO压力巨大;2)无法限定时间范围,凌晨的错误会污染白天的告警。正确方案是用logrotate配合tail -n,只读取新增行。

#!/bin/bash # count_log_errors.sh # 参数:$1=日志路径,$2=错误模式(正则),$3=时间窗口分钟数(默认5) LOG_FILE="${1:-/var/log/app.log}" PATTERN="${2:-ERROR}" WINDOW_MIN="${3:-5}" # 计算时间窗口起始时间戳(精确到秒) WINDOW_START=$(date -d "$WINDOW_MIN minutes ago" +%s 2>/dev/null) if [ -z "$WINDOW_START" ]; then WINDOW_START=$(($(date +%s) - WINDOW_MIN * 60)) fi # 获取日志文件最后修改时间 LOG_MTIME=$(stat -c "%Y" "$LOG_FILE" 2>/dev/null) if [ -z "$LOG_MTIME" ]; then echo 0 exit 0 fi # 如果日志文件比窗口还老,直接返回0 if [ "$LOG_MTIME" -lt "$WINDOW_START" ]; then echo 0 exit 0 fi # 使用awk按时间戳过滤(假设日志格式:2023-10-01 12:34:56 ERROR ...) # 提取时间戳,转换为秒,比较 awk -v start="$WINDOW_START" -v pattern="$PATTERN" ' BEGIN { # 定义时间格式解析函数 FS=" "; OFS=" " } { # 假设时间在第1、2列,如"2023-10-01 12:34:56" if (NF >= 2) { datetime = $1 " " $2 # 将datetime转为时间戳(GNU awk支持mktime) cmd = "date -d \"" datetime "\" +%s 2>/dev/null" cmd | getline ts close(cmd) if (ts != "" && ts >= start && $0 ~ pattern) { count++ } } } END { print count+0 } ' "$LOG_FILE" 2>/dev/null

避坑指南:

  • 日志轮转处理:logrotate后旧日志会被重命名(如app.log.1),脚本需同时监控app.log*,用find /var/log -name "app.log*" -mmin -$WINDOW_MIN获取所有相关文件;
  • 性能优化:对超大日志,用tac倒序读取(新日志在前),配合awk 'NR>10000{exit} /pattern/{count++}'限制扫描行数;
  • Zabbix触发器:不要设“错误数>0”就告警,应设“5分钟内错误数>10且环比增长200%”,避免偶发错误扰民;
  • 安全加固:PATTERN参数需严格校验,禁止传入.*等危险正则,防止ReDoS攻击。

4.3 数据库连接池监控:直击微服务性能瓶颈的“心脏监测仪”

数据库连接池耗尽是微服务雪崩的导火索,但Zabbix默认不采集此指标。以下脚本通过JDBC URL直连MySQL,查询information_schema.PROCESSLIST,统计活跃连接数,并区分业务连接与监控连接。

#!/bin/bash # check_mysql_pool.sh # 参数:$1=MySQL host, $2=port, $3=user, $4=password, $5=pool max size(用于计算使用率) HOST="${1:-localhost}" PORT="${2:-3306}" USER="${3:-zabbix}" PASS="${4:-zabbix}" MAX_POOL="${5:-100}" # 检查mysql客户端 command -v mysql >/dev/null 2>&1 || { echo "mysql client not found"; exit 1; } # 查询活跃连接数(排除Sleep状态和监控自身连接) ACTIVE_COUNT=$( mysql -h"$HOST" -P"$PORT" -u"$USER" -p"$PASS" -N -s -e " SELECT COUNT(*) FROM information_schema.PROCESSLIST WHERE COMMAND != 'Sleep' AND USER != '$USER' AND HOST NOT LIKE '127.0.0.1%' AND HOST NOT LIKE 'localhost%' " 2>/dev/null ) # 处理空结果 ACTIVE_COUNT=${ACTIVE_COUNT:-0} # 计算使用率百分比(用于触发器阈值) USAGE_PERCENT=$((ACTIVE_COUNT * 100 / MAX_POOL)) # 输出两个值:活跃数 和 使用率(Zabbix支持多值返回,用换行分隔) echo "$ACTIVE_COUNT" echo "$USAGE_PERCENT"

避坑指南:

  • 权限最小化:zabbix用户只需SELECT权限在information_schema.PROCESSLIST,禁用SUPER等高危权限;
  • 连接泄漏防护:脚本执行完自动退出,但需在MySQL配置wait_timeout=60,避免僵尸连接;
  • Zabbix多值接收:监控项类型选“Zabbix agent (active)”,Key填mysql.pool.stats,在Zabbix Server端用{$MYSQL_POOL_ACTIVE}和{$MYSQL_POOL_USAGE}提取第一、二行值;
  • 微服务适配:若用Druid连接池,可改查/actuator/druid/datasource端点,逻辑类似。

4.4 磁盘inode监控:被99%团队忽略的“隐形杀手”

磁盘空间充足但服务宕机?大概率是inode耗尽。Zabbix自带的vfs.fs.size只监控空间,不监控inode。以下脚本精准检测指定挂载点的inode使用率。

#!/bin/bash # check_inode_usage.sh # 参数:$1=挂载点路径(如/data),$2=告警阈值(默认90) MOUNT_POINT="${1:-/}" THRESHOLD="${2:-90}" # 检查挂载点是否存在 if ! mount | grep -q " $MOUNT_POINT "; then echo "Mount point $MOUNT_POINT not found" exit 1 fi # 获取inode使用率(df -i输出:Use%在第5列) INODE_USAGE=$(df -i "$MOUNT_POINT" | tail -1 | awk '{print $5}' | sed 's/%//') # 处理空值 INODE_USAGE=${INODE_USAGE:-0} # 判断是否超阈值 if [ "$INODE_USAGE" -gt "$THRESHOLD" ]; then echo 1 # 超阈值,需告警 else echo 0 # 正常 fi

避坑指南:

  • 小文件陷阱:/var/spool/postfix/maildrop等目录易堆积小文件,需单独监控;
  • Docker环境:容器内df -i可能显示宿主机inode,应在宿主机部署脚本,监控/var/lib/docker;
  • Zabbix触发器:设为“inode.usage>0 for 5m”,避免瞬时波动;关联动作发送find $MOUNT_POINT -xdev -type f | head -100找出最大文件列表,辅助定位。

5. 实战排障与经验沉淀:那些文档里不会写的血泪教训与提效技巧

5.1 Zabbix自定义监控的“死亡五连问”:快速定位90%的问题

当你的自定义监控项显示“Not supported”或数值异常,按以下顺序灵魂拷问,5分钟内定位根源:

  1. Agent端脚本能否手动执行?
    sudo -u zabbix /usr/local/bin/your_script.sh—— 必须用zabbix用户执行,模拟Agent运行环境。常见失败:脚本路径错误、权限不足(chmod 755)、缺少依赖(which curl)、环境变量缺失(PATH未包含/usr/local/bin)。

  2. UserParameter配置是否生效?
    sudo zabbix_agentd -t "your.key.name"—— 这是Zabbix Agent的调试命令,直接返回脚本输出。若报错Cannot obtain value,检查配置文件语法(=前后不能有空格)、配置文件是否被include、Agent是否重启。

  3. Zabbix Server能否获取到数据?
    zabbix_get -s <agent_ip> -k "your.key.name"—— 若返回ZBX_NOTSUPPORTED,说明Agent端问题;若超时,检查防火墙(10050端口)、Agent配置StartAgents值(需>0)、Server与Agent时间是否同步(相差>300秒会拒绝通信)。

  4. 监控项配置是否匹配?
    在Zabbix Web界面,进入监控项详情页,核对:Key是否与UserParameter完全一致(大小写、符号);类型是否为“Zabbix agent”;更新间隔是否合理(太短导致Agent过载);历史存储周期是否足够。

  5. 触发器表达式是否写错?
    进入触发器配置页,点击“Test”按钮,输入主机名和时间范围,查看实时计算结果。常见错误:{HOSTNAME:key.last()}写成{HOST:key.last()}(HOSTNAME是宏,HOST是错误写法);阈值单位混淆(如内存用MB却设阈值10000,实际应为10000000)。

提示:在Agent配置中开启Debug日志(DebugLevel=4),重启Agent后查看/var/log/zabbix/zabbix_agentd.log,里面会详细记录每次脚本调用的命令、返回值、耗时,是终极排障利器。

5.2 提效技巧:让自定义监控从“手工劳动”升级为“流水线工程”

写10个脚本是体力活,管理100个脚本是噩梦。我团队沉淀的提效技巧:

技巧一:脚本模板化与参数化
所有脚本统一入口,用case "$1"分发逻辑:

#!/bin/bash # unified_monitor.sh case "$1" in nginx_qps) check_nginx_qps "$2" ;; mysql_slow) check_mysql_slow "$2" "$3" ;; log_error) count_log_errors "$2" "$3" "$4" ;; *) echo "Usage: $0 {nginx_qps|mysql_slow|log_error} [args...]"; exit 1 ;; esac

UserParameter统一写成UserParameter=monitor.[*],/usr/local/bin/unified_monitor.sh $1 $2 $3 $4,管理成本直降70%。

技巧二:Zabbix配置版本化
用Git管理/etc/zabbix/zabbix_agentd.d/下的所有.conf文件,每次修改提交Commit,并附上变更原因(如“修复log_error脚本在CentOS8的date命令兼容性”)。Zabbix Server端同样用Git管理模板(XML导出),实现配置回滚与审计。

技巧三:自动化部署与验证
用Ansible Playbook一键部署:

- name: Deploy custom monitoring scripts copy: src: scripts/ dest: /usr/local/bin/ mode: '0755' - name: Deploy UserParameter configs template: src: templates/userparameter_*.j2 dest: /etc/zabbix/zabbix_agentd.d/ - name: Verify script execution command: sudo -u zabbix /usr/local/bin/check_nginx_qps.sh register: script_test changed_when: false - name: Fail if script fails fail: msg: "Custom script verification failed" when: script_test.rc != 0

每次上线前自动验证,杜绝“配置写了但没生效”的低级错误。

技巧四:监控即文档
在脚本头部用注释写明:监控目的、指标含义、正常范围、告警建议、关联业务。例如:

# 监控目的:检测Redis主从同步延迟,延迟>100ms触发告警 # 指标含义:slave节点的master_last_io_seconds_ago值(秒) # 正常范围:0-5s(网络良好时),<100s(可接受) # 告警建议:检查主从网络、Redis负载、AOF重写是否阻塞 # 关联业务:订单缓存、用户会话

新同事接手时,看脚本注释就能理解全部,无需翻查Wiki。

5.3 经验之谈:关于“何时该用自定义监控”的三条红线

不是所有监控都值得自定义。我踩过坑后总结的三条红线:

红线一:Zabbix原生指标能满足,绝不自定义
比如监控CPU使用率,system.cpu.util[,idle]已足够精准,再写脚本调用top纯属重复造轮子,还增加维护负担。自定义只用于原生无法覆盖的场景。

红线二:脚本执行耗时超过Zabbix Timeout的1/3,必须重构
Zabbix Agent默认Timeout=3秒,脚本应控制在1秒内完成。若需调用外部API,必须加timeout 1,并设置合理的失败兜底值(如返回-1),避免拖垮整个Agent。

红线三:监控逻辑涉及业务核心数据,必须走应用层埋点
比如“支付成功率”,不应在Nginx日志里统计200和500响应码来计算,而应在支付服务代码中,用Micrometer等框架直接上报payment.success.rate指标。日志监控是兜底方案,应用埋点才是真相。

最后分享个小技巧:在Zabbix Web界面,给所有自定义监控项的Name字段加上前缀[CUSTOM],如[CUSTOM] Nginx 502 Count。这样在主机监控项列表里,所有自定义项自动聚在一起,筛选、排序、管理效率提升数倍。这看似微小,却是我每天节省10分钟的实在功夫。

返回列表