真正可用的监控告警脚本需组合检查进程、端口、业务响应三者,用pgrep/ss/curl验证;通过/tmp文件实现告警冷却与恢复通知;固定路径、显式path、完整日志重定向、专用用户运行,并用flock防并发。

Linux 上写一个能真正用起来的监控告警脚本,核心不是语法多漂亮,而是得扛住日志轮转、进程重启、网络抖动、权限变化这四类真实干扰。
怎么判断服务是否真的挂了,而不是暂时没响应
只用 ps aux | grep nginx 或 curl -I http://localhost:80 容易误报:进程还在但 worker 崩了,或者 HTTP 返回 502 却被当成“通了”。必须组合检查。
- 先查进程存活:
pgrep -f "nginx: master process"(比grep更准,避免匹配到日志或命令行参数) - 再查端口监听:
ss -tln | grep ":80\b"(\b防止匹配到 8080) - 最后做轻量级业务探测:
curl -s --connect-timeout 3 -m 5 http://127.0.0.1/health | grep "ok"(加超时,且验证响应内容) - 三者全通过才算健康;任一失败,才触发告警逻辑
告警发出去就完事?得防重复轰炸和静默失效
脚本每分钟跑一次,但服务故障往往持续几十分钟——如果每次都发邮件,运维会直接屏蔽邮箱。必须做状态记忆和冷却控制。
- 用一个临时文件记录上次告警时间:
/tmp/nginx_alert_last_sent,每次发告警前读它,距今不足 15 分钟就跳过 - 恢复通知也得发:
if [ "$last_state" = "down" ] && [ "$current_state" = "up" ]; then echo "Nginx recovered at $(date)" | mail -s "✅ Recovered" admin@example.com; fi - 别依赖
mail命令:很多最小化系统没装mailx,改用echo ... | sendmail -t或直接调用企业微信 webhook(用curl -X POST)更稳
脚本放哪儿、谁来跑、权限够不够
写完脚本不等于能长期运行。crontab 权限、PATH 环境变量、输出重定向,三处最容易出 silent failure。
- 脚本路径固定放
/opt/monitor/check_nginx.sh,避免用~/或相对路径 - crontab 里显式声明 PATH:
PATH=/usr/local/bin:/usr/bin:/bin,否则pgrep或ss可能找不到 - 所有输出重定向到日志:
/opt/monitor/check_nginx.sh >> /var/log/monitor/nginx_check.log 2>&1,不加这句,错误全丢进黑洞 - 运行用户用
root或专用monitor用户,别用个人账号——密码改了或家目录删了,脚本就停摆
最常被忽略的是信号处理和锁机制:两个实例同时跑,可能并发发告警;kill 脚本时没清理临时文件,下次启动就误判历史状态。哪怕只是加个 flock -n /tmp/check_nginx.lock -c "...",也比裸奔强得多。










