Jenkins自动构建部署SpringCloud项目

2 篇文章 0 订阅
1 篇文章 0 订阅

Jenkins 在项目中的使用理解为:在 Jenkins 服务器将项目打包备份,然后将包发送到远程应用服务器,然后脚本启动包,完事!

一、Jenkins 安装和配置

1. Jenkins 安装

环境:centos8
参考:https://www.jenkins.io/doc/book/installing/linux/#red-hat-centos

sudo install wget
sudo wget -O /etc/yum.repos.d/jenkins.repo \
    https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
sudo yum upgrade
sudo yum install jenkins java-1.8.0-openjdk-devel
sudo systemctl daemon-reload
sudo systemctl start jenkins
sudo systemctl status jenkins
# 默认8080端口,开启端口
sudo firewall-cmd --zone=public --permanent --add-port 8080/tcp
sudo firewall-cmd --reload
sudo firewall-cmd --zone=public --query-port=8080/tcp
# 安装 maven 和 git
sudo yum install git
sudo yum install maven

默认配置文件在/etc/sysconfig/jenkins,可以修改端口等信息

2. 启动和配置

http://localhost:8080
在这里插入图片描述
获取管理员密码

$ sudo cat /var/lib/jenkins/secrets/initialAdminPassword
2dd8c576a3634e2a93f0ede7c13132bf

默认安装推荐插件,安装可能会失败,重试即可。
在这里插入图片描述
创建一个用户
在这里插入图片描述

3. 安装配置插件

3.1 Publish Over SSH

将 build 好的文件上传到远程 linux 的指定目录下,在插件管理中搜索并安装改插件
在这里插入图片描述

3.2 Config File Provider(非必须)

maven 设置 settings.xml 使用,安装成功后配置
在这里插入图片描述
在这里插入图片描述
在 Content 中配置自己的仓库地址即可
在这里插入图片描述
也可以修改我们安装的 maven 的默认的 settings.xml 文件

$ whereis maven
maven: /etc/maven /usr/share/maven
$ cd /usr/share/maven/conf/
$ ls
logging  settings.xml
3.3 Maven Integration(非必须)

maven 构建工具插件,可以在新建项目的时候选择构建一个maven项目,默认是没有该选项的
在这里插入图片描述

3.4 Build Name and Description Setter

自定义 Build History 名称,方便不同模块构建的区分
在这里插入图片描述

4. 全局工具配置

在这里插入图片描述
配置 maven 和 jdk,剩余默认即可
注意:如果 maven 设置 settings.xml 修改的是安装 maven 的 settings.xml,则Maven 配置默认即可
在这里插入图片描述
获取 maven 路径

$ whereis maven
maven: /etc/maven /usr/share/maven

在这里插入图片描述

5. 系统配置

在这里插入图片描述
拉到最后,点击新增SSH Servers添加远程服务器在这里插入图片描述

二、构建可选模块可回滚项目

参考:https://www.jianshu.com/p/af5fecaa8357

mall 项目主要有以下模块:
mall-admin
mall-portal
mall-pay

1. 新建任务,构建一个自由风格的软件项目

在这里插入图片描述

2. 参数化构建过程

2.1 模块选择

新建选项参数:在构建项目时选择模块(构建单体 springboot 应用时不需要)
在这里插入图片描述

2.2 发版还是回滚

新建选项参数:在构建项目时选择是发版还是回滚
在这里插入图片描述
Deploy【发版】
Rollback【回滚】

2.3 回滚版本号

新建字符参数:回滚时指定版本号
在这里插入图片描述

2.4 配置文件选择(非必须)

可以通过以下指定激活的配置文件

spring:
  profiles:
    active: dev

也可以通过启动覆盖指定的配置文件

nohup java -jar -Dspring.profiles.active=${ACTIVE} demo.jar > demo.log 2>&1 &

新建字符参数:指定激活的配置文件
在这里插入图片描述

3. 从 git 克隆代码

在这里插入图片描述
点击添加账号密码

4. 自定义 Build History 名称

在这里插入图片描述
效果如下:
在这里插入图片描述

5. 增加构建步骤

5.1 构建 maven 项目,配置打包参数

在这里插入图片描述
在这里插入图片描述

clean package -pl ${MODULE} -am -Ppre -Dmaven.test.skip=true

  • ${MODULE}:在构建选择模块后可获得模块名,从而决定构建哪个模块
  • -pl:指定只构建单独的模块而不是所有模块
  • -am:构建模块所需要的项目,如公共模块
  • -P:选择激活的配置文件
  • -Dmaven.test.skip=true:跳过测试
5.2 构建执行 shell,项目打包备份、回滚和清理备份

在这里插入图片描述
在这里插入图片描述

