Jenkins pipeline部署远程tomcat项目

说明:

提示:这篇文章仅是记录自己成长路上的愚笨,不喜勿喷,同时也希望各路大神提出优秀的观点。谢谢!!


问题描述:

使用Jenkins自动化构建、部署远程服务器tomcat项目
废话不多说,直接上代码:

  1. pipeline脚本
def createVersion() {
    return new Date().format('yyyyMMddHHmmss') + "_${env.BUILD_ID}"
}

pipeline {
    //定义执行任务的代理
    agent any
    //设置环境变量
    environment {
        _version = createVersion()
        // 工作空间目录
        workspace = pwd()
        // 需要修改此处,定义项目名称
        project = "server-customer-api-1.0-SNAPSHOT"
        // 定义项目git地址
        git_url = "http://192.168.0.193:9988/property/server-api.git"
        //定义tomcat目录
        tomcat_dir = "/home/web_programs/house_keeper/apache-tomcat-8.5.28/"
        // 定义项目的webroot目录
        project_dir = "${tomcat_dir}webapps/"
        //定义项目的版本目录,一般不用更改
        version_dir = "${workspace}/bak/"
        //resource文件地址,根据项目不同而更改
        resource_dir = "${workspace}/server-customer-api/target/"
    }
    
    options {
        timestamps()
        //禁用Jenkins同时执行多次该pipeline
        disableConcurrentBuilds()
        //pipeline运行超时时间
        timeout(time: 20, unit: 'MINUTES')
        //保留最近历史构建记录的数量
        buildDiscarder(logRotator(numToKeepStr: '5'))
    }
    
    parameters {
        string(name: 'branch', defaultValue: 'master', description: '请输入将要构建的代码分支')
        choice(name: 'mode', choices: ['deploy', 'rollback'], description: '请选择发布或者回滚?')
        string(name: 'version_id', defaultValue: '0', description: '回滚时用,默认回滚到上一次构建,如需要回滚到更早构建,请输入对应构建ID')
    }
    stages {
        stage('拉取代码') {
            steps {
                echo 'Checkout'
                script {
                    try {
                        git branch: "${branch}", url: "${git_url}"
                    } catch (err) {
                        echo "${err}"
                    }
                }
            }
        }
        stage('定义版本管理脚本') {
            steps {
                script {
                    try {
sh '''
# 《注意点一》
cat > keepfive.sh << 'EOF'
#! /bin/bash
cd ${version_dir}
while true;do
FILE_COUNT=$(ls *.war | wc -l)
FILE_NAME=$(ls -lrt *.war | tail -n 1 | awk \'{print $9}\')
if [[ $FILE_COUNT -gt 5 ]];then rm -rf $FILE_NAME;else break;fi;done
cd -
EOF
'''
                    } catch (err) {
                        echo "${err}"
                    }
                }
            }
        }
        stage('定义部署脚本') {
            steps {
                script {
                    try {
sh '''
cat << 'EOF' > deploy.sh
#! /bin/bash
# 《注意点二》
export JENKINS_NODE_COOKIE=dontKillMe
# "创建编译主机上的版本目录"
if [ ! -d "${version_dir}" ]; then
mkdir -p ${version_dir}
fi
# "将正在运行的代码同步到编译主机版本目录"
jar -cvfM0 ${version_dir}${_version}.war -C ${project_dir}/ROOT .
# "使版本目录保持五个版本历史"
chmod 755 keepfive.sh
# 《注意点三》
source ./keepfive.sh
# "将项目部署到服务器目录"
cp ${resource_dir}${project}.war "${project_dir}ROOT.war"
# 本地服务器重启
cd ${tomcat_dir}bin
# 《注意点四》
source /home/admin/.bash_profile
# 《注意点五》
export BUILD_ID=dontKillMe
# 《注意点六》
./restart.sh
cd -
# 远程部署
scp ${resource_dir}${project}.war admin@192.168.2.192:${project_dir}ROOT.war
# 远程重启服务器
ssh admin@192.168.2.192 << RS
cd /home/web_programs/house_keeper/apache-tomcat-8.5.28/bin
# 《注意点七》
./restart.sh
# 《注意点八》
exit
RS

EOF
'''
                    } catch (err) {
                        echo "${err}"
                    }
                }
            }
        }
        stage('部署') {
            //定义阶段执行的条件
            when {
                environment name: 'mode', value: 'deploy'
            }
            steps {
                script {
                    try {
                        sh '''mvn clean package -Dmaven.test.skip=true -P test
                            chmod 755 deploy.sh
                            source ./deploy.sh'''
                    } catch (err) {
                        echo "${err}"
                    }
                }
            }
        }
        stage('回滚') {
            when {
                environment name: 'mode', value: 'rollback'
            }
            steps {
                script {
                    try {
                        if (params.version_id == '0') {
                            sh '''echo "选择回滚的版本是默认,将回滚到上次制品,回滚即将进行..."
                                cd ${version_dir}
                                file_name=`ls -lt *.war | tail -1 | awk \'{print $9}\'`
                                # 拷贝文件到本地服务器地址
                                cp ${version_dir}${file_name} ${project_dir}ROOT.war
                                # 本地服务器重启
                                cd ${tomcat_dir}/bin
                                ./restart.sh
                                cd -
                                # 拷贝文件到远程服务器
                                scp ${version_dir}${file_name} admin@192.168.2.192:${project_dir}ROOT.war
                                # 远程服务器重启
ssh admin@192.168.2.192 << EOF
cd ${tomcat_dir}/bin
./restart.sh
exit
EOF
                                echo "=============="
                                echo "项目已回滚完成!"
                                echo "=============="'''
                        } else {
                            sh '''echo "选择回滚的版本是:${version_id},将回滚到 ${version_id} 的制品,回滚即将进行..."
                                cd ${version_dir}
                                # 拷贝文件到本地服务器地址
                                cp ${version_dir}${version_id} ${project_dir}ROOT.war
                                # 本地服务器重启
                                cd ${tomcat_dir}/bin
                                ./restart.sh
                                cd -
                                # 拷贝文件到远程服务器
                                scp ${version_dir}${version_id} admin@192.168.2.192:${project_dir}ROOT.war
                                # 远程服务器重启
ssh admin@192.168.2.192 << EOF
cd ${tomcat_dir}/bin
./restart.sh
exit
EOF
                                echo "项目回滚到 ${version_id} 完成!"'''
                        }
                    } catch (err) {
                        echo "${err}"
                    }
                }
            }
        }
    }
}
  1. tomcat重启脚本(restart.sh)
