Linux服务器定时监测服务脚本
这两天我们有个服务出现了很严重的内存泄漏问题,本来按说既然是内存泄漏问题那我们就找到内存泄漏原因然后解决掉就行了,但是因为那个服务不是我写的,然后现在又很忙抽不出那么多时间,所以就先用临时的方法补救一下,写个监测脚本发现不对就自动重启
脚本内容如下(脚本名称:monitor.sh)
注意我这里是根据 CPU 使用率判断的,因为这个服务即使内存泄漏很严重但是服务本身没有挂掉还在运行,只是请求进不去了
下面脚本加了一些内容,因为我发现有的服务器上环境变量不对启动不了 jar 包,还有就是有的程序启动的时候会有一段时间 CPU 占比非常大,所以又加了一个冷却时间,防止一直重启
#!/bin/bashAPP_HOME="/data/application/app"
JAR_NAME="app-1.0.jar"
LOG_FILE="$APP_HOME/monitor.log"
RESTART_RECORD="$APP_HOME/.last_restart_time"# 设置 Java 环境
export JAVA_HOME=/data/midsoftware/ali_jdk_8.16.17
export PATH=$JAVA_HOME/bin:$PATH# 进入应用目录
cd $APP_HOME || { echo "Failed to cd $APP_HOME"; exit 1; }PID=$(ps aux | grep "$JAR_NAME" | grep -v grep | awk '{print $2}')CURRENT_TIME=$(date +%s)
COOLDOWN=150 # 150秒冷却时间LAST_RESTART=0
if [ -f "$RESTART_RECORD" ]; thenLAST_RESTART=$(cat "$RESTART_RECORD")
fiif [ -z "$PID" ]; then# 服务未运行,启动sh startup.shecho "$(date '+%F %T') Service not running, starting..." >> $LOG_FILEdate +%s > "$RESTART_RECORD" # 记录启动时间
else# 检查 CPU# CPU=$(ps -p $PID -o %cpu= | awk '{print int($1)}')CPU=$(top -b -n1 -p $PID | tail -n +8 | awk '{print int($9)}')echo "$(date '+%F %T') PID=$PID CPU=${CPU}%" >> $LOG_FILECPU_THRESHOLD=80TIME_DIFF=$(( CURRENT_TIME - LAST_RESTART ))if [ "$CPU" -gt "$CPU_THRESHOLD" ]; thenif [ "$TIME_DIFF" -lt "$COOLDOWN" ]; thenecho "$(date '+%F %T') CPU exceed $CPU_THRESHOLD%, but within cooldown period, skipping restart." >> $LOG_FILEelseecho "$(date '+%F %T') CPU exceed $CPU_THRESHOLD%, restarting service..." >> $LOG_FILEsh shutdown.shsleep 5sh startup.shecho "$(date '+%F %T') Restarted service" >> $LOG_FILEdate +%s > "$RESTART_RECORD" # 更新重启时间fifi
fi
然后我们把它加到定时任务里面去
crontab -e
在里面加入一行(注意自己的脚本路径和名称)
* * * * * /data/application/app/monitor.sh >> /data/application/app/monitor.log 2>&1
上面的是每分钟执行一次,服务器上的定时任务最小的粒度就是一分钟了,如果想更细的粒度比如每十秒检查一次可以写成下面这样的
* * * * * /data/application/app/monitor.sh >> /data/application/app/monitor.log 2>&1
* * * * * sleep 10; /data/application/app/monitor.sh >> /data/application/app/monitor.log 2>&1
* * * * * sleep 20; /data/application/app/monitor.sh >> /data/application/app/monitor.log 2>&1
* * * * * sleep 30; /data/application/app/monitor.sh >> /data/application/app/monitor.log 2>&1
* * * * * sleep 40; /data/application/app/monitor.sh >> /data/application/app/monitor.log 2>&1
* * * * * sleep 50; /data/application/app/monitor.sh >> /data/application/app/monitor.log 2>&1
检查一下看是否添加成功,如果下面命令里面能看到你家的那条记录就说明成功了
crontab -l
等一两分钟我们再去看下日志(注意自己的路径)
tail -f /data/application/app/monitor.log
能看到下面这样的
root@ecs-v2:/data/application/app# tail -f /data/application/app/monitor.log
2025-08-22 09:36:01 PID=1736316 CPU=22%
2025-08-22 09:37:01 PID=1736316 CPU=22%
2025-08-22 09:38:01 PID=1736316 CPU=22%
2025-08-22 09:39:01 PID=1736316 CPU=22%
2025-08-22 09:40:01 PID=1736316 CPU=22%
还有那种服务直接挂了重启的脚本,其它的和上面一样,加入到定时任务里面就可以了
#!/bin/bash
APP_HOME=/data/application/app
JAR_NAME=app-1.0.jar
START_SCRIPT=$APP_HOME/startup.sh# 找到进程 PID
PID=$(ps aux | grep $JAR_NAME | grep -v grep | awk '{print $2}')cd $APP_HOMEif [ -z "$PID" ]; thensh $START_SCRIPTecho "服务已挂掉,已自动重启,时间:`date '+%Y-%m-%d %T'`" >> $APP_HOME/restart_record.log
fi