🚀 一键巡检脚本
#!/bin/bash
# patrol.sh — 服务器体检,输出到日志存档
LOG="/var/log/patrol-$(date +%F).log"
{
echo "===== $(date '+%F %T') ====="
echo "--- 负载 ---"; uptime
echo "--- 磁盘 ---"; df -h / | tail -1
echo "--- 内存 ---"; free -m | grep Mem
echo "--- 端口 ---"
for p in 3001 3005 3010; do
printf "port %-5s " "$p"
curl -s -o /dev/null -w "%{http_code}\n" -m 5 "http://127.0.0.1:$p/" || echo FAIL
done
echo "--- 公网入口 ---"
for u in https://example.com/ https://example.com/app/; do
printf "%-40s " "$u"
curl -s -o /dev/null -w "%{http_code} %{time_total}s\n" -m 10 "$u"
done
echo "--- PM2 ---"; pm2 list 2>/dev/null | grep -E "online|stopped|errored"
echo "--- 孤儿进程 ---"
ps -eo pid,ppid,rss,etime,cmd | awk '$2==1 && /node|python/'
echo "--- 重启风暴检测 ---"
for u in $(systemctl list-units --type=service --state=running --no-legend | awk '{print $1}'); do
n=$(systemctl show "$u" -p NRestarts --value 2>/dev/null)
[ -n "$n" ] && [ "$n" -gt 5 ] && echo "⚠️ $u NRestarts=$n"
done
} | tee -a "$LOG"
🔍 为什么需要「静默故障」检测
最贵的故障不是崩溃,是不报错但一直在空转。真实案例:
症状:服务器一切正常,网站能访问,服务不报错
真相:一个 systemd 单元空转了 37 天,重启了 30 万次
发现方式:
systemctl show xxx.service -p NRestarts --value → 308086
journalctl -u xxx.service | grep "Scheduled restart" | wc -l
根因:两个同名单元(系统级 + 用户级)都 enabled,
抢占同一端口失败 → 退出码 78 → 被当成崩溃 → 无限重启
代价:30 万次 × 8 秒 CPU ≈ 27 CPU-天
日志文件占满磁盘 2.2G,syslog 里 36% 是它
结论:这个故障 37 天里没触发任何告警。
「没有告警」≠「没有问题」。
🚨 核心教训:巡检不能只看「服务在不在」,必须看「重启了几次」。NRestarts 这个数字,是照出静默故障的镜子。
🧹 孤儿进程处理
被 kill 的父进程如果留下没退出的子进程,会被 init 收养(PPID=1),继续占内存但没人管:
# 1. 找出所有 PPID=1 的进程(排除正常守护进程)
ps -eo pid,ppid,etime,rss,cmd | awk '$2==1'
# 2. 关键一步:确认它没持监听端口!
ss -lntp | grep
# → 有输出 = 它是真正在服务的,别动
# → 无输出 = 孤儿,可以安全清理
# 3. 清理
kill
⚠️ 铁律:杀进程前必须确认「它没占着监听端口」。孤儿进程常年不清,一个进程泄漏 100MB 很常见。
📊 巡检指标速查表
指标 健康阈值 说明
─────────────────────────────────────────────
负载 1min < CPU 核数 长期 >2 要查
磁盘使用 < 80% 留 20% 缓冲
可用内存 > 10% total 不足会触发 OOM
端口状态 200 / 预期 非 200 立即查
PM2 重启次数 ↺ = 0 持续增长 = 有问题
systemd NRestarts < 10 暴涨 = 重启风暴
孤儿进程 0 个 有则确认后清理
日志增速 稳定 突然暴涨 = 有异常循环
⏰ 定时执行建议
# crontab -e
# 每天凌晨 2 点巡检一次
0 2 * * * /opt/patrol/patrol.sh >/dev/null 2>&1
# 每周日汇总对比
0 3 * * 0 /opt/patrol/weekly-report.sh
💡 经验:巡检结果要「存档 + 可对比」。单次巡检只能看当下,只有形成时间序列,才能发现「缓慢恶化」这类问题。