#! /bin/bash

# =======================================================
# Author:yimeng
# Date:2021-01-24
# Description:tomcat服务器重启脚本
# =======================================================

# 定义项目文件名称
readonly PROJECT_FILE="ROOT.war"
PRG="$0"
# 获取重启脚本路径
PRGDIR=$(dirname ${PRG})
# 获取tomcat服务器目录
[ -z "${CATALINA_HOME}" ] && CATALINA_HOME=$(
  # shellcheck disable=SC2164
  cd "${PRGDIR}"/.. >/dev/null
  pwd
)

# 执行前检查
function check() {
  if [[ ! -f ${CATALINA_HOME}/bin/${PRG} ]]; then
    echo "not found script"
    exit 1
  fi
  if [[ ! -x ${CATALINA_HOME}/bin/${PRG} ]]; then
    echo "the script is not executable"
    exit 1
  fi
  if [[ ! -f ${CATALINA_HOME}/webapps/${PROJECT_FILE} ]]; then
    echo "not found web file"
    exit 1
  fi
}

function restart() {
    rm -rf ${CATALINA_HOME}/webapps/ROOT
    # shellcheck disable=SC2006
    PID=`ps -ef | grep -v grep | grep "${CATALINA_HOME}/bin/bootstrap.jar" | awk '{print $2}'`
    if [ "${PID}" = "" ]; then
        echo "tomcat is not active, next, to start"
        ${CATALINA_HOME}/bin/startup.sh
        echo "tomcat is started"
     else
	#${CATALINA_HOME}/bin/shutdown.sh
        sleep 3
        kill -9 ${PID}
        ${CATALINA_HOME}/bin/startup.sh
        echo "tomcat is started"
     fi
}

check && restart


注意点:

  1. 注意点一:

    带有重定向符的EOF一定要顶头写,否则结尾符号(暂且就这样叫吧)EOF不会起作用。并且 EOF带有单引号和不带有单引号的区别是:当带有单引号的EOF时,在EOF框定的脚本中的表达式不会解析,会原样输出,而不带单引号时,EOF框定的脚本中的表达式会被解析。

  2. 注意点二:
    注意点二和注意点五都是阻止Jenkins在pipeline执行完毕后会杀死子进程的情况发生,详细了解可以查看Jenkins的说明。如果在脚本执行前不加那句export BUILD_ID=dontkillme,可以在Jenkins启动的时候加上:-Dhudson.util.ProcessTree.disable=true这句话(我是使用war包启动的)。

  3. 注意点三:一定要使用source执行处理历史版本的shell脚本,否则执行keepfive.sh会报 not found script 错误,至于sh、bash、./、source执行脚本的区别大家可以自行去度娘(fork、source、exec)。

  4. 注意点四:加载脚本的执行环境,以防止脚本执行的时候环境加载不全而导致某些命令报错(eg:not found command)

  5. 注意点六:此时就不可以使用source来执行了,一定要创建子进程来执行tomcat重启脚本(其实如果使用source来执行也不是不可以,只是tomcat重启脚本就需要改造了,而且会因服务器不同而造成脚本代码不同)。

  6. 注意点七:远程执行的命令就直接使用./来执行并且也不需要添加《注意点二》的代码了

  7. 注意点八:远程执行完一定要退出远程登录。因为是远程执行命令,所以知道为啥《注意点七》不用加那句话了吧。


最后:

好了,就先记录到这儿吧,欢迎大家提出优秀的观点和意见。

天天搬砖天天有,天天有砖天天搬。

加油!!!

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值