主要原理是在启动服务前先生成一个systemd service文件写入/etc/systemd/system目录并设置开机自启,相应注释在脚本中做了说明
#!/bin/bash
########################################################
# 采用 systemd 启动服务 #
########################################################
# start: /home/data/server/start.sh 服务名 版本 startd #
# restart:/home/data/server/start.sh 服务名 版本 restartd #
# stop: /home/data/server/start.sh 服务名 版本 stopd #
########################################################
# 检查三个参数是否为空
if [[ -z $1 ]] || [[ -z $2 ]] || [[ -z $3 ]] ; then
echo "Service args exist null."
exit 1
fi
# 设置值
# 服务名
SERVER_NAME=$1
# 版本
VERSION=$2
# jar包名 = 服务名-版本.jar
JAR_NAME="${SERVER_NAME}-${VERSION}.jar"
# 部署环境选择
PROFILES_ACTIVE="comp"
# 服务所在服务器主目录
SERVER_HOME="/home/data/server/${SERVER_NAME}"
# 服务日志目录
LOGGER_HOME="${SERVER_HOME}/log"
# systemd服务名
SYSTEMD_NAME="${SERVER_NAME}.service"
# systemd 文件路径
SCRIPT_SYSTEMD="${SERVER_HOME}/${SYSTEMD_NAME}"
# 备份路径
BACKUP_DIR=backup
# 判断服务日志目录是否存在 不存在就创建
if [ ! -d $LOGGER_HOME ]; then
mkdir -p $LOGGER_HOME
echo "log dir LOGGER_HOME=$LOGGER_HOME"
fi
# jvm args
[ -z "$JAVA_OPTS" ] && JAVA_OPTS=" -Xms1024M -Xmx1024M -Xmn512M -Xss256k "
SERVER_OPTS=" ${JAVA_OPTS} \
-XX:SurvivorRatio=8 \
-XX:+UseConcMarkSweepGC \
-XX:MaxTenuringThreshold=5 \
-XX:GCTimeRatio=19 \
-XX:CMSInitiatingOccupancyFraction=85 \
-XX:CMSFullGCsBeforeCompaction=1 \
-XX:+PrintTenuringDistribution \
-XX:+PrintCommandLineFlags \
-XX:+PrintGCDetails \
-XX:+PrintGCDateStamps \
-Xloggc:${LOGGER_HOME}/gc-%t.log \
-XX:-OmitStackTraceInFastThrow \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=${LOGGER_HOME}/java_heapdump.hprof"
# 生成systemd service file 内容
function write_systemd() {
cat >"${SCRIPT_SYSTEMD}" <<-EOF
[Unit]
Description=${SERVER_NAME}
After=network.target
[Service]
Type=forking
WorkingDirectory=/home/data/server/${SERVER_NAME}
ExecStart=/home/data/server/service.sh ${SERVER_NAME} ${VERSION} start
ExecReload=/home/data/server/service.sh ${SERVER_NAME} ${VERSION} restart
ExecStop=/home/data/server/service.sh ${SERVER_NAME} ${VERSION} stop
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
}
# 复制 systemd service file到/etc/systemd/system目录 并设置开机自启
function enable_systemd() {
if [ ! -f "${SCRIPT_SYSTEMD}" ]; then
echo "write systemd ${SYSTEMD_NAME}"
systemctl disable "${SCRIPT_SYSTEMD}"
write_systemd
cp "${SCRIPT_SYSTEMD}" /etc/systemd/system
chmod 755 /etc/systemd/system/${SYSTEMD_NAME}
systemctl daemon-reload
systemctl enable "${SYSTEMD_NAME}"
echo "systemd enable $SYSTEMD_NAME"
else
echo "systemd file $SYSTEMD_NAME is enabled."
fi
}
# startd命令
start_systemd() {
enable_systemd
echo "start $SYSTEMD_NAME"
systemctl start "${SYSTEMD_NAME}"
systemctl is-active --quiet "${SYSTEMD_NAME}" && echo "Service is running..."
}
# restartd命令
restart_systemd() {
enable_systemd
echo "restart $SYSTEMD_NAME"
systemctl restart "${SYSTEMD_NAME}"
systemctl is-active --quiet "${SYSTEMD_NAME}" && echo "Service is running..."
}
# stopd命令
stop_systemd() {
enable_systemd
echo "stop $SYSTEMD_NAME"
systemctl stop "${SYSTEMD_NAME}"
}
# start
start() {
eval exec "java -server $SERVER_OPTS \
-jar $SERVER_HOME/$JAR_NAME \
--spring.profiles.active=$PROFILES_ACTIVE \
-DLOGGING_PATH=$LOGGER_HOME \
-Duser.timezone=Asia/Shanghai \
-Dfile.encoding=UTF-8 \
-Djava.security.egd=file:/dev/./urandom \
>> $LOGGER_HOME/$SERVICE_NAME\.out 2>&1 &"
if [ $? -eq 0 ]; then
sleep 1
echo "Service:“$SERVER_NAME” start successful~~~"
else
echo "Service:“$SERVER_NAME” start failure."
exit 2
fi
}
# check service
check_service() {
pid_list=($(ps -ef | grep $JAR_NAME | grep -v grep | awk '{print $2}'))
ps_count=${#pid_list[@]}
test $ps_count -gt 0 && { echo "Found $ps_count $JAR_NAME service"; }
return $ps_count
}
# kill
stop() {
sleep 1 && check_service
[[ ${kill_retry} -le 3 ]] && kill_args='' || kill_args='-9'
test $ps_count -gt 0 && {
echo "Try to kill running service retry count ${ps_count}"
kill $kill_args ${pid_list[@]}
kill_result=$?
} || {
echo "Service $JAR_NAME not running"
return 0
}
test "$kill_result" -ne 0 && { echo "Kill Failed,Skip..."; } || echo "Kill command send,Waiting for $JAR_NAME process quit"
while [ $ps_count -ne 0 ]; do
let kill_retry=$kill_retry+1
stop
done
}
# restart
restart() {
if [ ! -f "${SERVER_HOME}/${JAR_NAME}" ]; then
echo "Jar: “${SERVER_HOME}/${JAR_NAME}” not sexists start failure."
exit 4
fi
stop
start
}
# clean
clean(){
if [ ! -d $BACKUP_DIR ]; then
mkdir $BACKUP_DIR
fi
#备份jar包
mv $SERVER_HOME/$JAR_NAME $BACKUP_DIR/$JAR_NAME\-$(date -d "today" +"%Y%m%d%H%M%S")
rm -rf $SERVER_HOME/$LOGGER_HOME/*.out
#删除7天前的日志和备份文件
find $SERVER_HOME/$LOGGER_HOME/ -type f -mtime +7 | xargs rm -rvf
find $SERVER_HOME/$BACKUP_DIR/ -type f -mtime +7 | xargs rm -rvf
echo **************clean $SERVICE_NAME success************
}
case "$3" in
start)
start
;;
restart)
restart
;;
stop)
stop
;;
clean)
clean
;;
startd)
start_systemd
;;
restartd)
restart_systemd
;;
stopd)
stop_systemd
;;
*)
echo -e $"=== Run $0 Use arg: { startd | restartd | stopd } ==="
;;
esac
exit $?