项目结构
├─bin
│ └─app.sh
│ ├─shutdown.cmd
│ ├─shutdown.sh
│ ├─startup.cmd
│ └─startup.sh
├─config
├─lib
├─logs
├─target
└─temp
背景
在spring boot 服务实际部署过程中,发现老版本脚本的很多问题
问题:
- 只能在项目目录启动脚本
- 项目可能在同一服务器部署了多套,没办法兼容
- 没办法通过ps -ef 一次观测到项目目录
- logs文件必须手动创建问题
lib 目录生成
mvn dependency:copy-dependencies -DoutputDirectory=lib
pom.xml
<build>
<resources>
<!-- 编译之后包含xml -->
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<testResources>
<testResource>
<directory>src/test/resources</directory>
</testResource>
</testResources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includes>
<include>
<groupId>nothing</groupId>
<artifactId>nothing</artifactId>
</include>
</includes>
<layout>ZIP</layout>
</configuration>
</plugin>
</plugins>
<finalName>${project.artifactId}</finalName>
</build>
使用方式
修改脚本中的SERVICE_NAME的值即可
app.sh
#!/bin/sh
##项目服务名称
SERVICE_NAME=-server
## 脚本所在目录
BASEPATH=$(
cd $(dirname $0)
cd ..
pwd
)
## 以脚本所在目录为执行目录
cd $BASEPATH
## 相关Config
JAR_NAME=$SERVICE_NAME\.jar
JAR_HOME=$BASEPATH/target/
JAR_PATH=$JAR_HOME$JAR_NAME
##pid监控文件 内容是程序的pid
PID=$BASEPATH/bin/$SERVICE_NAME\.pid
## 日志文件名称
LOG_NAME=app.log
##服务目录
SERVICE_LOGS=logs
SERVICE_LOGS_HOME=$SERVICE_LOGS/
LOG_FILE_PATH=$SERVICE_LOGS_HOME$LOG_NAME
##GC.log日志
GC_LOG=$SERVICE_LOGS/gc.log
JAVA_OPTS=""
## 配置外部化lib
JAVA_OPTS=$JAVA_OPTS"-Dloader.path=lib/ "
## 配置GC信息
JAVA_OPTS=$JAVA_OPTS"-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:$GC_LOG "
## 配置JVM堆栈相关参数
JAVA_OPTS=$JAVA_OPTS"-ms512m -mx512m -Xmn256m -Djava.awt.headless=true -XX:MaxPermSize=128m "
## 使用说明,用来提示输入参数
usage() {
echo "Usage: sh 执行脚本.sh [start|stop|restart|status]"
# 退出
exit 1
## help
## $? 是上个函数返回值
## Shell中判断语句if中-z至-d的意思 https://www.cnblogs.com/coffy/p/5748292.html
}
## 检查程序是否在运行
is_exist() {
## grep -v 排除 grep字段
pid=$(ps -ef | grep -F $JAR_NAME | grep -v grep | awk '{print $2}')
## 单个服务器部署了多个相同名称项目的话 只根据PID文件进行服务状态判断
## pid=cat $PID
if [[ -z "$pid" ]]; then
rm -rf $PID
fi
return $pid
}
#启动方法
init() {
## 判断logs目录是否存在,不存在则创建
if [ ! -d "$SERVICE_LOGS_HOME" ]; then
mkdir -p $SERVICE_LOGS_HOME
fi
if [ ! -f "$LOG_FILE_PATH" ]; then
touch $LOG_FILE_PATH
fi
}
start() {
is_exist
init
if [ ! -f "$PID" ]; then
# echo "java $JAVA_OPTS -jar $JAR_PATH >/dev/null 2>&1 &"
# nohup java $JAVA_OPTS -jar $JAR_PATH >catalin.log 2>&1 &
nohup java $JAVA_OPTS -jar $JAR_PATH >/dev/null 2>&1 &
echo $! >$PID
## 根据传参 判断 是自动构建工具还是直接运行 构建工具 需要睡眠5s,然后 打印出最后100行
if [[ $1 == "ci" ]]; then
sleep 10s
tail -n 100 $LOG_FILE_PATH
else
tail -0f $LOG_FILE_PATH
fi
echo ">>> start $JAR_NAME successed PID=$! <<<"
else
echo ">>> $JAR_NAME already start <<<"
status
fi
}
#停止方法 根据pid文件停止进程
stop() {
is_exist
if [[ -z "$pid" ]]; then
echo ">>> jarName:[$JAR_NAME] pid:[$pidf] process stopped success<<<"
return 0
fi
if [ ! -f "$PID" ]; then
echo -e "\npid文件不存在"
return 0
else
pidf=$(cat $PID)
#echo "$pidf"
echo ">>> api PID = $pidf begin kill $pidf <<<"
kill -15 $pidf
rm -rf $PID
sleep 5
kill -9 $pidf
sleep 2
echo ">>> jarName:[$JAR_NAME] pid:[$pidf] process stopped success<<<"
return 0
fi
}
#输出运行状态
status() {
is_exist
if [[ -z "$pid" ]]; then
echo ""
echo "${JAR_NAME} is not running "
echo ""
rm -rf $PID
else
echo -e "\n${JAR_NAME} is running PID is $pid "
detail=$(ps -ef | grep $JAR_NAME | grep -v grep)
echo -e "\n$detail\n"
fi
}
#重启
restart() {
stop
start $1
}
#根据输入参数,选择执行对应方法,不输入则执行使用说明
case "$1" in
"start")
start "$2"
;;
"stop")
stop
;;
"status")
status
;;
"restart")
restart "$2"
;;
*)
usage
;;
esac
exit 0
more and more
日志由应用输出到文件(方便管理)
控制台日志输出到 >/dev/null