Jenkins中通过execute shell无法启动tomcat

Jenkins中通过execute shell无法启动tomcat

一、问题描述

环境:

192.168.2.20 jenkins服务器192.168.2.17 tomcat服务器

设置jenkins与tomcat服务器相互免密钥登陆,shell在远程的tomcat服务器上的,用jenkins控制台去调用shell脚本。

用jekins+shell搭建自动化部署更新tomcat,脚本在Linux下运行一切正常,但是当用jenkins构建完毕后,发现shell脚本会将tomcat停止,但是却怎么也无法再次启动tomcat,查了权限问题,脚本问题等等都无法解决,后经过不懈之努力,测试发现,当jekins中只有一个工程(tomcat项目)的时候是正常的,但是有多个工程(tomcat项目)就无法启动,最后在网上查资料知道是jenkins的问题。原因如下:Jenkins会在构建完成后使用processTreeKiller杀掉了所有子进程,而且这是Jenkins的默认行为。其实回头来看这个问题,就发现Jenkins的做法非常合理。当一次build异常结束,或被人终止时,必然需要结束所有这次build启动的子进程。

Jenkins中通过execute shell无法启动tomcat_第1张图片

构建后报错如下图:

Jenkins中通过execute shell无法启动tomcat_第2张图片

百度很多说明都是需要在脚本头部加上export BUILD_ID="xxxxxx"随便写,可以通过改变BUILD_ID的值来防止后台进程被杀死。但是我试过在我这边加了这个没有作用的,最后才想到上面那个找不到jdk或者jre路径的提示,感觉脚本中startup.sh启动的不是项目Tomcat,而是Jenkins自身Tomcat,于是修改项目Tomcat的catalina.sh,重新设置了Tomcat启动需要的变量或在脚本头部加上“export JAVA_HOME=xxxx”;

在次构建项目,项目Tomcat启动成功。此时,Jenkins控制台输出的环境变量也变成了项目Tomcat路径,不再是JenkinsTomcat路径。

Jenkins中通过execute shell无法启动tomcat_第3张图片

原因分析(个人理解):项目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。

二、通过Jenkins提供的启动参数禁用杀死子进程的特性

2.1、使用java-jar启动,-Dhudson.util.ProcessTree.disable=true-jarjenkins.war
2.2、使用Tomcat启动,Linux系统修改catalina.sh,在环境变量的说明后,脚本开始前加上
JAVA_OPTS="$JAVA_OPTS-Dhudson.util.ProcessTree.disable=true"
Windows系统修改catalina.bat,在环境变量的说明后,脚本开始前加上
setJAVA_OPTS=%JAVA_OPTS%"-Dhudson.util.ProcessTree.disable=true"
修改好Tomcat的配置文件后重新启动Tomcat

三、最后附上完整脚本

192.168.2.17服务器上shell脚本

#!/bin/bash
exportBUILD_ID=dontkillme#随便写
exportJAVA_HOME=/usr/java/jdk1.7.0_80#tomcat需要的jdk
#
#__auther__:zhan
#__time__:2018年08月16日22:00:00
#__作用__:用于jenkinsbuild完成之后的最后操作shell脚本
#__使用__:定义jenkins
#
#----------------------------------文件路径配置----------------------------------
#tomcat服务器获取系统时间以2018-08-16显示
timedate=$(date+%Y-%m-%d)
#client服务器tomcat安装路径
TOMCAT_HOME=/web/tomcat-jih-8080
#tomcat服务器备份文件存放路径
BACKUP_HOME=$TOMCAT_HOME/bak
#tomcat服务器war包服务器更新包名称
WAR__NAME=yk
#tomcat服务器最新版本文件存放路径
PUBLISHVERSION_HOME=/web/appwar/yk
#client服务器以时间的方式备份发布前的项目文件目录名称
BACK_TIME=`date+%Y%m%d%H%M`
#tomcat服务器项目发布后的路径
PUBLISHED_PATH=$TOMCAT_HOME/webapps/$WAR__NAME

#war包远程jenkins服务器项目配置文件
PROJECT_CONFIG_FILE=/web/appwar/yk/classes
#war包远程jenkins服务器地址
WAR_SERVER_IP='192.168.2.20'
#war包远程jenkins服务器存放路径
WAR_SERVER_HOME='/web/appwar/yk'


