Jenkins 部署 RuoYi

news2024/11/19 1:21:30

目录

1、项目介绍

2、部署若依

clone 源代码

导入数据库到 node-16

修改 RuoYi 配置文件

推送 RuoYi 项目至 Gitlab

3、配置 Jenkins

配置本地 Maven

Jenkins 配置 Maven

新建 Maven 项目

编写构建后的脚本

Jenkins 构建后执行脚本

4、Jenkins 传递参数

设置项目部署动作

Jenkins 获取 git 标签

Jenkins 设置主机参数

配置 javagroup 主机

测试参数

5、配置参数化构建项目

修改 maven-deploy.sh 脚本

测试脚本

配置 Jenkins 构建后执行该脚本

测试回滚

6、Pipeline

概念介绍

创建 ruoyi-pipline 并构建测试

使用流水线语法生成脚本执行命令

修改 pipline 工作脚本

查看本地目录和日志

完整脚本


1、项目介绍

若依官网:http://doc.ruoyi.vip/ruoyi/

源代码地址:https://gitee.com/y_project/RuoYi

若依项目是一款使用java开发的后台管理系统,可以用于所有的Web应用程序, 如网站管理后台,网站会员中心,CMS,CRM,OA。所有前端后台代码封装过后十分精简易上手,出错概率低,同时支持移动客户端访问。 若依项目有单应用版本,前后端分离版本和微服务版本可供选择,本实例部署单应用版。

2、部署若依

主机名称

IP地址

服务

node-15

192.168.137.115

gitlab

node-04

192.168.137.116

mysql

node-17

192.168.137.117

jenkins

clone 源代码

导入数据库到 node-16

# 创建 ry 数据库 
mysql -uroot -p123456 -e "create database ry" 

# 导入数据库文件 
mysql -uroot -p123456 ry < quartz.sql 
mysql -uroot -p123456 ry < ry_20210924.sql 
mysql -uroot -p123456 -e "use ry;show tables"

#  给 root 账号授权 
mysql> grant all on *.* to root@'192.168.137.%' identified by '123456'; 
mysql> flush prileges;
修改 RuoYi 配置文件

推送 RuoYi 项目至 Gitlab

在Gitlab创建ruoyi空项目

3、配置 Jenkins
配置本地 Maven

maven 用于构建和管理任何基于 Java 的项目的工具,在文件中添加相应的配置,maven 就会自动的下载相应的 jar 包;下载依赖,只要配置的 jar 包所依赖的其他 jar 包都会被它自动下载下来;可以直接通过它打包 war 或者 jar 项目。

# maven 下载 
wget http://dlcdn.apache.org/maven/maven-3/3.8.6/binaries/apache-maven-3.8.6-bin.tar.gz

# maven 安装 
tar -zxvf apache-maven-3.8.6-bin.tar.gz -C /usr/local/ 

