一键启动、停止脚本开发指引

一、背景介绍

项目开发时使用gradle构建工具进行项目构建开发,借助application插件进行项目打包。

./gradlew clean build

执行以上命令后,gradle会自动将项目打包为zip包,并放在build/distributions目录下。
zip包里面包含了两个目录:

  • bin : gradle自动生成的启动脚本,与项目/模块名称相同。
  • lib : 所有的运行时jar包。

一般情况下,使用gradle自动生成的启动脚本即可满足需求,但要做成类似hadoop-daemon.sh这样的一键启动脚本,仍需在自动生成的脚本基础上做些封装。

二、一键启动脚本

封装的一键启动脚本主要扩展了以下功能:

  1. 通过nohup在后台启动服务,常驻运行。
  2. 捕获服务的标准输出,并保存到日志。
  3. 自定义Log4j2的日志文件名,添加用户名、主机名。
  4. 设置JVM出现内存异常时的输出日志。

示例:

# !/usr/bin/env bash
#
# 服务一键启动脚本
#
# @author chriscchen
# @createtime 2020-05-21
#

bin=`dirname ${BASH_SOURCE-$0}`
bin=`cd "$bin"; pwd`

# find correct directory
my_dir_prefix="/data/logs/data-studio"

# 模块名称,也是gradle自动生成的启动脚本名称
MODULE_NAME="ds-ide"

# 自定义日志目录
export DS_LOG_DIR=${my_dir_prefix}/${MODULE_NAME}

# 自定义Log4j2的日志文件名,添加用户名、主机名
LOG4J_OPTS="-Dlog.dir=${DS_LOG_DIR} -Dlog.file=${MODULE_NAME}-${USER}-${HOSTNAME}.log"

# 设置JVM出现内存异常时的输出日志
JVM_LOG_OPTS="-XX:HeapDumpPath=${DS_LOG_DIR} -XX:ErrorFile=${DS_LOG_DIR}/ps_err_pid%p.log"

# use JAVA_OPTS to pass the options
export JAVA_OPTS="${LOG4J_OPTS} ${JVM_LOG_OPTS}"

# 后台启动服务,并捕获标准输出,保存到日志文件
nohup ${bin}/${MODULE_NAME} >> ${DS_LOG_DIR}/${MODULE_NAME}.out.$(date +%Y%m%d%H%M%S) 2>&1 &

if [[ $? != 0 ]]; then
    echo "Failed to start ${MODULE_NAME}" 1>&2
    exit 1
else
    echo "${MODULE_NAME} started"
fi

三、一键停止脚本

一般情况下,停止进程都是通过kill命令来完成,但kill命令并不是同步的。
执行kill命令,本质上只是向进程发送了“关闭”命令,进程接受到“关闭”命令并响应给kill命令,这条命令就执行成功并退出了。
但进程是否已经停止,是由程序自身的停止逻辑决定。

所以参考 hadoop-daemon.sh stop停止脚本,实现了一键停止服务脚本,主要实现了等待进程退出的功能。

示例:

# !/usr/bin/env bash
#
# @author chriscchen
# @createtime 2020-05-21
#

# 根据类名来查找进程。要注意的是:如果启动进程时,显式拼接了所有的jar包,会导致`ps`时显示名称过长,无法查找得类名的。一般在指定`classpath`时,通过`lib/*`的方式来指定。
PIDS=$(ps -ef | grep -v grep | grep "com.demo.Application" | awk '{print $2}')

SERVICE_NAME="ds-ide"
# 没有找到进程,退出
if [[ -z "$PIDS" ]]; then
    echo "No ${SERVICE_NAME} to stop" 1>&2
else
    kill -s TERM ${PIDS}

    echo "Waiting for ${SERVICE_NAME} process to exit"
    # 通过 kill -0 来判断进程是否已经退出 
    while kill -0 ${PIDS} 2>/dev/null; do
        sleep 1
    done
    echo "Stopped ${SERVICE_NAME}"
fi

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章