springboot通用管理脚本
在springboot打包成jar包之后,往往需要很多启动参数辅助服务启动,为了避免每次都写很长的启动命令,可以将这些重复性工作写成脚本。
shell脚本:
#!/bin/bash
# jar包的名字
APP_NAME=appname
# 环境配置文件,如application-dev.yml
PROFILE=dev
JAR_NAME=$APP_NAME\.jar
PID=$APP_NAME\.pid
PROJ_HOME=$(pwd)
# 这个是jar包的路径需要根据自己的情况配置
APP_HOME=$PROJ_HOME/target
LOG_PATH=$APP_HOME/logs
# 创建log路径
if [ ! -d $LOG_PATH ]; then
mkdir $LOG_PATH
fi
# GC日志参数
GC_LOG_OPTS=" -XX:+PrintGC -XX:+PrintGCDetails -Xloggc:$LOG_PATH/gc-%t.log"
# GC收集器参数
GC_OPTS="-XX:+UseConcMarkSweepGC"
# 其他参数
OTHER_OPTS="-Dspring.profiles.active=$PROFILE"
# JVM 启动参数
JVM_OPTIONS="-server -Xms64m -Xmx64m -XX:MetaspaceSize=16m $GC_OPTS $GC_LOG_OPTS $OTHER_OPTS"
# 使用说明,用来提示输入参数
usage() {
echo "Usage: demogc.sh [start|stop|restart|status]"
exit 1
}
# 检查程序是否在运行
is_exist() {
pid=$(ps -ef | grep $APP_HOME/$JAR_NAME | grep -v grep | awk '{print $2}')
#如果不存在返回1,存在返回0
if [ -z "${pid}" ]; then
return 1
else
return 0
fi
}
# 启动方法
start() {
is_exist
if [ $? -eq "0" ]; then
echo "WARN: $JAR_NAME is already running PID=${pid}"
else
echo "JVM_OPTIONS : "
echo $JVM_OPTIONS | sed 's/ /\n/g '
nohup java -jar $JVM_OPTIONS $APP_HOME/$JAR_NAME >>$LOG_PATH/stdout.log 2>&1 &
echo $! >$PID
echo "INFO: start $JAR_NAME successed PID=$!"
fi
}
# 停止方法
stop() {
#is_exist
pidf=$(cat $PID)
echo "INFO: app PID = $pidf begin kill $pidf"
kill "$pidf"
rm -rf $PID
sleep 2
is_exist
if [ $? -eq "0" ]; then
echo "INFO: app 2 PID = ${pid} begin kill -9 ${pid}"
kill -9 ${pid}
sleep 2
echo "INFO: $JAR_NAME process stopped ---"
else
echo "INFO: $JAR_NAME is not running ---"
fi
}
# 输出运行状态
status() {
is_exist
if [ $? -eq "0" ]; then
echo "INFO: $JAR_NAME is running PID is $pid"
else
echo "WARN: $JAR_NAME is not running"
fi
}
# 重启
restart() {
stop
start
}
case "$1" in
"start")
start
;;
"stop")
stop
;;
"status")
status
;;
"restart")
restart
;;
*)
usage
;;
esac
exit 0
这种写法也是CentOS7之前服务文件的写法,CentOS7时候就采用了systemd服务,所以也可以写成systemctl的service文件形式
systemctl服务:
1.在写systemd服务时可以借助上面写好的shell脚本
[Unit]
Description=demo - demo server
Documentation=http://git.demo/demo
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
User=root
ExecStart=/bin/sh -c '/home/codes/java/demo/demo.sh start'
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/sh -c '/home/codes/java/demo/demo.sh stop'
[Install]
WantedBy=multi-user.target
2.也可以不借助上面的shell脚本,使用systemctl的写法来写服务
[Unit]
Description=demo - demo server
Documentation=http://git.demo/demo
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
User=root
Environment="JAR_NAME=demogc-1.0.0.jar"
Environment="PROFILE=dev"
Environment="PROJ_HOME=/home/codes/java/demogc"
Environment="APP_HOME=$PROJ_HOME/target"
Environment="LOG_PATH=$PROJ_HOME/logs"
Environment="GC_LOG_OPTS=-XX:+PrintGC -XX:+PrintGCDetails -Xloggc:/home/codes/java/demogc/logs/demogc.log"
Environment="GC_OPTS=-XX:+UseConcMarkSweepGC"
Environment="OTHER_OPTS=-Dspring.profiles.active=dev"
Environment="JVM_OPTIONS=-server -Xms64m -Xmx64m -XX:MetaspaceSize=16m $GC_OPTS $GC_LOG_OPTS $OTHER_OPTS"
ExecStartPre=/bin/sh -c 'if [ ! -d ${LOG_PATH} ]; then mkdir ${LOG_PATH}; fi'
ExecStart=/bin/sh -c 'java ${JVM_OPTIONS} -jar ${APP_HOME}/${JAR_NAME} >${LOG_PATH}/stdout.log 2>&1 &'
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
[Install]
WantedBy=multi-user.target
因为涉及变量和创建路径,这里会用到Environment
和ExecStartPre
。
但是这里有个问题,环境变量太多看着乱,每次有修改还需要改service问题件,而且-Xloggc
这个参数中不能再引入$变量,在Exec*
中无法解析这个变量。所以可以才用EnvironmentFile
的形式将变量独立一个文件出来。
3.借助EnvironmentFile来引入变量(或环境变量)
先将所有变量提取到demo.env中
JAR_NAME=demogc-1.0.0.jar
PROFILE=dev
PROJ_HOME=/home/codes/java/demogc
APP_HOME=$PROJ_HOME/target
LOG_PATH=$PROJ_HOME/logs
GC_LOG_OPTS="-XX:+PrintGC -XX:+PrintGCDetails -Xloggc:$LOG_PATH/gc.log"
GC_OPTS=-XX:+UseConcMarkSweepGC
OTHER_OPTS=-Dspring.profiles.active=dev
JVM_OPTIONS="-server -Xms64m -Xmx64m -XX:MetaspaceSize=16m $GC_OPTS $GC_LOG_OPTS $OTHER_OPTS"
修改demo.service文件
[Unit]
Description=demo - demo server
Documentation=http://git.demo/demo
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
User=root
EnvironmentFile=/home/codes/java/demogc/demo.env
ExecStartPre=/bin/sh -c 'if [ ! -d ${LOG_PATH} ]; then mkdir ${LOG_PATH}; fi'
ExecStart=/bin/sh -c 'java ${JVM_OPTIONS} -jar ${APP_HOME}/${JAR_NAME} >${LOG_PATH}/stdout.log 2>&1 &'
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
[Install]
WantedBy=multi-user.target
这样service文件就清晰了很多
总结
1.注意${DEMO}
和$DEMO
的区别,shell命令执行的时候会将$DEMO
中的$
符号继续解析为变量所代表的值,而使用${DEMO}
会将里面所有的字符包括$
都原封不动的当成字符不解析
2.注意Environment中即便带空格可以不用引号在包起来,如Environment="DEMO=a b"
,不用写成Environment='DEMO="a b"'
3.EnvironmentFile可以将环境变量独立出一个单独的文件,并且在$嵌套的情况下不会出现问题
更多推荐
springboot自启动脚本shell、systemctl以及service文件Environment用法
发布评论