文章目录
告知
作者对jenkins并未做到深入的了解和使用,所以该篇内容建立在作者暂时未找到jenkins自带备份回滚操作的基础之上,如果有大神知道,请告知作者;
正文
1. 备份回滚方式
利用jenkins的ssh的功能,在目标服务器上执行编辑好的备份回滚shell脚本;
2. 依赖环境
- jenkins自动化构建工具(请自行百度构建jenkins)
- maven 工具(本篇采用maven项目的方式构建,请确保jenkins运行环境中安装有maven环境)
- jenkins插件:Maven Integration plugin (配合2使用)
- jenkins插件:Publish Over SSH ,用于和目标服务器进行远程连接,并执行构建,备份,回滚等操作;
3. 备份回滚思路
4. 依赖shell脚本
4.1 备份脚本
## =============== backups.sh
## 回滚判断,如果该次操作为回滚操作,则不备份处理
rollbackFile=`ls | grep rollback`
if [ $rollbackFile == "rollback" ]
then
##回滚版本
version=`cat $rollbackFile`
if [ ! $version ]
then
echo "version is null"
exit 1
fi
if grep '^[[:digit:]]*$' <<< "$version"
then
echo "Perform a rollback operation,Rollback operation, the current version is not backed up..."
exit 1
fi
fi
## 首次操作,没有.jar 文件不予备份
files=`ls | grep -v ".sh" | grep -v "rollback"`
if [ ! $files ]
then
echo "首次构建,不予备份"
exit 1
fi
echo "Normal build, perform backup processing..."
##当前日期
date=`date +%Y%m%d%H%M%S`
##备份文件数量
backupCount=5
##工作目录
workDir=`pwd`
## 工作目录名
workName=`pwd | xargs basename`
## 备份文件目录
nextBackupDir=
## >>> 获取备份文件目录
## 上级目录
cd ..
## 创建并进入备份目录
mkdir "backups"
cd backups
## 创建并进入工作备份目录
mkdir $workName
cd $workName
##备份数量
backupNumber=`ls -l | grep "^d" | wc -l`
## 下一个备份文件数
nextBackupNumber=$[backupNumber+1]
## 备份文件大于约定备份数量,则删除一个
if [ $nextBackupNumber -gt $backupCount ]
then
echo "delete start backup file "
##删除最先创建的那一个
ls -ltr | grep -v 'total' | grep -v "总用量" | grep "^d" | awk '{print $9}' | head -n 1 | xargs rm -rf
fi
## 下一个备份文件名
nextBackupName=$date+$nextBackupNumber
## 老得文件名
oldBackupName=`ls | grep "$nextBackupName"`
## 判断是否存在相同文件名,并重新生成
while [[ $nextBackupName == $oldBackupName ]]
do
echo "backup file name is exists ,ready to generete"
nextBackupNumber=$[$nextBackupNumber+1]
nextBackupName=$date+$nextBackupNumber
oldBackupName=`ls | grep "$nextBackupName"`
done
## 创建备份文件目录
mkdir $nextBackupName
cd $nextBackupName
nextBackupDir=`pwd`
##回到工作目录
cd $workDir
## 备份当前非sh文件
ls | grep -v ".sh" | grep -v "list" | xargs -i -t cp {} $nextBackupDir
## 删除当前非sh,sh.info.list文件
ls | grep -v "sh" | grep -v "list" | xargs -i -t rm -rf {}
echo "backup file over"
##
4.2 校验并回滚shell脚本
#============== checkRollBack.sh
## 回滚文件
rollbackFile=`ls | grep rollback`
if [ $rollbackFile == "rollback" ]
then
##回滚版本
version=`cat $rollbackFile `
if [ ! $version ]
then
echo "version is null"
exit 1
fi
if grep '^[[:digit:]]*$' <<< "$version"
then
echo "Perform a rollback operation, rolling back to the first $version"
##工作目录
workDir=`pwd`
## 工作目录名
workName=`pwd | xargs basename`
##删除当前非.sh 和 sh.info.list 文件
rm -rf $(ls | grep -v "sh" | grep -v "sh.info.list")
##进入备份文件复制回滚版本
cd ../backups/$workName
###获取符合要求的文件
targetFile=`ls -ltr | grep -v 'total' | grep -v "总用量" | awk '{print $9}' | head -n $version | tail -n 1`
echo "copy file name : $targetFile"
##copy 内容到工作路径
cp -R $targetFile/. $workDir/.
echo "rollback over"
else
echo "The rollback content must be of type numeric"
fi
else
echo "No file rollback, normal build"
fi
4.3 部署运行脚本
###============start.sh
## 项目名称
projectName=`ls | grep ".jar" | sed -E "s/(.*)\.jar{1}/\1/"`
## jar应用名
jarName=`ls | grep ".jar"`
echo "$projectName启动应用中..."
## java环境设置
export JAVA_HOME=/usr/local/jdk1.8
echo ${JAVA_HOME}
## 授权给jar应用,使具有执行权限
chmod 777 $jarName
## 项目信息文件
## oldPid
oldPid=
shInfoList=`ls | grep 'sh.info.list'`
if [ $shInfoList == "sh.info.list" ]
then
oldPid=`cat $shInfoList | grep pid | sed -E "s/(.*)={1}(.*)/\2/"`
echo "获取到老版pid: $oldPid"
fi
## port 获取
port=
if ls | grep "application.properties"
then
echo "application.properties存在,获取当前应用的端口号"
port=`cat application.properties | grep "server.port" | cut -d "=" -f 2 | awk '$1=$1' | tr -cd "[0-9]"`
elif ls | grep "application.yml"
then
echo "application.yml存在,获取当前应用的端口号"
port=`cat application.yml | grep "port:" | cut -d ":" -f 2 | awk '$1=$1' | tr -cd "[0-9]"`
else
echo "application 文件不存在,不能获取应用端口,将使用jar包的方式直接运行"
fi
echo "应用端口:$port"
## dockerFile文件获取
dockerFile=`ls | grep Dockerfile`
## 应用启动方式判断
if [ $dockerFile == "Dockerfile" ] && [ $port != "" ]
then
echo "使用docker方式启动应用..."
## 删除老版应用
## 老版docker容器名称
oldDockerContainerName=$projectName
## 老版docker镜像名称
oldDockerImageName=$projectName
## 停止老版容器
docker stop $oldDockerContainerName
echo "删除老版容器: $oldDockerContainerName"
## 删除老版容器
docker rm $oldDockerContainerName
echo "删除老版容器:$oldDockerContainerName"
## 删除老版镜像
docker rmi $oldDockerImageName
echo "删除老版镜像:$oldDockerImageName"
# 构建项目docker镜像
docker build -t $projectName .
## 工作目录
workDir=`pwd`
## 新启容器
docker run --name $projectName -v $workDir/data:/application -d -p $port:$port $projectName
else
echo "使用jar方式启动应用..."
kill -9 $oldPid
nohup ${JAVA_HOME}/bin/java -jar $jarName > console.log &
pid=`ps -ef | grep $jarName | grep -v grep | head -n 1 | awk '{print $2}'`
##备份应用pid
echo "pid=$pid" > sh.info.list
fi
echo "$projectName 启动成功"
5. 脚本说明
5.1 临时文件/回滚文件说明
5.1.1 sh.info.list 临时文件
脚本运行中会生成一个零时文件sh.info.list,该文件会保存当前项目的运行的pid信息,当项目以jar的方式部署运行时,在下一次部署时,需要利用该文件中的pid停止掉上次的项目,确保下次能够部署成功;
5.1.2 rollback 回滚文件
脚本的回滚操作需要jenkins从构建参数中获取回滚标识,并写入到rollback中,传入给目标服务器
5.2 脚本优化建议
该脚本有很多地方可以优化,建议点;
1. jenkins上传的rollback文件,可以修改为脚本执行的参数文件,使脚本不止拥有回滚功能;如:停止功能;
2. 可为脚本添加一个配置文件,以在脚本运行期可获取更多执行信息,和执行更多其他功能;
6. 使用
使用说明:
1. 需要在目标服务器建立目标工作目录,并将shell脚本copy到工作目录中;
2. 下面 cd /home/jenkisn/test 等操作,是切入到目标工作目录,请更换为自定义工作目录
6.1 新建maven项目
6.2 配置项目信息
参数化构建,可执行定义
上传构建参数,并执行备份操作
构建项目
【部署方式选择一】jar方式构建,只需要传递jar包即可
【部署方式选择二】docker方式构建,需要上传Dockerfile文件和application配置文件,application文件用于获取docker映射端口