springboot 啟動腳本優化
問題
前面記錄過如何將springboot 項目打包成zip(tar.gz)格式,而不是jar形式發布。里面提到了需要自己寫啟動腳本和停機腳本。
當時腳本中通過jps + 主類的方式檢查是否啟動項目。這沒有考慮項目在同一台服務器上部署2遍的情況。如果重復啟動,會提示已經啟動。如果啟動時去除校驗,真的啟動2個進程,停機時,會因為還存在一個項目進行而提示無法停止。
優化
這個問題的原因在於對是否啟動項目的檢查太過死板,沒有那么靈活。聯想到tomcat的部署,同一台機器可以部署多個tomcat。只要端口不沖突,都是可以的。所以不能通過jps+主類的形式檢查是否啟動項目。
調整后的啟動和停止方法:
-
項目啟動后,將項目pid寫入文件main.pid
-
檢查項目是否啟動的標准是:main.pid存在,且通過文件中的pid能找到對應進程
-
項目成功停止后將main.pid刪除
直接上腳本:
run.sh
#!/bin/bash
#Java程序所在的目錄(classes的上一級目錄)
APP_HOME=..
#需要啟動的Java主程序(main方法類)
APP_MAIN_CLASS="io.github.loanon.springboot.MainApplication"
#拼湊完整的classpath參數,包括指定lib目錄下所有的jar
CLASSPATH="$APP_HOME/conf:$APP_HOME/lib/*:$APP_HOME/classes"
s_pid=0
checkPid() {
if [ -f "main.pid" ];then
java_ps=`ps -aux |grep -v grep|grep \`cat main.pid\``
if [ -n "$java_ps" ]; then
s_pid=`echo $java_ps | awk '{print $2}'`
else
s_pid=0
fi
else
s_pid=0
fi
}
start() {
checkPid
if [ $s_pid -ne 0 ]; then
echo "================================================================"
echo "warn: $APP_MAIN_CLASS already started! (pid=$s_pid)"
echo "================================================================"
else
echo -n "Starting $APP_MAIN_CLASS ..."
nohup java -classpath $CLASSPATH $APP_MAIN_CLASS >./st.out 2>&1 &
echo $! > main.pid
checkPid
if [ $s_pid -ne 0 ]; then
echo "(pid=$s_pid) [OK]"
else
echo "[Failed]"
fi
fi
}
echo "start project......"
start
stop.sh
#!/bin/bash
#Java程序所在的目錄(classes的上一級目錄)
APP_HOME=..
#需要啟動的Java主程序(main方法類)
APP_MAIN_CLASS="io.github.loanon.springboot.MainApplication"
SHUTDOWN_CLASS="io.github.loanon.springboot.Shutdown"
#拼湊完整的classpath參數,包括指定lib目錄下所有的jar
CLASSPATH="$APP_HOME/conf:$APP_HOME/lib/*:$APP_HOME/classes"
ARGS="http://127.0.0.1:8080/actuator/shutdown"
s_pid=0
checkPid() {
if [ -f "main.pid" ];then
java_ps=`ps -aux |grep -v grep|grep \`cat main.pid\``
if [ -n "$java_ps" ]; then
s_pid=`echo $java_ps | awk '{print $2}'`
else
s_pid=0
fi
else
s_pid=0
fi
}
stop() {
checkPid
if [ $s_pid -ne 0 ]; then
echo -n "Stopping $APP_MAIN_CLASS ...(pid=$s_pid) "
nohup java -classpath $CLASSPATH $SHUTDOWN_CLASS $ARGS >./shutdown.out 2>&1 &
if [ $? -eq 0 ]; then
echo "[OK]"
else
echo "[Failed]"
fi
sleep 3
checkPid
if [ $s_pid -ne 0 ]; then
stop
else
echo "$APP_MAIN_CLASS Stopped"
rm main.pid
fi
else
echo "================================================================"
echo "warn: $APP_MAIN_CLASS is not running"
echo "================================================================"
fi
}
echo "stop project......"
stop