本文所有的部署都是在CentOS 7上完成,软件安装都采用的是Docker,如果你想跟着这个教程搭建,需要准备一下环境:
以下两台测试机器的IP和功能点
docker-compose
由于是工具类的软件,为了减少对机器的侵入, Jenkins 和代码仓库 GitLab的安装都是采用的Docker的方式,所以请提前安装好Docker。
准备挂载目录,用于持久化数据
mkdir -p /var/jenkins/datachmod 777 /var/jenkins/datacd /var/jenkins/data
查看Docker的组ID
重要!这个步骤很重要,因为后续Jenkins使用的是宿主机的 Docker ,所以在启动的时候,就需要做好Docker的映射以及权限组ID的配置;
cat /etc/group | grep docker
每台电脑都会有所差异,下面是我两台虚拟机对应的ID;
记住你装Jenkins那一台的ID,在下个步骤配置docker-compose时,需要在group_add
中配置上对应的ID;这里务必要配置正确,否则后面在Jenkins容器中使用Docker命令时,会报权限不足的错误。
准备docker-compose-jenkins.yml配置文件
vim docker-compose-jenkins.yml
#添加以下配置
version: '2'
services:
jenkins:
container_name: 'jenkins'
image: 'jenkins/jenkins'
restart: always
environment:
TZ: 'Asia/Shanghai'
ports:
- '8880:8080'
- '50000:50000'
group_add:
- 994
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /usr/bin/docker:/usr/bin/docker
- /var/jenkins/data:/var/jenkins_home
- /usr/local/apache-maven-3.8.6:/usr/local/apache-maven-3.8.6
启动
# 启动docker-compose -f docker-compose-jenkins.yml up -d# 查看容器docker ps | grep jenkins
初始化:容器启动,大约等1分钟之后,就可以来初始化Jenkins了,安装推荐插件:参考之前的文章去选择。默认也可以。
后续还需要用到一些插件,这里提前安装一下。安装入口:系统管理-->插件管理-->可选插件。注意!所有插件在重启之后才会生效
Maven Integration
安装Maven相关插件主要是配置一些基础的环境,比如Maven、Git、JDK等工具,便于后续构建的时候,能够直接使用这些全局的基础配置。
Maven配置:这里的Maven是容器启动时,映射的宿主机的包,如果你是下载的其他的版本或者映射的其他路径,请根据实际情况调整;
可以通过配置 MAVEN_OPTS 避免编译复杂项目时出现内存泄漏等问题。
Docker安装的Jenkins容器自带了JDK,所以这里只需要拿到容器内的JDK路径,配置上即可;获取当时如下:
# 进去容器docker exec -it jenkins /bin/bash# 输出JDK的环境变量echo $JAVA_HOME
这里配置的是远端服务器的信息(也就是代码最终运行的服务器信息);
GitLab 是一个用于仓库管理系统的开源项目,使用 Git 作为代码管理工具,并在此基础上搭建起来的Web服务。
准备docker-compose
version: '2'
services:
gitlab:
container_name: 'gitlab-ce-zh'
image: 'twang2218/gitlab-ce-zh'
restart: unless-stopped
hostname: 'gitlab'
environment:
TZ: 'Asia/Shanghai'
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://192.168.1.253:880'
ports:
- '880:880'
- '8443:443'
- '2212:22'
volumes:
- /var/gitlab/etc:/etc/gitlab
- /var/gitlab/log:/var/log/gitlab
- /var/gitlab/data:/var/opt/gitlab
其中external_url
中的IP为你本地机器的IP;地址的端口和容器映射的端口要保持一致,否则将无法访问。
启动
docker-compose -f docker-compose-gitlab.yml up -ddocker ps | grep gitlab
状态变成healthy
,说明服务已经正常。
访问上一步的external_url
(本机:http://192.168.1.253:880)设置管理员密码。
设置完之后,就使用root
和你新设置的密码,登录即可进入gitlab的主页。
由于后续Jenkins需要自动在Gitlab中获取最新的代码,因此,需要提前配置身份认证令牌。
hYw-Qy6KxGFsdzGA96Ux
每次创建的都会不一样;而且,这个令牌只会显示一次,之后就不会再显示了,所以请保存好;否则就只能重新生成了;
将前面步骤生成的GitLab令牌配置成Jenkins的全局凭据,以方便后续的使用。
选择管理凭据
点击Jenkins
点击全局凭据
点击添加凭据
输入Token:选择GitLab API token
,然后输入前一步在GitLab中创建好的token
创建成功:点击Create
按钮即可创建凭据
本教程使用的源码:https://github.com/vehang/ehang-spring-boot
jenkins
分支,推送到本地Gitlab仓库。此脚本的作用就是将Jenkins传到运行服务器的Jar包给跑起来;下面只是一个最基础的脚本,个人可以根据实际的使用过程,再进行调整;
#!/bin/sh
# JDK的环境变量
export JAVA_HOME=/usr/local/jdk-11.0.14
export PATH=$JAVA_HOME/bin:$PATH
# 基础路径,由参数传入
# 多模块的时候,需要在路径中使用*统配一下多模块
# 比如/opt/ehang-spring-boot是多模块,下面由module1和module2
# 那么执行shell的时候使用:sh restart.sh /opt/ehang-spring-boot/\* 注意这里的*需要转义一下
JAR_BATH=$1
echo "基础路径:"$JAR_BATH
JAR_PATH=${JAR_BATH}/target/*.jar
# 获取所有的JAR 开始遍历
for JAR_FILE in $JAR_PATH
do
if [ -f $JAR_FILE ]
then
echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
echo "JAR路径:"$JAR_FILE
JAR_FILE_MD5=${JAR_FILE}.md5
# 用于标记是否需要重启的标识
RESTART=false
# 判断MD5文件是否存在,存在就校验MD5值
if [ -f $JAR_FILE_MD5 ]; then
# 校验MD5
md5sum --status -c $JAR_FILE_MD5
# = 0表示校验成功 =1 表示校验失败
if [ $? = 1 ];then
echo "MD5校验失败,安装包已经更新!"
RESTART=true
else
echo "安装包没有更新!"
fi
else
echo "没有MD5值,说明是第一次启动"
RESTART=true
fi
# 获取进程号
PROCESS_ID=`ps -ef | grep $JAR_FILE | grep -v grep | awk '{print $2}'`
# 如果不需要重启,但是进程号没有,说明当前jar没有启动,同样也需要启动一下
if [ $RESTART == false ] && [ ${#PROCESS_ID} == 0 ] ;then
echo "没有发现进程,说明服务未启动,需要启动服务"
RESTART=true
fi
# 如果是需要启动
if [ $RESTART == true ]; then
# kill掉原有的进程
ps -ef | grep $JAR_FILE | grep -v grep | awk '{print $2}' | xargs kill -9
#如果出现Jenins Job执行完之后,进程被jenkins杀死,可尝试放开此配置项
#BUILD_ID=dontKillMe
#启动Jar
nohup java -jar $JAR_FILE > ${JAR_FILE}.log 2>&1 &
# =0 启动成功 =1 启动失败
if [ $? == 0 ];then
echo "restart success!!! process id:" `ps -ef | grep $JAR_FILE | grep -v grep | awk '{print $2}'`
else
echo "启动失败!"
fi
# 将最新的MD5值写入到缓存文件
echo `md5sum $JAR_FILE` > $JAR_FILE_MD5
fi
echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
echo ""
fi
done
脚本细节,注释已经写的很清楚了;简单说一下脚本的流程:
*
转义一下;详情见下图target
目录下的所有jar包创建Maven任务
设置gitlab凭据,选择前面步骤配置的凭据。
设置GitLab项目地址:首次配置,这里需要先添加Git仓库的凭据信息,步骤如下:
配置构建命令
clean package -DskipTests=true
注意这里本身就是使用的Maven构建,所以命令不需要在前面加上mvn
构建完后上传文件
上传脚本:在上传Jar包之前,我们需要将项目的启动/重启脚本传到服务器,方便后续jar上传完之后,就能直接执行了。
Transfer Set Source files #表示要传输的文件/文件规则
Remove prefix #要去掉文件的前缀,比如以上配置,默认文件路径是:script/jenkins/abc.sh,在这里配置script/jenkins/就只会将abc.sh拷贝到远端目录,否则,script/jenkins/abc.sh 完整的拷贝过去。
Remote directory #拷贝的远端路径,如果不配置,就是有SSH Server中配置的路径,我ssh server配置的远端路径为/opt/jenkins/package
Exec command #拷贝完之后,执行的脚本
上传Jar包:由于项目是多模块的,打包之后,每个模块都会打出一个jar包,分别放在各个模块的target目录下;我们需要作的就是将所有模块的Jar都拷贝到服务器并启动;
上传成功之后,会在/opt/jenkins/package
目录下看到所有的包信息:
拷贝完之后,将执行shell
脚本,单模块和多模块执行的命令仅仅为参数上的区别:
单模块:以spring-boot-001-hello-world/target/spring-boot-001-hello-world-0.0.1-SNAPSHOT.jar
为单模块的包进行测试,执行的重启脚本为:
sh /opt/jenkins/package/jenkins_restart.sh /opt/jenkins/package/spring-boot-001-hello-world
其中参数/opt/jenkins/package/spring-boot-001-hello-world
为单模块的根目录
多模块:多模块仅仅只是路径不同而已
sh /opt/jenkins/package/jenkins_restart.sh /opt/jenkins/package/*
其中/opt/jenkins/package/*
用于指明/opt/jenkins/package路径下的所有子模块Jar包都重启;其中*
表示通配。
注意:由于这里执行了shell脚本,所以配置的时候,一定要在高级选项中将Exec in pty
勾选上,否则shell命令执行不会终止,直到超时结束,如下日志:
....
SSH: Connecting with configuration [centos_server] ...
SSH: Disconnecting configuration [centos_server] ...
ERROR: Exception when publishing, exception message [Exec timed out or was interrupted after 120,000 ms]
Build step 'Send files or execute commands over SSH' changed build result to UNSTABLE
Finished: UNSTABLE
开启控制台的输出日志:初次配置的时候,容易出现异常情况,为了方便排查问题,可以勾上下图左侧的选项,输出远端服务器执行日志;下图右侧中的日志就是远端执行shell脚本的输出;不勾选将不会有这些日志。
选择项目,点击“立即构建”即可开始,执行完如果是绿色,说明构建成功,红色表示失败。
Jenkins任务开启监听:前面的手动构建已经完成了,我们最终的目的是希望能够做到代码一提交,就自动构建并发布。
Jenkins中开启Gitlab的监听,并设置一个token(可以不设置)
配置好之后,得到了以下的信息:
GitLab配置钩子
找到项目之后,按着上图的步骤,将jenkins的地址、token以及触发条件配置好后,点击添加按钮;
下面就来通过git提交一段代码,看能否自动触发 https://img-blog.csdnimg.cn/img_convert/3c49134400fafb8f3301d2a4e99efe72.gif 动图中可以看到,当代码成功push
2秒之后,Jenkins就已经自动开始构建任务了。执行完之后,查看Jenkins的日志与Linux的服务进程,服务已经正常启动。
上面写的jenkins_restart.sh脚本,在多模块部署的时候,没办法检测到未更新的模块。假如一个项目,分了10个小模块,类似于下图:
本次修改,只是模块①修复了1个Bug,其他9个都没有变动,那么编译打包整个项目之后,也只需要更新模块①即可,其他的9个模块完全可以不做任何操作,要做到这一需求,就需要在这10个模块中找出那些模块更新了,那些没有更新;上篇文章中采用的方案是:计算 jar 包的MD5,如果MD5值一样,说明没有更新。
下面就一起来把之前的那个教程再完善一下!
MD5 判断文件是否改变,这思路似乎没有任何问题;代码既然没做任何改变,所有文件结构目录也相同,那按理说打出来的Jar包的MD5值应该是一样的,但为什么会有问题呢?为了验证这个问题,对项目连续打两次包,分别得到两个相同大小的a.jar
和b.jar
;然后做了MD5计算,发现确实不一样:
然后Beyound对两个包进行比较,发现除了修改时间不同,文件内容也都是一摸一样的;
原因:Zip在压缩的时候,会将将文件的access time写入到压缩包中,压缩包里面虽然保存的文件内容虽然是一致的,但由于时间不同,导致最终压缩包的MD5值也就不一致;因此,jar 包所面临的问题就属于类似的情况。
既然知道包里面的文件都是一样的,只是由于压缩带来的问题,我们完全可以换个思路来解决,将Jar包解压之后,判断各个文件是否发生变化,同样也能够校验出来,过程如下:
如果Jar都没有重新编译打包,那不用说,MD5值肯定相同;
unzip
命令解压Jar包如果直接校验Jar没通过,就继续以解压校验文件详情的方式进行校验;
unzip app.jar -d /tmp/jar_unzip_tmp
find
命令查找解压目录下的所有文件并计算MD5值find /tmp/jar_unzip_tmp -type f -print | xargs md5sum > ./jar_files
# 上面的这条命令等价于下面这个for循环
#for file in `find /tmp/jar_unzip_tmp`
#do
# if [ -f $file ];then
# echo $file
# `md5sum $file >> ./jar_files`
# fi
#done
得到的jar_files
;左侧表示文件的MD5值,右侧为文件的路径;如果文件内容发生变化,左侧MD5就会不同,如果是结构/目录发生变化,右侧的详细路径就会不一样;
如果代码发生变化、目录结构发生变化,得到的文件详情列表就是产生差异,那根据详情列表得到的MD5值也就不同了
本文的主要目的是:优化多模块的自动化构建,能感知变化,只自动部署已经修改的模块;
通过上面的原因分析以及解决方案梳理,需要调整一下相关的脚本;
以下的内容是基于上面内容的改进:SSH的方式主要是修改jenkins_restart.sh
脚本
把这个脚本的修改带入到前文的对应的地方,就能正常使用了;如果还没有看过前文,麻烦稍微花点时间阅读一下,再继续往下看;
主要的修改是在jenkins_restart.sh
脚本上,当Jar被传到运行服务,执行jenkins_restart.sh
脚本启动各个模块的时候,解压检测,变化的就重启,没变的就跳过。
#!/bin/sh
# JDK的环境变量
export JAVA_HOME=/usr/local/jdk-11.0.14
export PATH=$JAVA_HOME/bin:$PATH
# 基础路径,由参数传入
# 多模块的时候,需要在路径中使用*统配一下多模块
# 比如/opt/ehang-spring-boot是多模块,下面由module1和module2
# 那么执行shell的时候使用:sh restart.sh /opt/ehang-spring-boot/\* 注意这里的*需要转义一下
JAR_BATH=$1
echo "基础路径:"$JAR_BATH
JAR_PATH=${JAR_BATH}/target/*.jar
# jar_check_md5 通过jar的md5值直接检测
# jar_unzip_check_md5 通过对jar包解压 校验文件详情的MD5
# check_md5 汇总上面两个方法的校验
# 直接通过jar校验
jar_check_md5() {
# jar 包的路径
JAR_FILE=$1
if [ ! -f $JAR_FILE ]; then
# 如果校验的jar不存在 返回失败
return 1
fi
JAR_MD5_FILE=${JAR_FILE}.md5
echo "Jenkins Docker镜像构建校验 JAR的MD5文件:"$JAR_MD5_FILE
if [ -f $JAR_MD5_FILE ]; then
md5sum --status -c $JAR_MD5_FILE
RE=$?
md5sum $JAR_FILE > $JAR_MD5_FILE
return $RE
else
md5sum $JAR_FILE > $JAR_MD5_FILE
fi
return 1
}
# 将Jar解压之后校验
jar_unzip_check_md5() {
# jar 包的路径
UNZIP_JAR_FILE=$1
if [ ! -f $UNZIP_JAR_FILE ]; then
# 如果校验的jar不存在 返回失败
return 1
fi
# jar的名称
UNZIP_JAR_FILE_NAME=`basename -s .jar $UNZIP_JAR_FILE`
echo "Jenkins Docker镜像构建校验 JAR包名称:"$UNZIP_JAR_FILE_NAME
# jar所在的路径
UNZIP_JAR_FILE_BASE_PATH=${UNZIP_JAR_FILE%/${UNZIP_JAR_FILE_NAME}*}
echo "Jenkins Docker镜像构建校验 JAR包路径:"$UNZIP_JAR_FILE_BASE_PATH
# 解压的临时目录
JAR_FILE_UNZIP_PATH=${UNZIP_JAR_FILE_BASE_PATH}/jar_unzip_tmp
echo "Jenkins Docker镜像构建校验 解压路径:"$JAR_FILE_UNZIP_PATH
# 用于缓存解压后文件详情的目录
UNZIP_JAR_FILE_LIST=${UNZIP_JAR_FILE_BASE_PATH}/${UNZIP_JAR_FILE_NAME}.files
echo "Jenkins Docker镜像构建校验 jar文件详情路径:"$UNZIP_JAR_FILE_LIST
# 缓存解压后文件详情的MD5
UNZIP_JAR_FILE_LIST_MD5=${UNZIP_JAR_FILE_BASE_PATH}/${UNZIP_JAR_FILE_NAME}.files.md5
echo "Jenkins Docker镜像构建校验 jar文件详情MD5校验路径:"$UNZIP_JAR_FILE_LIST
rm -rf $JAR_FILE_UNZIP_PATH
mkdir -p $JAR_FILE_UNZIP_PATH
# 解压文件到临时目录
unzip $UNZIP_JAR_FILE -d $JAR_FILE_UNZIP_PATH
# 遍历解压目录,计算每个文件的MD5值及路径 输出到详情列表文件中
find $JAR_FILE_UNZIP_PATH -type f -print | xargs md5sum > $UNZIP_JAR_FILE_LIST
rm -rf $JAR_FILE_UNZIP_PATH
if [ ! -f $UNZIP_JAR_FILE_LIST_MD5 ]; then
# 如果校验文件不存在 直接返回校验失败
md5sum $UNZIP_JAR_FILE_LIST > $UNZIP_JAR_FILE_LIST_MD5
return 1
fi
# 根据上一次生成的MD5校验
md5sum --status -c $UNZIP_JAR_FILE_LIST_MD5
RE=$?
# 生成最新的文件列表的MD5
md5sum $UNZIP_JAR_FILE_LIST > $UNZIP_JAR_FILE_LIST_MD5
# 返回校验结果
return $RE
}
check_md5() {
# jar 包的路径
JAR_FILE=$1
if [ -f $JAR_FILE ]; then
# 直接通过jar校验
jar_check_md5 $JAR_FILE
if [ $? = 0 ];then
echo "Jenkins Docker镜像构建校验 通过Jar的MD5校验成功"
return 0
else
echo "Jenkins Docker镜像构建校验 通过Jar的MD5校验失败"
fi
# 通过解压jar 校验是否更新
jar_unzip_check_md5 $JAR_FILE
if [ $? = 0 ];then
echo "Jenkins Docker镜像构建校验 通过解压的MD5校验成功"
return 0
else
echo "Jenkins Docker镜像构建校验 通过解压的MD5校验失败"
fi
fi
return 1
}
# 获取所有的JAR 开始遍历
for JAR_FILE in $JAR_PATH
do
if [ -f $JAR_FILE ]
then
echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
echo "JAR路径:"$JAR_FILE
APP_UPDATE=false
check_md5 $JAR_FILE
if [ $? = 0 ];then
echo "Jenkins Docker镜像构建校验lib!成功,没有发生变化"$JAR_FILE
else
APP_UPDATE=true
echo "Jenkins Docker镜像构建校验lib!失败,已经更新"$JAR_FILE
fi
# 获取进程号 判断当前服务是否启动;如果Jar没变,但是服务未启动,也需要执行启动脚本
PROCESS_ID=`ps -ef | grep $JAR_FILE | grep -v grep | awk '{print $2}'`
# 如果不需要重启,但是进程号没有,说明当前jar没有启动,同样也需要启动一下
if [ $APP_UPDATE == false ] && [ ${#PROCESS_ID} == 0 ] ;then
echo "没有发现进程,说明服务未启动,需要启动服务"
APP_UPDATE=true
fi
# 如果是需要启动
if [ $APP_UPDATE == true ]; then
# kill掉原有的进程
ps -ef | grep $JAR_FILE | grep -v grep | awk '{print $2}' | xargs kill -9
#如果出现Jenins Job执行完之后,进程被jenkins杀死,可尝试放开此配置项
#BUILD_ID=dontKillMe
#启动Jar
nohup java -jar $JAR_FILE > ${JAR_FILE}.log 2>&1 &
# =0 启动成功 =1 启动失败
if [ $? == 0 ];then
echo "restart success!!! process id:" `ps -ef | grep $JAR_FILE | grep -v grep | awk '{print $2}'`
else
echo "启动失败!"
fi
fi
echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
echo ""
fi
done
稍微有点点长,这里分段来说明一下,详细的细节,可以查看对应的注释。
公共方法:直接通过Jar的MD5值检测
# 直接通过jar校验
jar_check_md5() {
# jar 包的路径
JAR_FILE=$1
if [ ! -f $JAR_FILE ]; then
# 如果校验的jar不存在 返回失败
return 1
fi
JAR_MD5_FILE=${JAR_FILE}.md5
echo "Jenkins Docker镜像构建校验 JAR的MD5文件:"$JAR_MD5_FILE
if [ -f $JAR_MD5_FILE ]; then
md5sum --status -c $JAR_MD5_FILE
RE=$?
md5sum $JAR_FILE > $JAR_MD5_FILE
return $RE
else
md5sum $JAR_FILE > $JAR_MD5_FILE
fi
return 1
}
公共方法:通过解压Jar,根据文件详情的MD5值检验是否改变
# 将Jar解压之后校验
jar_unzip_check_md5() {
# jar 包的路径
UNZIP_JAR_FILE=$1
if [ ! -f $UNZIP_JAR_FILE ]; then
# 如果校验的jar不存在 返回失败
return 1
fi
# jar的名称
UNZIP_JAR_FILE_NAME=`basename -s .jar $UNZIP_JAR_FILE`
echo "Jenkins Docker镜像构建校验 JAR包名称:"$UNZIP_JAR_FILE_NAME
# jar所在的路径
UNZIP_JAR_FILE_BASE_PATH=${UNZIP_JAR_FILE%/${UNZIP_JAR_FILE_NAME}*}
echo "Jenkins Docker镜像构建校验 JAR包路径:"$UNZIP_JAR_FILE_BASE_PATH
# 解压的临时目录
JAR_FILE_UNZIP_PATH=${UNZIP_JAR_FILE_BASE_PATH}/jar_unzip_tmp
echo "Jenkins Docker镜像构建校验 解压路径:"$JAR_FILE_UNZIP_PATH
# 用于缓存解压后文件详情的目录
UNZIP_JAR_FILE_LIST=${UNZIP_JAR_FILE_BASE_PATH}/${UNZIP_JAR_FILE_NAME}.files
echo "Jenkins Docker镜像构建校验 jar文件详情路径:"$UNZIP_JAR_FILE_LIST
# 缓存解压后文件详情的MD5
UNZIP_JAR_FILE_LIST_MD5=${UNZIP_JAR_FILE_BASE_PATH}/${UNZIP_JAR_FILE_NAME}.files.md5
echo "Jenkins Docker镜像构建校验 jar文件详情MD5校验路径:"$UNZIP_JAR_FILE_LIST
rm -rf $JAR_FILE_UNZIP_PATH
mkdir -p $JAR_FILE_UNZIP_PATH
# 解压文件到临时目录
unzip $UNZIP_JAR_FILE -d $JAR_FILE_UNZIP_PATH
# 遍历解压目录,计算每个文件的MD5值及路径 输出到详情列表文件中
find $JAR_FILE_UNZIP_PATH -type f -print | xargs md5sum > $UNZIP_JAR_FILE_LIST
rm -rf $JAR_FILE_UNZIP_PATH
if [ ! -f $UNZIP_JAR_FILE_LIST_MD5 ]; then
# 如果校验文件不存在 直接返回校验失败
md5sum $UNZIP_JAR_FILE_LIST > $UNZIP_JAR_FILE_LIST_MD5
return 1
fi
# 根据上一次生成的MD5校验
md5sum --status -c $UNZIP_JAR_FILE_LIST_MD5
RE=$?
# 生成最新的文件列表的MD5
md5sum $UNZIP_JAR_FILE_LIST > $UNZIP_JAR_FILE_LIST_MD5
# 返回校验结果
return $RE
}
公共方法:check_md5
check_md5() {
# jar 包的路径
JAR_FILE=$1
if [ -f $JAR_FILE ]; then
# 直接通过jar校验
jar_check_md5 $JAR_FILE
if [ $? = 0 ];then
echo "Jenkins Docker镜像构建校验 通过Jar的MD5校验成功"
return 0
else
echo "Jenkins Docker镜像构建校验 通过Jar的MD5校验失败"
fi
# 通过解压jar 校验是否更新
jar_unzip_check_md5 $JAR_FILE
if [ $? = 0 ];then
echo "Jenkins Docker镜像构建校验 通过解压的MD5校验成功"
return 0
else
echo "Jenkins Docker镜像构建校验 通过解压的MD5校验失败"
fi
fi
return 1
}
判断Jar是否更新
check_md5 $JAR_FILE
if [ $? = 0 ];then
echo "Jenkins Docker镜像构建校验lib!成功,没有发生变化"$JAR_FILE
else
APP_UPDATE=true
echo "Jenkins Docker镜像构建校验lib!失败,已经更新"$JAR_FILE
fi
判断进程是否存在
PROCESS_ID=`ps -ef | grep $JAR_FILE | grep -v grep | awk '{print $2}'`
# 如果不需要重启,但是进程号没有,说明当前jar没有启动,同样也需要启动一下
if [ $RESTART == false ] && [ ${#PROCESS_ID} == 0 ] ;then
echo "没有发现进程,说明服务未启动,需要启动服务"
RESTART=true
fi
剩下的就是重启的逻辑了。
至此,多模块优化就已经弄好了,文中是根据个人的小项目在做演示,思路在文中已经说清楚了,大家可以根据自己实际的业务需求,进行适当调整,以满足自己实际的项目需求。
参考文章:https://blog.csdn.net/a2285786446/article /details/130981868 https://blog.csdn.net/lililidahaoren /article/details/126590979