#----------------------远程复制war包[需要SSH免密码登陆设置]-------------------
#复制远程jenkins服务器war包到tomcat服务器上最新版本文件存放路径
scp-r$WAR_SERVER_IP:/$WAR_SERVER_HOME/$WAR__NAME.war$PUBLISHVERSION_HOME


#---------------------------------tomcat服务器备份文件-------------------------------------
echogoto$BACKUP_HOME
cd$BACKUP_HOME
echobackuptime$BACK_TIME
/bin/mkdir$BACK_TIME
echogoto$BACK_TIME
cd$BACK_TIME
echo"backuppath"
pwd
echo"startcopyprojectfiles"
#复制项目文件
cp$PUBLISHED_PATH.-R


#-------------------------------tomcat服务器解压war包---------------------------------------
#进入要发布版本的文件夹
cd$PUBLISHVERSION_HOME
echo"goto$PUBLISHVERSION_HOME"
#解压前先删除旧解压后的文件
rm-rf$WAR__NAME
echo"rmsuccessfull"
#解压项目war包
/bin/unzip$WAR__NAME.war-d$WAR__NAME/&>/dev/null
echo"unzipsuccessfull"

#复制远程服务器war包最新配置文件到本地服务器配置文件存放路径
scp-r$WAR_SERVER_IP:/$PROJECT_CONFIG_FILE/*$PUBLISHVERSION_HOME/$WAR__NAME/WEB-INF/classes

#最后删除war包,以便下次更新下载最新war包
rm-rf$WAR__NAME.war
echo"$WAR__NAME.warrmsuccessfull"

--------------------------------------------说明----------------------------------------------------------------------------------
#下面的命令会将【PROJECT_CONFIG_FILE=/web/appwar/yj/classes】classes目录给拷贝到本地文件的properties目录的
#scp-r$WAR_SERVER_IP:/$PROJECT_CONFIG_FILE/$PUBLISHVERSION_HOME/$WAR__NAME/WEB-INF/classes/properties
#将远程【PROJECT_CONFIG_FILE=/web/appwar/yj/classes】classes目录下的所有文件(不包含classes目录)拷贝本地properties目录下
#scp-r$WAR_SERVER_IP:/$PROJECT_CONFIG_FILE/*$PUBLISHVERSION_HOME/$WAR__NAME/WEB-INF/classes/properties
#将远程classes目录下的文件拷贝本地classes目录下
#scp-r$WAR_SERVER_IP:/$PROJECT_CONFIG_FILE/*$PUBLISHVERSION_HOME/$WAR__NAME/WEB-INF/classes
#或者用scp-r$WAR_SERVER_IP:/$PROJECT_CONFIG_FILE/$PUBLISHVERSION_HOME/$WAR__NAME/WEB-INF到这里即可,就直接将classes目录放到WEB-INF下面了
--------------------------------------------说明----------------------------------------------------------------------------------

#-------------------------------tomcat服务器部署文件---------------------------------------
#关闭tomcat
#/sbin/servicetomcatstop
#$TOMCAT_HOME/bin/shutdown.sh
cd$TOMCAT_HOME/bin
#查看进程
ps-ef|grep$TOMCAT_HOME|grep-vgrep|grep-vkill

#上一个命令退出后就执行kill进程号,否则是执行下一个语句说明
#【if[$-eq0]:代表上一个命令执行后的退出状态:0为成功,非0为失败】
if[$-eq0];then
kill-9`ps-ef|grep$TOMCAT_HOME|grep-vgrep|grep-vkill|awk'{print$2}'`
sleep3
echo"停止tomcat服务成功"
else
echo$TOMCAT_HOME'该目录进程已KILL或项目未启动'
fi

#删除项目文件
rm-rf$PUBLISHED_PATH/*
#删除临时文件、log日志
rm-rf$TOMCAT_HOME/temp/*
rm-rf$TOMCAT_HOME/conf/Catalina/*
rm-rf$TOMCAT_HOME/work/*

#拷贝最新版本更新文件到项目发布路径下
cp$PUBLISHVERSION_HOME/$WAR__NAME/*$PUBLISHED_PATH/-R
#复制配置文件
#cp$PUBLISHVERSION_HOME/classes/*$PUBLISHED_PATH/WEB-INF/classes-R
#启动tomcat,使用service命令时,使用普通用户需要输入密码,所以直接暂不采用service的方式启动和关闭tomcat
#/sbin/servicetomcatstart
$TOMCAT_HOME/bin/startup.sh
#tail-f$TOMCAT_HOME/logs/catalina.$timedate.out

你可能感兴趣的:(jenkins)