1. 程式人生 > >自動釋出指令碼導致的Tomcat意外退出

自動釋出指令碼導致的Tomcat意外退出

最近公司專案的Dev環境要自己維護,為了避免麻煩,寫了一個釋出指令碼,但是發現每次關閉和伺服器的SSH連線後,Tomcat就意外退出,檢視日誌發現最後退出有如下幾行日誌:

Nov 10, 2017 2:38:35 PM org.apache.coyote.AbstractProtocol pause
INFO: Pausing ProtocolHandler ["http-nio-8080"]

Nov 10, 2017 2:38:35 PM org.apache.catalina.core.StandardService stopInternal
INFO: Stopping service Catalina

[INFO][2017
-11-10 14:38:35] org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:960) Closing WebApplicationContext for namespace 'Dispatcher-servlet': startup date [Fri Nov 10 14:37:53 CST 2017]; parent: Root WebApplicationContext [INFO][2017-11-10 14:38:35] org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:960
) Closing Root WebApplicationContext: startup date [Fri Nov 10 14:37:52 CST 2017]; root of context hierarchy Nov 10, 2017 2:38:35 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads SEVERE: The web application [/] appears to have started a thread named [FileWatchdog] but has failed to
stop it. This is very likely to create a memory leak. Nov 10, 2017 2:38:35 PM org.apache.coyote.AbstractProtocol stop INFO: Stopping ProtocolHandler ["http-nio-8080"] Nov 10, 2017 2:38:35 PM org.apache.coyote.AbstractProtocol destroy INFO: Destroying ProtocolHandler ["http-nio-8080"]

最開始懷疑是 OOM 問題,排查程式碼沒有發現相關問題,JVM配置OOM後轉存堆記憶體快照,也沒有發現問題,後來發現規律是每次關閉SSH連線一會兒後Tomcat即關閉,度娘後發現如下文章:

-XX:+HeapDumpOnOutOfMemoryError  -XX:HeapDumpPath=\data\heap\

解決方案

在指令碼開始新增 set -m,使用監視模式。

問題原因

  • SSH關閉後,作業系統kill掉指令碼;
  • Java程序掛在了指令碼程序下面;

修改後的指令碼

修改後的釋出指令碼:

#!/bin/sh
# author qiesai

##呼叫格式:base-war-deploy-tools.sh proName branchName profile 
##命名規則:proName作為back、release、war的名稱存在,要保持一致
PRO_NAME=$1
BRANCH_NAME=$2
PROFILE=$3

BASE_DIR=`pwd`
CODE_DIR="/data/code/${PRO_NAME}/"
RELEASE_DIR="/data/release/"
BACKUP_DIR="/data/backup/"
WAR_NAME="${PRO_NAME}.war";


function stopTomcat(){
    echo "_______________________________"
    echo "stop tomcat"

    TOMCAT_PID=`ps -ef|grep tomcat | grep -v 'grep\|tail' | awk '{print $2}'`
    if [ -n "$TOMCAT_PID" ]; then
        echo "tomcat is running : ${TOMCAT_PID} , will stop it"
        kill -9 $TOMCAT_PID
    fi

    COUNT=0  
    while [ $COUNT -lt 1 ]; do      
        echo -e ".\c"  
        sleep 1
        COUNT=1

        PID_EXIST=`ps --no-heading -p $TOMCAT_PID`  
        if [ -n "$PID_EXIST" ]; then  
            COUNT=0
            break
        fi 
    done
    echo ""
    echo "stop tomcat succes"
}

function buildProject(){
    source /etc/profile
    echo "_______________________________"
    echo "pull git code"
    cd $CODE_DIR
    git branch -q $BRANCH_NAME
    git checkout $BRANCH_NAME
    git pull origin $BRANCH_NAME
    echo "_______________________________"
    echo "buil project"
    echo `/data/maven/maven/bin/mvn clean package -P${PROFILE}`
    echo "buil finish"
}

function releaseWar(){
    echo "_______________________________"
    echo "deploy war"
    cd $RELEASE_DIR
    mv -f ./$WAR_NAME $BACKUP_DIR$WAR_NAME
    #注意不要 rm -rf /*也不要 cd到/下
    rm -rf *
    mv -f $CODE_DIR/target/$WAR_NAME ./$WAR_NAME 
    #set -m是解決Tomcat關閉的關鍵點。
    set -m
    nohup /data/tomcat/bin/startup.sh &
    echo "deploy success"
}

function main(){
    if [ -z "$PRO_NAME" ]; then
        echo "please input project name"
        exit;
    fi

    if [ -z "$BRANCH_NAME" ]; then
        echo "please input a git branch name"
        exit;
    fi

    if [ -z "$PROFILE" ]; then
        echo "please choose a profile"
        exit;
    fi

    echo "=====================begin deploy====================="
    buildProject;
    stopTomcat;
    releaseWar;
    echo "=====================deploy succ====================="
    tail -f /data/tomcat/logs/catalina.out
}

main;