来源:https://blog.csdn.net/matrixlzp
👉 欢迎加入小哈的星球,你将获得: 专属的项目实战(多个项目) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《Spring AI 项目实战》正在更新中..., 基于 Spring AI + Spring Boot 3.x + JDK 21;
-
《从零手撸:仿小红书(微服务架构)》 已完结,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17..., 点击查看项目介绍;演示地址:http://116.62.199.48:7070/
- 《从零手撸:前后端分离博客项目(全栈开发)》 2期已完结,演示链接:http://116.62.199.48/;
- 专栏阅读地址:https://www.quanxiaoha.com/column
截止目前,累计输出 100w+ 字,讲解图 4013+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,Spring Cloud Alibaba 等等,
戳我加入学习,解锁全部项目,已有4000+小伙伴加入
我们今天用 Jenkins + Maven + Git 来实现一套简单的自动化部署
图片- • 首先,程序员将本地代码,
git push 到远程 GitLab 服务器。 - • 然后,Jenkins
git pull 到 Jenkins 服务器,并用 maven 帮我们打成 jar 包。 - • 最后,Jenkins 将打好的 jar 包通过 SSH Publisher 发布到测试服务器。
一、先决条件
这里需要用到 三台服务器,一台安装 GitLab,一台安装 Jenkins,还有一台测试服务器。
服务器信息如下:
| 服务器名 | IP | 配置 | 安装的软件 |
|---|
| gitlab99 |
192.168.40.99 | 8C8G | gitlab |
| jenkins98 | 192.168.40.98 | 4C4G |
jenkins\jdk\maven\git |
| test97 | 192.168.40.97 | 2C2G | jdk |
GitLab 安装可以 戳这里👉
https://blog.csdn.net/matrixlzp/article/details/130773520
Jenkins 安装可以 戳这里👉
https://blog.csdn.net/matrixlzp/article/details/153967848
二、环境准备
1、GitLab 创建空白项目
1)创建分组
- •
Your work / Groups / New group
图片
图片
图片2)新建项目
图片
图片
图片3)新建 token
点击页面左上角的 头像(或用户名),在下拉菜单中选择 Preferences(偏好设置)或 Settings(设置)。在左侧导航栏中,找到并点击 Access Tokens(访问令牌)选项(通常在 User Settings 分类下)。
图片
图片拷贝 token glpat-qx7VU3J219j1D4_92uqJ
图片2、IDEA 创建新项目
1)新建项目
图片
图片2)修改配置端口
server.port=8088
3)新建 Controller
@RestController
@RequestMapping("/")
public class HelloController {
@RequestMapping
public String sayHello() {
return "Hello dev";
}
}
4)测试
浏览器访问 127.0.0.1:8088
图片5)给 IDEA 设置GIT
打开 IDEA Settings > Git 在 Path to Git executable 里面选择本机安装的Git目录
图片6)创建 Git 仓库
Version Control > Create Git repository 选择当前项目,意思是把当前项目作为 Git 仓库
图片
图片点击 OK 后为我们弹开下面的视图,证明成功
图片7) 关联 Git 远程仓库
对着项目 右键 > Git > Manage Remotes
点击 +,弹出 Define Remote,在 URL 里面把我们从 gitlab 项目克隆的 http 链接填进去
图片填入 gitlab token
图片8)把代码提交到本地仓库
图片9)把代码推送到远程仓库
图片10)在 GitLab 上合并代码
图片
三、Jenkins CICD
1、安装 Maven 插件
我们想让 Jenkins 能使用 Maven 进行构建,需要安装 Maven 插件。
Dashboard > Manage Jenkins > 插件管理 >
Available plugins,搜索 maven,点击 安装
图片等待安装完成,点击返回首页
图片2、创建项目
Dashboard > All > 新建 Item
图片
3、配置 Git
Dashboard > first > Configuration
图片添加 git 凭据
图片
4、配置分支
图片5、配置 Maven
图片在 http://192.168.40.98:8080/configureTools/ 下配置 maven 安装路径后保存
图片Root POM 保持不变
图片Root POM 表示,相对于项目文件夹 jenkins-study,pom.xml 的位置,我们的 pom.xml 刚好位于 jenkins-study 路径下,所以不变。
图片
6、测试 jenkins 打包
保存上述配置,点击 运行
图片在 Dashboard > first > #1 > 控制台输出 的日志中,能看到 Jenkins 将 代码 打包的目录:
图片进入 /root/.jenkins/workspace/first/target/ 测试打出来的包是否运行成功:
[root@jenkins98 target]# java -jar jenkins-study-0.0.1-SNAPSHOT.jar
看到如下内容,说明 Jenkins 打包成功。接下来,我们要利用 Jenkins 将这个 jar 传到 测试服务器,并运行起来。
图片报错:
如果运行 java -jar 报错 no main manifest attribute, in jenkins-study-0.0.1-SNAPSHOT.jar
说明 spring-boot-maven-plugin 打包得有问题,把项目 pom.xml skip 改为 false 即可。
图片
7、安装 SSH Publisher 插件
要利用 Jenkins 将这个 jar 传到 测试服务器,需要使用插件 SSH Publisher
Dashboard > Manage Jenkins > 插件管理 > Available plugins
图片安装完,返回首页
图片8、配置测试服务器信息
Dashboard > Manage Jenkins > System,新增测试服务器
图片填上测试服务器信息并保存
图片Test Configuration 测试连接
图片
9、配置 Post Steps
Dashboard` > `first` > `Configuration` > `Post Steps` > `Send files or execute commands over SSH
图片配置 Post Steps
图片
Source files 表示从 workspace 开始找编译后的包,Jenkins 将我们的代码编译到
/root/.jenkins/workspace/first/target
图片- •
Remote directory:包存放的远程服务器目录,默认是 ~,即当前使用的 SSH 账户的 家目录。root 用户是 /root,普通用户是
/home/当前用户名
10、测试 jenkins 传包
立即构建
图片在 test97 这台服务器 /root 下看到多添加了 /target 目录:
图片配置 Remove prefix,去掉 /target:
图片重新运行构建:
图片可见,Jenkins 多次构建并不会帮我清除旧的构建,需要我们编写 Exec command 来做这些工作。
通常,我们会将包放置在项目文件夹里,方便不同的项目管理。
配置 Remote director
图片保存后重新运行构建:
图片11、运行 jar 包
配置 Exec command
nohup java -jar /root/jenkins-study/jenkins*.jar >> /root/jenkins-study/log.out 2>&1 &
- •
nohup(忽略挂起信号):进程与终端解耦,即使终端关闭,进程仍能继续运行。 - •
>>:将 nohup java -jar 的日志输出,从标准输出(控制台)重定向到 /root/jenkins-study/log.out 文件。并且是以追加的方式。 - •
2>&1:将标准错误输出(2)重定向到标准输出(1),而标准输出在前面已经被重定向到 /root/jenkins-study/log.out 文件,所以标准错误输出也被重定向到 /root/jenkins-study/log.out 文件。 - • 最后一个
&:后台运行程序,此时终端会立即返回控制权(可以继续输入其他命令)。
图片保存并重新构建,在测试服务器执行 jps 命令,能看到 jenkins-study 项目已运行。
报错:
如果 jps 只有一个 Jps 进程在跑:
[root@test97 ~]# jps
20876 Jps
查看 /root/jenkins-study/log.out 日志,如果看到
nohup: failed to run command ‘java’: No such file or directory
用如下方法发解决:
vim /etc/bashrc
# 在最后一行添加
export JAVA_HOME=/usr/local/jdk/jdk-17.0.12
export PATH=$PATH:$JAVA_HOME/bin
export CLASSPATH=.:$JAVA_HOME/lib/
这是因为
/bin/bash 启动的终端也需要配置 JAVA_HOME
我们现在这样的配置还是有问题:
多次构建,看看测试服务器 jps
[root@test97 ~]# jps
20807 jenkins-study-0.0.1-SNAPSHOT.jar
20895 Jps
[root@test97 ~]# jps
20807 jenkins-study-0.0.1-SNAPSHOT.jar
20968 Jps
[root@test97 ~]# jps
20807 jenkins-study-0.0.1-SNAPSHOT.jar
20987 Jps
会发现 jenkins-study 的 pid 并没有变化,查看 /root/jenkins-study/log.out,端口被占用。
图片因为 8088 端口已经被第一次运行的 java 程序占用了,所以后续 nohup 都启动不成功,所以 pid 一直是第一次运行的 java 程序。解决这个问题的方法,就是进行构建前清理,清理 java 进程,和旧的 jar 包。
12、配置 Pre Steps
在测试服务器 /root 下创建一个 clean.sh 清理脚本,脚本内容如下:
#!/bin/bash
appname=$1
# 如果appname为空,提示返回;
if [ -z $appname ];
then
echo"应用名称不能为空!"
exit -1
else
echo"应用名称为$1"
fi
# 清理旧版本jar包
rm -rf $appname/"${appname}"*.jar
# 获取正在运行的项目pid
pid=`ps -ef | grep $1 | grep 'java -jar' | awk '{printf $2}'`
echo"pid为$pid"
# 如果pid为空,提示一下;否则,执行kill命令
if [ -z $pid ];
then
echo"$appname is not started"
else
kill -9 $pid
echo"$appname was stopped"
fi
- •
$1:表示Shell脚本的第一个参数,就比如 ./clean.sh test,$1 就等于 test;以此类推,$2 表示第二个,$3 表示第三个...... - •
-z:字符串运算符,检测字符串长度是否为0,为0返回true。z zero 的意思。
直接 ps -ef | grep appname 会把 grep 进程也打印出来
[root@test97 ~]# ps -ef|grep jenkins-study
root 20807 1 1 19:40 ? 00:00:33 java -jar /root/jenkins-study/jenkins-study-0.0.1-SNAPSHOT.jar
root 21223 21093 0 20:31 pts/0 00:00:00 grep --color=auto jenkins-study
所以需要 grep 'java -jar' 再过滤一次
[root@test97 ~]# ps -ef|grep jenkins-study|grep 'java -jar'
root 20807 1 1 19:40 ? 00:00:33 java -jar /root/jenkins-study/jenkins-study-0.0.1-SNAPSHOT.jar
用 grep -v grep,排除掉 grep 也可以
[root@test97 ~]# ps -ef|grep jenkins-study|grep -v grep
root 20807 1 1 19:40 ? 00:00:33 java -jar /root/jenkins-study/jenkins-study-0.0.1-SNAPSHOT.jar
awk '{printf $2}':对字符串进行匹配,打印出第二个参数,也即 20807,也就是我们的 pid。
更改一下 clean.sh 脚本的模式,使其具有可执行权限
[root@test97 ~]# chmod 777 clean.sh
配置 Pre Steps
图片加上我们的脚本
图片保存并重新构建
# 重新构建前
[root@test97 ~]# jps
20807 jenkins-study-0.0.1-SNAPSHOT.jar
21445 Jps
# 重新构建后
[root@test97 jenkins-study]# jps
21562 jenkins-study-0.0.1-SNAPSHOT.jar
21610 Jps
可以看到 pid 已经不同了。
13、测试
浏览器访问 192.168.40.97:8088
图片四、总结
至此,我们完成了一个简单的 Jenkins CICD,大家思考一下还有什么需要改进的地方?
👉 欢迎加入小哈的星球,你将获得: 专属的项目实战(多个项目) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《Spring AI 项目实战》正在更新中..., 基于 Spring AI + Spring Boot 3.x + JDK 21;
- 《从零手撸:仿小红书(微服务架构)》 已完结,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17..., 点击查看项目介绍;演示地址:http://116.62.199.48:7070/
-
《从零手撸:前后端分离博客项目(全栈开发)》 2期已完结,演示链接:http://116.62.199.48/;
- 专栏阅读地址:https://www.quanxiaoha.com/column
截止目前,累计输出 100w+ 字,讲解图 4013+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,Spring Cloud Alibaba 等等,戳我加入学习,解锁全部项目,已有4000+小伙伴加入
最近面试BAT,整理一份面试资料《Java面试BATJ通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。
获取方式:点“在看
”,关注公众号并回复 Java 领取,更多内容陆续奉上。
PS:因公众号平台更改了推送规则,如果不想错过内容,记得读完点一下“在看”,加个“星标”,这样每次新文章推送才会第一时间出现在你的订阅列表里。
点“在看”支持小哈呀,谢谢啦