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