实现基于Jenkins实现项目的自动化构建和回滚操作,本文分前端的构建回滚和后端的构建回滚,记录一下配置过程中踩下的坑和最终结果。
PS:关于Jenkins的搭建本文不再赘述,主要讲项目的配置
【前端构建与回滚】
我们的项目是Vue框架的,所以前端自动构建采用的是NodeJs+jenkins+GitLab的构建
1.首先在Jenkins下载NodeJS,这里一定要确保自己搭建Jenkins的服务器位数与所下载的NodeJS位数一致,(查看linux位数cat /proc/version 、 uname -a、getconf LONG_BIT都可以),我的是64位,所以此处下载如下:
wget https://nodejs.org/dist/latest/node-v16.1.0-linux-x64.tar.gz
2.把下载好的文件解压到Jenkins的NodeJS路径
tar xvzf node-v16.1.0-linux-x64.tar.gz -C /root/.jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation(/root/.jenkins/tools根据你实际的路径改一下)
3.在Jenkins的全局工具配置里添加NodeJs,别名随意取,目录选择你刚才解压的路径,配置完成后保存
4.新建一个自由风格的项目,名称自己取,项目的配置如下:
4.1.General
参数化构建里添加两个参数,一个是 选项参数,这个是在发布时选择构建还是回滚,一个是字符参数,用来记录BUILD编号,回滚时使用
4.2.源码管理
4.3构建环境
4.4构建–构建和回滚的shell脚本
点击左下角增加构建步骤,选择执行Shell,添加构建和回滚的脚本
具体代码如下:
case $Status in
Deploy)
echo "Status:$Status"
path="/root/.jenkins/workspace/bak/projPortal-H5-Test/${BUILD_NUMBER}" #每次要备份的目录,此目录需要手动创建
cd ${WORKSPACE}
echo "-----------Start build-----------"
npm config set registry https://registry.npm.taobao.org #设置安装源为淘宝
npm install #安装npm
npm run build-test #构建命令,此命令可向前端开发人员要,不同环境可能命令不一样
echo "-----------Start deploy-----------"
scp -P 10087 -r dist username@**.**.**.**:/home/appuser || echo "拷贝dist至应用服务器失败!" #把dist拷贝至远程应用服务器,如果应用服务器在本机,直接cp过去就行
echo "-----------Start backup-----------"
if [ -d $path ];then
echo "备份目录已存在"
else
mkdir -p $path
fi
\cp -r ${WORKSPACE} $path || echo "-----------备份失败!-----------" #复制当前版本代码到历史文件夹
echo "-----------Backup Completing!-----------"
;;
RollBack)
echo "Status:$Status"
echo "Version:$Version"
cd /root/.jenkins/workspace/bak/projPortal-H5-Test/
if [ ! -d "$Version" ];then
echo "回滚版本不存在,请重新选择回滚版本"
cd $Version
exit
else
echo "-----------Start deleting history files-----------"
cd $Version/projPortal-H5-Test #进入备份目录
echo "$Version" #输出获取的版本号
rm -rf ${WORKSPACE}/* #删除工作空间代码
echo "-----------Copy the backup file to the working directory-----------"
\cp -r ./* ${WORKSPACE} #拷贝历史版本至工作空间
echo "-----------Start roolback-----------"
scp -P 10087 -r dist appuser@10.50.2.4:/home/appuser || echo "拷贝dist至应用服务器失败!" #拷贝dist文件夹至应用服务器
exit
echo "-----------RollBack Completing!-----------"
fi
;;
esac
再次添加一个shell,用来判断备份目录数量,先设定一个备份上限值,若超出上限,则删除最早的备份
ReservedNum=10 #保留文件数
FileDir="/root/.jenkins/workspace/bak/projPortal-H5-Test"
date=$(date "+%Y%m%d-%H%M%S")
cd $FileDir #进入备份目录
FileNum=$(ls -l | grep '^d' | wc -l) #当前有几个文件夹,即几个备份
while(( $FileNum > $ReservedNum))
do
OldFile=$(ls -rt | head -1) #获取最旧的那个备份文件夹
echo $date "Delete File:"$OldFile
rm -rf $FileDir/$OldFile
let "FileNum--"
done
保存之后构建就可以了。
过程中的坑点:
NodeJS的版本,Jenkins是其他人搭建的,原来有几个NodeJS,我开始使用的是已有的,然后每次构建都报cannot execute binary file,把脚本放到服务器一句一句执行没问题,建一个.sh文件执行也没问题,最后换了NodeJS后解决
【后端的构建与回滚】
基本与前端差不多,采取Maven+jenkins+GitLab构建
1.一样需要先安装maven,在jenkins的系统管理-全局工具配置里点击添加Maven,自动安装
2.创建一个自由风格的项目,名称自定,配置如下
2.1Gener
参数化构建过程通前端一致
2.2源码管理
源码管理也与前端一致
2.3构建
点击增加构建步骤,选择调用顶层Maven目标,选择你安装的Maven,输入构建命令
点击增加构建步骤,添加执行Shell
脚本如下:
case $Status in
Deploy)
echo "Status:$Status"
path="/root/.jenkins/workspace/bak/projPortal-front-Test/${BUILD_NUMBER}" #每次要备份的目录
echo "-----------Start deploy------------"
cd ${WORKSPACE}
scp -P 10087 projportal-front/target/projportal-front*.jar username@**.**.**.**:/home/appuser/projportal-front_test.jar ||echo "拷贝jar包至应用服务器失败" #拷贝jar包至远程应用服务器,如果应用服务器在本机,直接cp就行
ssh -p username@**.**.**.** 'kill -9 $(/usr/sbin/lsof -i:8083 -t)'||echo "进程不存在" #杀掉原应用进程
BUILD_ID=DONTKILLME
ssh -p 10087 username@**.**.**.** 'nohup java -jar projportal-front*.jar --spring.profiles.active=test --server.port=8083 >logs/projportal-front_nohup.log 2>&1 &'||echo "服务启动失败" #重启应用进程
echo "-----------Start backup------------"
if [ -d $path ];then
echo "备份目录已存在"
else
mkdir -p $path
fi
\cp -r ${WORKSPACE} $path || echo "-----------备份失败-----------" #复制当前版本代码到历史文件夹
echo "-----------Backup Completing!-----------"
;;
RollBack)
echo "Status:$Status"
echo "Version:$Version"
cd /root/.jenkins/workspace/bak/projPortal-front-Test/
if [ ! -d "$Version" ];then
echo "回滚版本不存在,请重新选择回滚版本"
cd $Version
exit
else
echo "-----------Start deleting history files-----------"
rm -rf ${WORKSPACE}/* #删除工作空间代码
cd /root/.jenkins/workspace/bak/projPortal-front-Test/$Version/projPortal-front-Test #进入备份目录
echo $Version #输出获取的版本号
echo "-----------Copy the backup file to the working directory-----------"
\cp -r ./* ${WORKSPACE} #拷贝历史版本至工作空间
cd ${WORKSPACE}
scp -P 10087 projportal-front/target/projportal-front*.jar username@**.**.**.**:/home/appuser/projportal-front_test.jar ||echo "拷贝jar包至应用服务器失败" #拷贝jar包到应用服务器
ssh -p 10087 username@**.**.**.** 'kill -9 $(/usr/sbin/lsof -i:8083 -t)'||echo "进程不存在"
BUILD_ID=DONTKILLME
ssh -p 10087 username@**.**.**.** 'nohup java -jar projportal-front*.jar --spring.profiles.active=test --server.port=8083 >logs/projportal-front_nohup.log 2>&1 &'||echo "服务启动失败"
exit
echo "-----------RollBack Completing!------------"
fi
;;
esac
再添加一个shell,管理备份数量,同前端脚本
ReservedNum=10 #保留文件数
FileDir="/root/.jenkins/workspace/bak/projPortal-front-Test"
date=$(date "+%Y%m%d-%H%M%S")
cd $FileDir #进入备份目录
FileNum=$(ls -l | grep '^d' | wc -l) #当前有几个文件夹,即几个备份
while(( $FileNum > $ReservedNum))
do
OldFile=$(ls -rt | head -1) #获取最旧的那个备份文件夹
echo $date "Delete File:"$OldFile
rm -rf $FileDir/$OldFile
let "FileNum--"
done
过程中的坑点
最初的SHELL脚本中对远程服务器的IP和用户名都做了参数化,然后构建的时候报连接超时,但是单独执行SSH语句和方到Jenkins的sh脚本中执行是没有问题,后来把参数化的全改回来了,目前仍未明白到底什么原因,有看到此处的大佬希望能给个解答