# 添加软连接 
ln -s /usr/local/apache-maven-3.8.6/bin/* /usr/local/bin/ 
mvn -version

# 修改Maven仓库源
vim /usr/local/apache-maven-3.8.6/conf/settings.xml
<mirror>
  <id>alimaven</id>
  <name>aliyun maven</name>
  <mirrorOf>central</mirrorOf>
  <url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>

Jenkins 配置 Maven

安装Maven Integration、Pipeline Maven Integration、Maven Release插件

新建 Maven 项目

编写构建后的脚本

注意:此脚本执行前提是,每台机器之间都做免密(包括自身)

vim maven-deploy.sh
#!/bin/bash
jardir="/var/lib/jenkins/workspace/ruoyi/ruoyi-admin/target/"
jar="ruoyi-admin.jar"
workdir="/javaapp"
iplist="192.168.137.116 192.168.137.117" #注意配置免密认证

for ip in $iplist
do
	ssh root@$ip "ls $workdir"
	if [ $? -ne 0 ];then
		ssh root@$ip "mkdir -p $workdir/{log,backup}"
		echo -e "\033[32m$ip /app create sucessful!!!\e[0m"
	else
		echo -e "\033[33m$ip /app is exist!!!\e[0m"
	fi
  
	if [ -f $jardir$jar ];then
		ssh root@$ip "rm -rf $workdir/backup/*"
		ssh root@$ip "mv $workdir/*.jar $workdir/backup"
		scp $jardir$jar root@$ip:$workdir

    # 是否需要下载java
		ssh root@$ip "which java &> /dev/null " 
		if [ $? -ne 0 ];then
			ssh root@$ip "yum install -y  java-11-openjdk"
		fi

    # 结束ry进程
		ryprocess=$(ssh root@$ip ps -ef | grep ruoyi-admin.jar | grep -v grep | awk '{print $2}')
		if [ $ryprocess ];then
			ssh root@$ip "kill $ryprocess"
		fi
		ssh root@$ip "nohup java -jar $workdir/$jar &> $workdir/log/ruoyi-$(date "+%F-%T").log &"
		
	fi
done


# 测试脚本
[root@node-17 ~]# sh -x maven-deploy.sh

Jenkins 构建后执行脚本

注意:脚本应该赋予执行权限

sudo ssh root@192.168.137.117 ./maven-deploy.sh

4、Jenkins 传递参数
设置项目部署动作

Jenkins 获取 git 标签

jenkins可以根据git代码tag(标签)拉取指定的标签分支代码进行部署,方便进行版本回滚

下载 git parameter 插件

添加参数:git 参数

gitlab 添加版本标签

在Jenkins 查看 git 标签

Jenkins 设置主机参数

配置 javagroup 主机

测试参数

编写测试脚本

# 写测试脚本
[root@node-17 ~] vim test.sh
#!/bin/bash
echo $1 >> /root/test.log
echo $2 >> /root/test.log
echo $3 >> /root/test.log

chmod +x test.sh

配置 Jenkins 调用脚本

使用参数构建

5、配置参数化构建项目
修改 maven-deploy.sh 脚本
#!/bin/bash
#author: lemonZ
#description: deploy/rollback ruoyi
#date: 2022年9月11日 18:59:49

version=$2
iplist=$3 #注意配置免密认证
target="ruoyi"
jardir="/var/lib/jenkins/workspace/$target/ruoyi-admin/target/"
jar="ruoyi-admin.jar"
date_time=$(date "+%F-%T")
target_version="$(basename -s .jar $jar)-$version-${date_time}"
tar_name="$target_version.tar.gz"
workdir="/javaapp/$target"
backup_num=3


#检测客户机工作目录
check_workdir(){
	ssh root@$ip "ls $workdir &> /dev/null"
	if [ $? -ne 0 ];then
		echo "创建$workdir"
		ssh root@$1 "mkdir -p $workdir/{$2,backup}"
	else
		echo "清空$workdir 工作目录下$target 项目"
		ssh root@$1 "rm -rf $workdir/${target}*" 		
		ssh root@$1 "mkdir -p $workdir/{$2,backup}"
	fi
}

#cp jar包到分发目录
cp_java(){
	if [ ! -d $workdir ];then
		mkdir -p  $workdir
	fi
	cd $jardir
	tar -zcf $workdir/$tar_name $jar
}

#scp jar包到远程目录
scp_java(){
	scp $workdir/$2 root@$1:$workdir/backup
}

#本地分发目录和远程备份目录每个版本保留3个备份
rm_backup(){
	echo $workdir
	cd $workdir; rm -rf $(ls . | grep $version | grep -v "$(ls . | grep $version | sort -r |head -$backup_num)" )
	backup_file=$(ssh root@$1 "cd $workdir/backup ; ls -t | grep $version")
	num=1
	for i in $backup_file
	do
		while [ $num -gt $backup_num ]
		do
				ssh root@$1 "rm -rf /javaapp/ruoyi/backup/$i"
				echo "删除$i"
				break
		done
		let num++
	done

}
#远程主机安装jdk11
install_java11(){
	ssh root@$1 "which java &> /dev/null"
	if [ $? -ne 0 ];then
			ssh root@$1 "yum install -y  java-11-openjdk"
	fi
}

#启动java项目
start_java(){
	ryprocess=$(ssh root@$ip ps -ef | grep $(basename -s .jar $jar) | grep -v grep | awk '{print $2}') 
	if [ "$ryprocess" ];then
			ssh root@$1 kill "$ryprocess"
	fi
	
	ssh root@$1 "rm -rf $workdir/$3/*"
	ssh root@$1 "tar -zxf $workdir/backup/$2 -C $workdir/$3"
	ssh root@$1 "cd $workdir/$3 ; nohup java -jar $jar &>$workdir/$3/${3}.log &"
}

deploy(){
	for ip in $iplist
	do
		check_workdir $ip $target_version
		cp_java 
		scp_java $ip $tar_name 
		install_java11 $ip
		start_java $ip $tar_name $target_version
		rm_backup $ip
	done
}

#回滚策略,根据版本回滚到上一次构建
rollback(){
	last_version=$(ls $workdir | sort -r | sed -n '2p' | awk -F "-" '{print $3}')
	if [ $version == $last_version ];then
		rollback_version_tar=$(ls $workdir | grep $version | sort -r | sed -n "2p")
	else
		rollback_version_tar=$(ls $workdir | grep $version | sort -r | sed -n "1p")
	fi
	rollback_version=$(basename -s .tar.gz $rollback_version_tar)
	for ip in $iplist
        do
		ls $workdir | grep $version &> /dev/null
		if [ $? -eq 0 ];then
			ssh root@$ip ls $workdir/backup/$rollback_version_tar
			if [ $? -eq 0 ];then
				check_workdir $ip $rollback_version
				start_java $ip $rollback_version_tar $rollback_version
			else
				check_workdir $ip $rollback_version
				install_java11 $ip
				scp_java $ip $rollback_version_tar		
				start_java $ip $rollback_version_tar $rollback_version
			fi
		else
			deploy
		fi		
	done
}

case $1 in
	deploy)
		deploy
		;;
	rollback)
		rollback
		;;
	*)
		echo "use: $0 [deploy|rollback]"
		exit
esac
测试脚本
sh -x maven-deploy.sh rollback v4.7.6 192.168.137.116

查看本机项目目录

查看远程项目目录

配置 Jenkins 构建后执行该脚本
sudo ssh root@192.168.137.117 ./maven-deploy.sh $action $tag $hostgroup

测试回滚

首先再Gitlab创建新标签:这里假设我们新创建了v4.7.7这个标签

使用新标 v4.7.7 签构建程序

查看项目目录

重新构建使用 v4.7.6 标签:测试回滚

6、Pipeline
概念介绍

官网:https://www.jenkins.io/doc/book/pipeline/

pipline是帮助Jenkins实现CI到CD转变的重要角色,是运行在jenkins 2.X版本的核心插件,简单来说Pipline就是一套运行于Jenkins上的工作流框架,将原本独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂发布流程,从而实现单个任务很难实现的复杂流程编排和任务可视化,Pipeline的实现方式是一套Groovy DSL,任何发布流程都可以表述为一段Groovy脚本。

Pipeline 语法

说明

Stage

阶段,一个pipline可以划分为若干个stage,每个stage都是一个操作,比如clone代码、代码编译、代码测试和代码部署,阶段是一个逻辑分组,可以跨多个node执行。

Node

节点,每个node都是一个jenkins节点,可以是jenkins master也可以是jenkins agent,node是执行step的具体服务器。

Step

步骤,step是jenkins pipline最基本的操作单元,从在服务器创建目录到构建容器镜像,由各类Jenkins 插件提供实现,例如: sh “make”

pipline优势

  • 可持续性:jenkins的重启或者中断后不影响已经执行的Pipline Job
  • 支持暂停:pipline可以选择停止并等待人工输入或批准后再继续执行。
  • 可扩展:通过groovy的编程更容易的扩展插件。
  • 并行执行:通过groovy脚本可以实现step,stage间的并行执行,和更复杂的相互依赖关系。
创建 ruoyi-pipline 并构建测试

简单的 pipline 工作脚本

node {
  stage("clone 代码"){
    echo "代码 clone"
  }
  stage("代码构建"){
    echo "代码构建"
  }
  stage("代码测试"){
    echo "代码测试"
  }
  stage("代码部署"){
    echo "代码部署"
  }
}

使用流水线语法生成脚本执行命令

git credentialsId: '81283712-9db6-4f33-95f1-be6bc79712c4', url: 'git@192.168.137.115:lemon/ruoyi.git'
修改 pipline 工作脚本
node {
  stage("clone 代码"){
    git credentialsId: '81283712-9db6-4f33-95f1-be6bc79712c4', url: 'git@192.168.137.115:lemon/ruoyi.git'
  }
  stage("代码构建"){
    echo "代码构建"
  }
  stage("代码测试"){
    echo "代码测试"
  }
  stage("代码部署"){
    echo "代码部署"
  }
}

查看本地目录和日志

完整脚本
pipeline {
    agent any
    tools {
        maven 'apache-maven-3.8.6' 
    }
    stages {
        stage('Example') {
            steps {
                sh 'mvn --version'
            }
        }
        stage("clone 代码"){
            steps {
                git credentialsId: '81283712-9db6-4f33-95f1-be6bc79712c4', url: 'git@192.168.137.115:lemon/ruoyi.git'
            }
        }
        stage("代码构建"){
            steps {
            sh 'cd /var/lib/jenkins/workspace/ruoyi-pipline && mvn clean install'
            }
        }
        stage("代码拷贝"){
            steps {
                sh 'sudo ssh root@192.168.137.117 chown -R jenkins:jenkins /javaapp/'
                sh 'mkdir -p /javaapp/ruoyi-pipline'  
                sh 'cd /var/lib/jenkins/workspace/ruoyi-pipline/ruoyi-admin/target/ && cp ruoyi-admin.jar /javaapp/ruoyi-pipline '
            }    
        }
        stage("代码复制 "){
            steps {
                sh 'sudo ssh root@192.168.137.116 mkdir -p /javaapp/ruoyi-pipline'
                sh 'sudo scp /javaapp/ruoyi-pipline/ruoyi-admin.jar 192.168.137.116:/javaapp/ruoyi-pipline'
            }
        }
        stage("安装jdk11"){
            steps {
                sh 'sudo ssh root@192.168.137.116 yum install -y java-11-openjdk'  
            }
        }
        stage('杀死若依进程'){
            steps {
                sh 'sudo ssh root@192.168.137.116 "ps -ef | grep ruoyi | grep -v grep | awk \'{print $2}\' | xargs rm -rf {} ||  true "'
            }
        }
        stage('启动服务'){
            steps {
                sh 'sudo ssh root@192.168.137.116 "nohup java -jar /javaapp/ruoyi-pipline/ruoyi-admin.jar &"'
            }
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1505810.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

el-table 插入输入框并进行校验

<template><div><el-form :model"list" ref"ruleForm"><el-table :data"list.tableData" style"width: 100%"><el-table-column prop"time" label"日期" width"180"><…

Swagger修改Api文档中的数据类型

swagger不陌生,API接口利器,本次要解决的问题是:我们知道前端在接收Long类型的属性时会出现精度问题,一般我们会在序列化的时候将Long类型的数字转换成String但是swagger的API文档中的类型还是Long,我们要解决的就是这个问题 不知道swagger怎么配置得可以看之前的文章:springb…

matlab阶段学习笔记小节2

syms定义符号变量 求极限 第二题 第三题 limit(y,n,inf);求的的函数y关于自变量n在无穷处&#xff08;inf&#xff09;的极限 exp(2)即指数为2&#xff0c;底为e,也就是e^2 求导数 第一题 log(x)默认是以e为底的指数函数&#xff0c;也就是ln(x). 使用diff(f)对函数进行求…

工作纪实46-关于微服务的上线发布姿势

蓝绿部署 在部署时&#xff0c;不需要将旧版本的服务停掉&#xff0c;而是将新版本与旧版本同时运行&#xff0c;新版本测试无误之后再将旧版本停掉。这样可以避免再升级的过程中如果失败服务不可用的问题&#xff0c;因为同时部署了两个版本的程序&#xff0c;使得硬件资源是…

Xshell 连接 虚拟机

一、网络配置 1. 虚拟网络编辑器 2. 打开本机的网络适配器选项 检查 3. 修改虚拟机的网段 vim /etc/sysconfig/network-scripts/ifcfg-ens33 按键盘 i 进行修改 键盘右上角Esc退出&#xff0c;然后输入 &#xff1a;wq 保存&#xff0c;然后重启网卡 systemctl restart netwo…

Oracle Essbase 多维库导入文件数据步骤操作

第一步&#xff1a; 先确定导入数据的维度数量&#xff08;清楚自己需要导入什么数据和范围&#xff09; 第二步&#xff1a; 设置加载的规则 1.创建规则 2.编辑规则-》打开数据文件 通过数据文件来确定加载规则的加载格式 先查看数据文件格式&#xff1a; 将数据文件导入&…

javase day02笔记

第二天课堂笔记 源文件的组成部分★★ 源文件外部结构 class 类名{}main方法 public static void main(String [] args){}main方法可有可无 没有main的情况&#xff0c;编译成功&#xff0c;运行失败&#xff0c;没有程序入口 多个main情况&#xff0c;编译报错&#xff0c;…

编曲学习:钢琴编写 人性化、逻辑预制 工程音频导出

第8课 钢琴编写 人性化、逻辑预制 工程音频导出小鹅通-专注内容付费的技术服务商https://app8epdhy0u9502.pc.xiaoe-tech.com/live_pc/l_65e30339e4b064a8cfe56001?course_id=course_2XLKtQnQx9GrQHac7OPmHD9tqbv 音乐创作中,有思路时可以不套学习到的公式,没有思路时可以套…

软件测试相关内容第三弹--软件测试基础

写在前&#xff1a;在前篇的两篇博客介绍中我们主要学习软件测试的相关概念&#xff0c;对软件测试进行了初步的了解&#xff0c;本篇博客将进一步进行学习。重点内容包括&#xff1a;软件测试的生命周期、如何描述一个bug、如何定义bug的级别、bug的生命周期以及在实际工作中如…

C语言:ctype和string库中的部分常用函数的应用和实现

在编程过程中&#xff0c;我们经常要处理字符和字符串&#xff0c;C语言标准库中就提供了一系列的库函数&#xff0c;便于我们操作库函数。 字符分类函数 C语⾔中有⼀系列的函数是专⻔做字符分类的&#xff0c;也就是⼀个字符是属于什么类型的字符的。这些函数的使⽤都需要包含…

蓝桥杯递推与递归法|斐波那契数列|数字三角形|42点问题|数的计算|数的划分(C++)

递归是用来做dfs&#xff0c;是搜索算法的基础 递推是用来做dp部分&#xff0c;及部分其他算法&#xff0c;复杂度较低&#xff0c;不会出现爆栈问题递推法&#xff1a; 递推法是一种在数学和其他领域广泛应用的重要方法&#xff0c;它在计算机科学中被用作一种关键的数值求解…

【深度学习笔记】6_10 双向循环神经网络bi-rnn

注&#xff1a;本文为《动手学深度学习》开源内容&#xff0c;部分标注了个人理解&#xff0c;仅为个人学习记录&#xff0c;无抄袭搬运意图 6.10 双向循环神经网络 之前介绍的循环神经网络模型都是假设当前时间步是由前面的较早时间步的序列决定的&#xff0c;因此它们都将信…

Java宝典-抽象类和接口

目录 1. 抽象类1.1 抽象类的概念1.2 抽象类的语法1.3 抽象类的特点 2. 接口2.1 接口的概念2.2 接口的语法2.3 接口的特点2.4 实现多个接口2.5 接口的继承 3. 接口使用案例 铁汁们好,今天我们学习抽象类和接口~ 1. 抽象类 1.1 抽象类的概念 什么是抽象类?在面向对象中,如果一…

cmaketool插件的自动扫描工作空间设置

点击左下角的齿轮&#xff0c;进入设置。 搜索cmake&#xff1a;config 将不需要的取消打钩即可

CCF-A推荐会议 安全界顶会ACM CCS‘24 4月29日第二轮投稿!共建更安全的数字世界!

会议之眼 快讯 第31届ACM CCS (ACM Conference on Computer and Communications Security)即计算机和通信安全会议将于 2024 年 10月14日-18日在美国盐湖城举行&#xff01;CCS是美国计算机协会(ACM)安全、审计与控制特别兴趣小组(SIGSAC)主办的一年一度的重要会议。是SIGSAC的…

Redisson学习

简介 Redisson 是一个在 Redis 的基础上实现的 Java 驻留内存数据网格&#xff08;In-Memory Data Grid&#xff09;。它提供了许多分布式 Java 对象和服务&#xff0c;包括分布式锁、分布式集合、分布式执行服务、分布式调度任务等。 使用 依赖 相关依赖&#xff0c;注意版…

【Attribute】Inspector视图可视不可编辑字段特性

简介 在Unity开发中&#xff0c;有时候我们存在这种需求&#xff0c;需要在Inspector视图中可以查看字段信息但是无法对字段进行赋值&#xff0c;那么我们也可以像Unity内置的[SerializeField]、[Tooltip]等特性那样自定义一个特性&#xff0c;用于满足这个需求。 代码示例(C#…

【备战蓝桥杯系列】蓝桥杯国二选手笔记二:算法模版笔记(Java)

感谢大家的点赞&#xff0c;关注&#xff0c;评论。准备蓝桥杯的同学可以关注一下本专栏哦&#xff0c;不定期更新蓝桥杯笔记以及经验分享。本人多次参加过蓝桥杯&#xff0c;并获得过蓝桥杯国二的成绩。 算法模版笔记&#xff08;Java&#xff09; 这篇文章给大家分享我的蓝桥…

【C++】二叉树进阶之二叉搜索树

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大二&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;熟练掌握二叉搜索树&#xff0c;能自己模拟实现二…

每日一题-合成两个有序链表

&#x1f308;个人主页: 会编辑的果子君 &#x1f4ab;个人格言:“成为自己未来的主人~” 以上是题目信息&#xff1a; 下面是解答过程 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ typedef struct Lis…