首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Shell 腳本防止 Java 應用重複啟動

     編輯:Java 相關知識

在 Linux 環境下,Java 後台應用若無防護,可被重複啟動導致資源浪費、端口衝突、資料競爭。本文提供一個健壯的啟動腳本,透過 ps + grep + awk 檢測進程是否存在,實現「單實例守護」功能,並處理腳本權限、編碼格式等常見坑點。

應用目錄結構

app/
├── bin/          # 啟動腳本 startup.sh、類別檔、配置檔
└── lib/          # 依賴 JAR 包

主類:mypack.MyAppMain

防重複啟動腳本:startup.sh

#!/bin/sh
programdir="."
program="mypack.MyAppMain"
num=$#
temp=$CLASSPATH

# 設定 lib 目錄所有 JAR 到 CLASSPATH
libs=../lib/*
append() { temp=$temp":"$1; }
for file in $libs; do append $file; done
export CLASSPATH=$temp:.:../:$programdir
export LANG=zh_CN

# 核心:檢測進程是否已存在
res=`ps aux | grep java | grep $program | grep -v grep | awk '{print $2}'`
if [ -n "$res" ]; then
    echo "MyAppMain already running"
else
    # 後台啟動,輸出重定向到 nohup.out
    nohup java -classpath $CLASSPATH mypack.MyAppMain &
    sleep 3  # 等待 JVM 啟動
    unset res
    # 二次驗證啟動成功
    res=`ps aux | grep java | grep $program | grep -v grep | awk '{print $2}'`
    if [ -n "$res" ]; then
        echo "MyAppMain start success"
    else
        echo "MyAppMain start error"
    fi
fi

關鍵邏輯解析

  1. 進程檢測鏈:ps aux 列出所有進程 → grep java 過濾 Java 進程 → grep $program 精確匹配主類名 → grep -v grep 排除 grep 自身 → awk '{print $2}' 取得 PID。
  2. 雙重檢查:啟動前檢查避免重複;啟動後 sleep 3 再檢查確認 JVM 確實掛起(防止啟動即崩潰)。
  3. CLASSPATH 動態組裝:遍歷 ../lib/* 所有 JAR,避免手動維護列表。
  4. nohup &:脫離終端後台運行,標準輸出導向 nohup.out。

常見坑點與解決

對比:無防護版腳本

#!/bin/sh
programdir="."
temp=$CLASSPATH
libs=../lib/*
append() { temp=$temp":"$1; }
for file in $libs; do append $file; done
export CLASSPATH=$temp:.:../:$programdir
export LANG=zh_CN
nohup java -classpath $CLASSPATH mypack.MyAppMain &

此版本可無限重複啟動,導致多實例競爭資源。

進階建議

  • 生產環境建議使用 Systemd / Supervisor / Docker 管理進程生命週期,而非純 Shell 腳本。
  • 腳本加入 PID 檔案 (/var/run/myapp.pid) 鎖定,避免 grep 誤判。
  • 整合 健康檢查:啟動後呼叫 HTTP/TCP 探針確認服務就緒,而非單純 sleep 3。
  • 日誌切割:nohup.out 長期運行會膨脹,配合 logrotate 定期切割。

出處:lavasoft.blog.51cto.com

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
問題現象解決
腳本無執行權限Permission deniedchmod 755 startup.sh (或 777)
編碼格式錯誤: bad interpreter: No such file or directory確保檔案格式為 Unix (LF),非 Windows (CRLF);用 dos2unix startup.sh 或編輯器轉換
grep 匹配過寬誤殺無關進程主類名需足夠唯一,或加上完整包名 mypack.MyAppMain
CLASSPATH 為空找不到主類腳本先組裝 ../lib/* 再導出