Shell脚本 + crontab 监控 Java 进程并自动重启的完整方案

315 阅读2分钟

以下是使用 Shell脚本 + crontab 监控 Java 进程并自动重启的完整方案:

1. 编写监控脚本 (monitor_java.sh)

#!/bin/bash

#启动进程:./java_monitor.sh start
#停止进程:./java_monitor.sh stop
#重启进程:./java_monitor.sh restart
#检查状态:./java_monitor.sh status

# 配置项
JAVA_PROCESS_NAME="one-admin-application.jar"  # 进程关键词
APP_PORT=8080
RESTART_SCRIPT="/Users/snackpub/Desktop/temp-files/jar/start-admin.sh" # 启动脚本路径
LOG_FILE="/var/log/java_monitor.log"       # 日志路径
MAX_START_TIME=300                        # 允许的最大启动时间(秒)

# 函数:记录日志
log() {
    local message="$1"
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $message" >> "$LOG_FILE"
}

# 函数:检查进程是否"完全启动"(通过端口/健康接口检测)
is_fully_started() {
    log "开始检测..."
    if [[ "$OSTYPE" == "darwin"* ]]; then
        # macOS 方式
        if lsof -i :"$APP_PORT" | grep -q "LISTEN" && ps aux | grep -v grep | grep -q "$JAVA_PROCESS_NAME"; then
            log "$APP_PORT 端口正在监听,且存在 $JAVA_PROCESS_NAME 进程。"
            return 0
        fi
    else
        # Linux 方式
        if netstat -tlnp | grep -w "$APP_PORT" | grep -q "$JAVA_PROCESS_NAME"; then
            log "$APP_PORT 端口正在监听,且存在 $JAVA_PROCESS_NAME 进程。"
            return 0
        fi
    fi

    # 可选:HTTP健康检查(跨平台)
    # if curl -sf --connect-timeout 3 "http://localhost:$APP_PORT/actuator/health" | grep -q '"status":"UP"'; then
    #     return 0
    # fi

    return 1
}

# 函数:启动进程
start_process() {
    if ! pgrep -f "$JAVA_PROCESS_NAME" > /dev/null; then
        log "Java进程未运行,正在启动..."
        "$RESTART_SCRIPT" start >> "$LOG_FILE" 2>&1
        local start_time=$(date +%s)
        while [ $(($(date +%s) - start_time)) -lt "$MAX_START_TIME" ]; do
            if is_fully_started; then
                log "Java进程已成功启动。"
                return 0
            fi
            sleep 5
        done
        log "Java进程启动超时(${MAX_START_TIME}s)。"
        return 1
    else
        log "Java进程已经在运行。"
        return 0
    fi
}

# 函数:停止进程
stop_process() {
    if pgrep -f "$JAVA_PROCESS_NAME" > /dev/null; then
        log "Java进程正在运行,正在停止..."
        pkill -f "$JAVA_PROCESS_NAME"
        local stop_time=$(date +%s)
        while [ $(($(date +%s) - stop_time)) -lt 30 ]; do
            if ! pgrep -f "$JAVA_PROCESS_NAME" > /dev/null; then
                log "Java进程已成功停止。"
                return 0
            fi
            sleep 2
        done
        log "Java进程停止超时(30s),强制终止..."
        pkill -9 -f "$JAVA_PROCESS_NAME"
        return 1
    else
        log "Java进程未运行。"
        return 0
    fi
}

# 函数:重启进程
restart_process() {
    stop_process
    start_process
}

# 函数:检查进程状态
check_status() {
    if pgrep -f "$JAVA_PROCESS_NAME" > /dev/null; then
        if is_fully_started; then
            log "Java进程正在运行且已完全启动。"
        else
            log "Java进程正在运行,但未完全启动。"
        fi
    else
        log "Java进程未运行。"
    fi
}

# 主逻辑
case "$1" in
    start)
        start_process
        ;;
    stop)
        stop_process
        ;;
    restart)
        restart_process
        ;;
    status)
        check_status
        ;;
    *)
        echo "用法: $0 {start|stop|restart|status}"
        exit 1
        ;;
esac
    

2. 编写重启脚本

3. 设置脚本权限

chmod +x /path/to/monitor_java.sh

4. 配置crontab定时监控(每分钟检查一次)

crontab -e  //EDITOR=vimcrontab -e 强制使用vim打开


crontab -l

添加以下行:

* * * * * /path/to/monitor_java.sh start >> /var/log/monitor_zsba.log 2>&1
* * * * *
| | | | |
| | | | +----- 星期几 (0 - 6) (0表示周日)
| | | +------- 月份 (1 - 12)
| | +--------- 日期 (1 - 31)
| +----------- 小时 (0 - 23)
+------------- 分钟 (0 - 59)

测试执行

/bin/bash /path/to/monitor_java.sh start

日志检查

tail -f /var/log/monitor_zsba.log

5. 查看日志:

vim /var/log/java_monitor.log

6. 日志轮转(可选):

安装 logrotate 防止日志文件过大:

sudo nano /etc/logrotate.d/java_monitor

添加:

/var/log/java_monitor.log {
    daily
    rotate 7
    missingok
    notifempty
    compress
}

7. 邮件报警(可选):

在 monitor_java.sh 中添加邮件通知:

echo "Java进程已重启!" | mail -s "警报: Java进程崩溃" admin@example.com

8.其他指令