# 保留文件数
RESERVED_NUM=5
# 模块文件夹
FILE_DIR=${WORKSPACE}/${MODULE}
# 备份文件夹
FILE_BAK_DIR=${FILE_DIR}/bak
DATE=$(date "+%Y%m%d-%H%M%S")
case ${STATUS} in
    Deploy)
        echo "发版"
        # 创建每次要备份的目录
        path="${FILE_BAK_DIR}/${BUILD_NUMBER}"
        if [ ! -d ${path} ]
        then
            mkdir -p ${path}
        fi
        # 将打包好的war包备份到相应目录,覆盖已存在的目标
        cp -f ${FILE_DIR}/target/*.jar ${path}
        # 进入备份目录
        cd ${FILE_BAK_DIR}
        # 当前有几个文件夹,即几个备份,删除多余备份
        fileNum=$(ls -l | grep '^d' | wc -l)
        while [ ${fileNum} -gt ${RESERVED_NUM} ]
        do
            # 获取最旧的那个备份文件夹
            oldFile=$(ls -rt | head -1)
            echo ${DATE} "删除备份文件:"${oldFile}
            rm -rf ${FILE_BAK_DIR}/${oldFile}
            let "fileNum--"
        done
        echo "备份完成"
        ;;
    Rollback)
        echo "回滚"
        echo "VERSION:${VERSION}"
        # 如果文件夹不存在或文件夹太小,则判断备份文件不存在,直接返回
        if [ ! -d ${FILE_BAK_DIR}/${VERSION} ] || [ $(du -s ${FILE_BAK_DIR}/${VERSION} | awk '{print $1}') -lt 100 ]
        then
            echo "备份文件不存在"
            # 抛出异常,让 Jenkins 构建失败
            set -e
            # 退出
            exit 1
        fi
        # 进入备份目录
        cd ${FILE_BAK_DIR}/${VERSION}
        # 将备份拷贝到程序打包目录中,并覆盖之前的war包
        cp -f *.jar ${FILE_DIR}/target/
        ;;
    *)
        set -e
        exit 1
        ;;
esac

脚本执行失败让 Jenkins 构建失败
参考:jenkins ssh脚本出现错误后怎么才能让jenkins构建失败
注意: 存在一个问题,就是该步骤在远程的SSH Server执行时,不会构建失败,只会显示Finished: UNSTABLE

5.3 构建执行 shell,项目本地打包执行(不在本地启动应用可跳过)

创建 Jenkins 家目录,否则 shell 没有执行权限

cd /home
sudo mkdir jenkins
sudo chown -R jenkins:jenkins jenkins/

添加项目启动命令

export JAVA_HOME PATH CLASSPATH
JAVA_HOME=/opt/jdk1.8.0_281
PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$CLASSPATH
BUILD_ID=dontKillMe
# 模块文件夹
JAR_DIR=${WORKSPACE}/${MODULE}/target
FILE_DIR=/home/jenkins/apps/
JARFILE=${MODULE}-1.0-SNAPSHOT.jar
# 设置超时时间,如果达到超时时间项目还未启动则退出
TIMEOUT=60
# 根据模块使用响应端口号
PORT=0
if [ "mall-admin" == ${MODULE} ]
then
   PORT=31001
elif [ "mall-portal" == ${MODULE} ]
then
   PORT=8085
elif [ "mall-pay" == ${MODULE} ]
then
   PORT=8086
else
   echo "模块不存在"
   set -e
   exit 1
fi

if [ ! -d ${FILE_DIR} ]
then
   mkdir -p ${FILE_DIR}
fi

# 复制编译好的包
cp -f ${JAR_DIR}/${JARFILE} ${FILE_DIR}

cd ${FILE_DIR}
PROCESS_ID=$(ps -ef | grep ${JARFILE} | grep -v grep | awk '{print $2}')
# 如果该项目正在运行,就杀死项目进程
if [ ! -z "${PROCESS_ID}" ]
then 
   echo "停止服务"
   kill -9 ${PROCESS_ID}
else 
	echo "服务未启动"
fi
nohup java -jar ${JARFILE} > ${MODULE}.log 2>&1 &
# 如果该项目还未启动,则等启动后再执行下个发布任务,判断项目是否启动要用端口号占用,不能用进程,因为在项目启动的瞬间进程就有了
retryTime=0
while true
do
   RESTART_PROCESS_ID=$(lsof -i:${PORT} | awk '{if (NR>1){print $2}}')
   if [ -z "${RESTART_PROCESS_ID}" ]
   then
      # 如果超时还未启动则退出
      if [ ${retryTime} -gt ${TIMEOUT} ]
      then
         echo "启动超时"
         set -e
         exit 1
      fi
      retryTime=$((${retryTime} + 3))
      sleep 3
      echo "服务启动中"
   else
      echo "服务启动成功"
      break
   fi
done

注意: BUILD_ID=dontKillMe,Jenkins 默认会在构建完成后杀掉构建过程中 shell 命令触发的衍生进程。Jenkins 根据 BUILD_ID 识别某个进程是否为构建过程的衍生进程,修改 BUILD_ID 则此进程能在后台保留运行,否则项目启动成功后就被杀死了。

6. 增加构建后操作

构建后将包发到远程服务器并执行启动操作

注意 如果是微服务,那么系统服务可能存在于多台服务器上,为了避免所有服务器同时启动导致的服务不可用,要等服务发布成功后再发布下一个服务,具体表现为,启动服务后轮询服务端口号,当端口号被占用后即可理解为服务启动成功,然后再继续下一个发布任务。

在这里插入图片描述
在这里插入图片描述

Source files:打包源文件路径
Remove prefix:${MODULE}/target
Remote directory:远程服务器代码存放路径,相对路径,前缀是新增SSH Server时设置的Remote Directory
Exec command:远程服务器执行脚本

export JAVA_HOME PATH CLASSPATH
JAVA_HOME=/opt/jdk1.8.0_281
PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$CLASSPATH
FILE_DIR=/home/jl/apps/
JARFILE=${MODULE}-1.0-SNAPSHOT.jar
# 设置超时时间,如果达到超时时间项目还未启动则退出
TIMEOUT=60
# 根据模块使用响应端口号
PORT=0
if [ "mall-admin" == ${MODULE} ]
then
   PORT=31001
elif [ "mall-portal" == ${MODULE} ]
then
   PORT=8085
elif [ "mall-pay" == ${MODULE} ]
then
   PORT=8086
else
   echo "模块不存在"
   set -e
   exit 1
fi

if [ ! -d ${FILE_DIR} ]
then
   mkdir -p ${FILE_DIR}
fi

cd ${FILE_DIR}
PROCESS_ID=$(ps -ef | grep ${JARFILE} | grep -v grep | awk '{print $2}')
# 如果该项目正在运行,就杀死项目进程
if [ ! -z "${PROCESS_ID}" ]
then 
   echo "停止服务"
   kill -9 ${PROCESS_ID}
else 
	echo "服务未启动"
fi
nohup java -jar ${JARFILE} > ${MODULE}.log 2>&1 &
# 如果该项目还未启动,则等启动后再执行下个发布任务,判断项目是否启动要用端口号占用,不能用进程,因为在项目启动的瞬间进程就有了
retryTime=0
while true
do
   RESTART_PROCESS_ID=$(lsof -i:${PORT} | awk '{if (NR>1){print $2}}')
   if [ -z "${RESTART_PROCESS_ID}" ]
   then
      # 如果超时还未启动则退出
      if [ ${retryTime} -gt ${TIMEOUT} ]
      then
         echo "启动超时"
         set -e
         exit 1
      fi
      retryTime=$((${retryTime} + 3))
      sleep 3
      echo "服务启动中"
   else
      echo "服务启动成功"
      break
   fi
done

注意nohup java -jar ${JARFILE} > ${MODULE}.log &,默认会报超时错误
在这里插入图片描述
这是因为 Jenkins 默认会在构建完成后杀掉构建过程中 shell 命令触发的衍生进程。Jenkins 根据 BUILD_ID 识别某个进程是否为构建过程的衍生进程,而且远程脚本执行环境为非 tty(终端)。
解决方法:

a. nohup java -jar ${JARFILE} > ${MODULE}.log 2>&1 &

这样确实可以解决问题,但是原理不明
参考:解决linux环境下nohup: redirecting stderr to stdout问题

b. 在 SSH Server 的高级中勾选Exec in pty,让脚本在 pty(虚拟终端)中执行,
在这里插入图片描述

参考:Jenkins 构建后执行 nohup 脚本,前台不退出解决

c. 修改 BUILD_ID,Jenkins 就无法识别是否为衍生进程,则此进程能在后台保留运行;

BUILD_ID=dontKillMe
nohup java -jar ${JARFILE} > ${MODULE}.log &
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Jenkins可以用于部署Spring Cloud项目。根据引用\[1\]中提到的方案,可以使用Jenkins + Docker + Spring Cloud的集群部署流程来实现。首先,需要搭建一个Docker服务器,并进行配置。然后,修改所有微服务的配置,包括eureka、admin、gathering和zuul等。接下来,在Jenkins中创建一个流水线项目,并安装Extended Choice Parameter插件。通过配置构建参数,可以实现多服务器远程发布。在项目配置中,需要修改Docker配置以信任Harbor私服地址。然后,编写部署脚本,并进行构建测试。最后,可以使用Nginx+Zuul实现高可用网关,通过在web2-server服务器上安装nginx并修改配置文件来实现。\[2\]\[3\] #### 引用[.reference_title] - *1* [Jenkins---部署Spring Cloud项目](https://blog.csdn.net/qq_40823910/article/details/106197154)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Jenkins 微服务持续集成之集群部署(SpringCloud微服务)(六)](https://blog.csdn.net/m0_59430185/article/details/123296947)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值