很多企业都用Nagios做监控,覆盖服务器、应用、数据库的状态,但很少有人关注Nagios自己会不会挂。比如前阵子接触的一家游戏公司,用Nagios监控几十台服务器,某天突然发现Nagios页面打不开,所有监控数据都断了,折腾半天才找到是Nagios的核心进程因为某个自定义插件的死循环崩溃了,而且崩溃后没有任何告警,运维过了两天才发现,那段时间服务器的异常完全没被监控,差点影响到玩家的游戏体验。这就是因为没给Nagios做自监控,核心监控系统本身成了监控盲区。
一、为什么要给Nagios做自监控?
1.1 实际应用场景
Nagios作为整个运维体系的核心,一旦出现静默故障,后果非常严重。常见的故障场景包括:核心进程因自定义插件的死循环占用100%CPU,此时Web页面仍能加载但无法处理监控任务;进程直接退出变成僵尸状态,ps命令能看到进程但无法响应请求;配置文件被误改导致服务启动失败,运维还以为Nagios在正常运行。这些情况如果没有自监控,就会出现监控空白,无法及时发现业务的异常。
1.2 方案优缺点分析
给Nagios做自监控的优点很明显:第一是补全监控盲区,把核心监控系统纳入监控范围,避免依赖第三方监控;第二是门槛极低,用系统自带的Shell脚本和crontab就能实现,不需要额外安装复杂工具,运维人员不用学习新技术;第三是响应及时,定时检查的机制能在几分钟内发现异常,比手动检查效率高很多。 缺点也需要注意:一是依赖系统的定时任务和邮件服务,如果系统本身崩溃,这个自监控方案也会失效;二是脚本需要根据实际环境调整,比如Nagios的进程名、配置文件路径,要是环境变化了需要同步修改脚本。
1.3 关键注意事项
最核心的注意点是:绝对不能让Nagios本身接收这个自监控的告警。很多运维习惯把所有告警都配置在Nagios的联系人里,但如果Nagios自己崩溃了,那告警也发不出去。应该把告警直接推送到运维的手机短信、企业微信或者钉钉,用独立的通知渠道,不依赖Nagios本身。另外,脚本要放在自己可控的路径,权限设置为755,防止被篡改,导致监控失效。
二、怎么实现Nagios自监控?
2.1 确定要监控的核心指标
不能只监控Nagios进程是否存在,要覆盖三个关键维度:第一是主进程的真实状态,排除僵尸进程(Z状态);第二是Nagios的Web管理页面是否能正常访问,确保运维能看到监控数据;第三是Nagios配置文件是否合法,防止误改导致服务无法启动。
2.2 编写Shell自监控脚本(技术栈:Shell)
这个脚本要覆盖上述三个指标,带详细注释,方便根据自己的环境修改:
#!/bin/bash
# Nagios自监控脚本:监控Nagios核心状态,避免监控系统静默崩溃
# 配置项:根据实际环境修改以下参数
NAGIOS_PROC_NAME="nagios" # Nagios核心进程名,部分系统是nagios3
NAGIOS_WEB_PORT=80 # Nagios Web页面端口,HTTPS的话改为443
NAGIOS_CFG_PATH="/etc/nagios/nagios.cfg" # Nagios主配置文件路径
ALERT_RECEIVER="ops-alert@example.com" # 告警接收邮箱
LOG_FILE="/var/log/nagios_self_monitor.log" # 监控日志路径
# 第一步:检查Nagios主进程是否正常运行(排除僵尸进程)
echo "$(date '+%Y-%m-%d %H:%M:%S') 开始Nagios自监控检查" >> $LOG_FILE
# 查找所有Nagios进程,排除grep自身
NAGIOS_PIDS=$(pgrep -f $NAGIOS_PROC_NAME | grep -v grep)
if [ -z "$NAGIOS_PIDS" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') [FAIL] 未找到Nagios进程" >> $LOG_FILE
# 发送告警(系统已配置sendmail)
echo -e "Subject: Nagios自监控告警 - 进程崩溃\n\nNagios核心进程已不存在,监控系统已失效,请立即处理!" | sendmail -t $ALERT_RECEIVER
exit 1
fi
# 检查进程是否为僵尸状态,确保是正常运行的进程
for pid in $NAGIOS_PIDS; do
PROC_STATE=$(ps -p $pid -o stat --no-headers)
if [[ $PROC_STATE == *"Z"* ]]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') [FAIL] Nagios进程变成僵尸状态,PID: $pid" >> $LOG_FILE
echo -e "Subject: Nagios自监控告警 - 僵尸进程\n\nNagios出现僵尸进程,无法处理监控任务,请立即恢复服务!" | sendmail -t $ALERT_RECEIVER
exit 1
fi
done
# 第二步:检查Nagios Web页面是否可达
curl -s http://localhost:$NAGIOS_WEB_PORT/nagios > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') [FAIL] Nagios Web页面无法访问" >> $LOG_FILE
echo -e "Subject: Nagios自监控告警 - Web不可达\n\nNagios Web管理页面无法打开,服务异常,请排查!" | sendmail -t $ALERT_RECEIVER
exit 1
fi
# 第三步:检查Nagios配置文件是否合法
nagios -v $NAGIOS_CFG_PATH > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') [FAIL] Nagios配置文件不合法" >> $LOG_FILE
echo -e "Subject: Nagios自监控告警 - 配置错误\n\nNagios配置文件验证失败,可能是误改导致,请检查配置!" | sendmail -t $ALERT_RECEIVER
exit 1
fi
# 所有检查通过,记录正常日志
echo "$(date '+%Y-%m-%d %H:%M:%S') [OK] Nagios所有核心指标正常" >> $LOG_FILE
exit 0
2.3 加入定时任务触发
用Linux自带的crontab定时工具,每5分钟执行一次脚本,确保异常被及时发现。打开当前用户的crontab配置:
# 编辑crontab配置
crontab -e
# 添加以下内容,每5分钟执行自监控脚本,日志追加记录
*/5 * * * * /usr/local/bin/nagios_self_monitor.sh >> /var/log/nagios_self_monitor.log 2>&1
三、方案落地后的实际效果
某电商公司落地这个方案后,遇到过两次核心异常:一次是Nagios的自定义监控插件出现死循环,导致核心进程占用满CPU,脚本在5分钟内就发送了告警,运维2分钟就恢复了服务,监控只断了7分钟,没有影响业务;另一次是运维人员误改了Nagios的配置文件,脚本的配置检查步骤在1分钟内发现了错误,避免了Nagios服务启动失败导致的监控空白,减少了业务风险。
四、总结
Nagios作为核心监控工具,它的稳定性直接决定了整个运维体系的可靠性,给它做自监控不是多此一举,而是对监控体系的必要补全。这个方案用最简单的Shell脚本就能实现,不需要额外的复杂工具,运维人员可以快速落地,而且效果显著,能有效避免因核心监控系统崩溃导致的业务监控盲区,提升运维的响应效率和业务的稳定性。
评论
围绕“针对Nagios监控自身的死循环问题定义自监控项目来防止监控系统进程静默崩溃”参与讨论