一鍵啓動、停止腳本開發指引

一、背景介紹

項目開發時使用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

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