1. 程式人生 > >Jenkins通過shell不能啟動Tomcat和啟動後進程被殺死的問題

Jenkins通過shell不能啟動Tomcat和啟動後進程被殺死的問題

    工作中搭建基於Jenkins+Svn+Maven+Tomcat的持續整合環境,結合shell實現自動編譯部署和測試,其中Jenkins是通過Tomcat啟動的。

問題一、Tomcat無法啟動

在搭建過程中出現一個現象,自動編譯,停止專案Tomcat,war包複製等都沒有問題,但是專案Tomcat停止後,無法啟動。把指令碼放在伺服器直接執行,tomcat可以正常啟動,通過Jenkins執行就不行。

指令碼如下:

#!/bin/bash
export BUILD_ID=192.168.5.258 #必須加  
TOMCATTHREAD=`ps aux | grep 'tomcat-ceshi' | grep -v grep`  
if test -z "$TOMCATTHREAD"  
then  
   echo "TOMCAT NOT START"  
else  
    THREADLIST=(${TOMCATTHREAD// / })
    PID=${THREADLIST[1]}  
    kill -9 $PID 
    sleep 6s  
fi  
   cd /usr/local/tomcat-ceshi/webapps  
   rm -f test.war
   rm -rf test 
   cp -r /usr/local/tomcat-forjenkins18/workspace/test/test-web/target/test.war  /usr/local/tomcat-ceshi/webapps/
   cd /usr/local/tomcat-ceshi/bin  
   ./startup.sh 
   sleep 5s

觀察Jenkins自身Tomcat的日誌,發現有報錯:埠被佔用,Jenkins的Tomcat又被啟動了一次,結合Jenkins控制檯輸出

感覺指令碼中./startup.sh 啟動的不是專案Tomcat,而是Jenkins自身Tomcat,於是修改專案Tomcat的catalina.sh, 重新設定了Tomcat啟動需要的變數,如下

JAVA_OPTS="-server -Xms1024m -Xmx1024m -XX:PermSize=512m -XX:MaxPermSize=1024m -XX:MaxNewSize=1024m"
export TOMCAT_HOME=/usr/local/tomcat-ceshi
export CATALINA_HOME=/usr/local/tomcat-ceshi
export JAVA_HOME=/usr/local/java/jdk1.8.0_101

 構建專案,專案Tomcat啟動成功。此時,Jenkins控制檯輸出的環境變數也變成了專案Tomcat路徑,不再是JenkinsTomcat路徑。

       原因分析(個人理解):專案Tomcat未啟動應該環境變數的問題,指令碼./startup.sh啟動了一個tomcat, 但啟動的是Jekins本身的TOMCAT , 不是Cd到目錄下的目標TOMCAT,正常在伺服器cd到對應目錄, 此時環境變更(CATALINA_BASE、CATALINA_HOME、CATALINA_TMPDIR、JRE_HOME、CLASSPATH)沒值,./startup.sh預設使用錄前目錄Tomcat路徑,故可正常啟動當前目錄下的TOMCAT:而在Jenkins的指令碼中,Jenkins是用TOMCAT啟的, 啟動的時候設定了環境變數,  要啟動的目標TOMCAT是通過Jenkins啟動的, 延用了Jenkins的環境變數,其Startup.sh (其實是 CATALINA.sh)執行時上述幾個環境變數還是Jenkins的值,故再一次啟動了Jenkins的TOMCAT,而不是目標TOMCAT。

問題二、Tomcat啟動後又被殺死

因為上述使用的指令碼中有export BUILD_ID=192.168.5.258 ,所以並未遇到Tomcat啟動後又被殺死的問題,總結網上各類文章,Tomcat服務啟動後被停止的原因是由於jenkins構建完畢後殺掉了所有其啟動的程序,但是我們需要啟動的Tomcat服務繼續執行,可通過重置環境變數BUILD_ID和禁用Jenkins殺死子程序特性來實現,Jenkins上的說明

(Jenkins若是通過Tomcat啟動的,禁用特性的話,修改其Tomcat的catalina.sh,指令碼前加JAVA_OPTS="$JAVA_OPTS -Dhudson.util.ProcessTree.disable=true")