大数跨境
0
0

Jenkins + Maven + Git 自动化部署指南!

Jenkins + Maven + Git 自动化部署指南! 架构师专栏
2025-11-04
0

大家好,我是鹏磊。


图片

https://www.ddkk.com

我们今天用 Jenkins + Maven + Git 来实现一套简单的自动化部署

img_1
  • 首先,程序员将本地代码, 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
img_2
  • Create group
img_3
  • 填入组名,点击  Create group
img_4

2)新建项目

  • 点击  New project
img_5
  • 创建空白项目
img_6
  • 输入项目名, Create project
img_7

3)新建 token

点击页面左上角的 头像(或用户名),在下拉菜单中选择 Preferences(偏好设置)或 Settings(设置)。在左侧导航栏中,找到并点击Access Tokens(访问令牌)选项(通常在 User Settings 分类下)。

img_8img_9

拷贝 token glpat-qx7VU3J219j1D4_92uqJ

img_10

2、IDEA 创建新项目

1)新建项目

img_11
  • 选择  Spring Web
img_12

2)修改配置端口

server.port=8088

3)新建 Controller

@RestController
@RequestMapping("/")
public class HelloController {

    @RequestMapping
    public String sayHello() {
        return "Hello dev";
    }
}

4)测试

浏览器访问 127.0.0.1:8088

img_13

5)给 IDEA 设置GIT

打开 IDEA Settings > Git 在 Path to Git executable 里面选择本机安装的Git目录

img_14

6)创建 Git 仓库

Version Control > Create Git repository 选择当前项目,意思是把当前项目作为 Git 仓库

img_15img_16

点击 OK 后为我们弹开下面的视图,证明成功

img_17

7) 关联 Git 远程仓库

对着项目 右键 > Git > Manage Remotes

点击 +,弹出 Define Remote,在 URL 里面把我们从 gitlab 项目克隆的 http 链接填进去

img_18

填入 gitlab token

img_19

8)把代码提交到本地仓库

img_20

9)把代码推送到远程仓库

img_21

10)在 GitLab 上合并代码

img_22

三、Jenkins CICD

1、安装 Maven 插件

我们想让 Jenkins 能使用 Maven 进行构建,需要安装 Maven 插件。

Dashboard > Manage Jenkins > 插件管理 > Available plugins,搜索 maven,点击 安装

img_23

等待安装完成,点击返回首页

img_24

2、创建项目

Dashboard > All > 新建 Item

img_25

3、配置 Git

Dashboard > first > Configuration

img_26

添加 git 凭据

img_27

4、配置分支

img_28

5、配置 Maven

img_29

在 http://192.168.40.98:8080/configureTools/ 下配置 maven 安装路径后保存

img_30

Root POM 保持不变

img_31

Root POM 表示,相对于项目文件夹 jenkins-study,pom.xml 的位置,我们的 pom.xml 刚好位于 jenkins-study 路径下,所以不变。

img_32

6、测试 jenkins 打包

保存上述配置,点击 运行

img_33

在 Dashboard > first > #1 > 控制台输出 的日志中,能看到 Jenkins 将 代码 打包的目录:

img_34

进入/root/.jenkins/workspace/first/target/ 测试打出来的包是否运行成功:

[root@jenkins98 target]# java -jar jenkins-study-0.0.1-SNAPSHOT.jar

看到如下内容,说明 Jenkins 打包成功。接下来,我们要利用 Jenkins 将这个 jar 传到 测试服务器,并运行起来。

img_35

报错:

如果运行 java -jar 报错 no main manifest attribute, in jenkins-study-0.0.1-SNAPSHOT.jar

说明 spring-boot-maven-plugin 打包得有问题,把项目 pom.xml skip 改为 false 即可。

img_36

7、安装 SSH Publisher 插件

要利用 Jenkins 将这个 jar 传到 测试服务器,需要使用插件 SSH Publisher

Dashboard > Manage Jenkins > 插件管理 > Available plugins

img_37

安装完,返回首页

img_38

8、配置测试服务器信息

Dashboard > Manage Jenkins > System,新增测试服务器

img_39

填上测试服务器信息并保存

img_40

Test Configuration 测试连接

img_41

9、配置 Post Steps

Dashboard > first > Configuration > Post Steps > Send files or execute commands over SSH

img_42

配置 Post Steps

img_43

Source files 表示从 workspace 开始找编译后的包,Jenkins 将我们的代码编译到

/root/.jenkins/workspace/first/target
img_44
  • **
     :表示任意路径
  • jenkin*.jar
     :表示通配符匹配
  • Remote directory
     :包存放的远程服务器目录,默认是 ~ ,即当前使用的 SSH 账户的 家目录。root 用户是  /root ,普通用户是  /home/当前用户名

10、测试 jenkins 传包

立即构建

img_45

在 test97 这台服务器 /root 下看到多添加了 /target 目录:

img_46

配置 Remove prefix,去掉 /target

img_47

重新运行构建:

img_48

可见,Jenkins 多次构建并不会帮我清除旧的构建,需要我们编写 Exec command 来做这些工作。

通常,我们会将包放置在项目文件夹里,方便不同的项目管理。

配置Remote director

img_49

保存后重新运行构建:

img_50

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  文件。
  • 最后一个  & :后台运行程序,此时终端会立即返回控制权(可以继续输入其他命令)。
img_51

保存并重新构建,在测试服务器执行 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,端口被占用。

img_52

因为 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
     :打印进程信息。

直接 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

img_53

加上我们的脚本

img_54

保存并重新构建

# 重新构建前
[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

img_55

四、总结

至此,我们完成了一个简单的 Jenkins CICD,大家思考一下还有什么需要改进的地方?

https://www.ddkk.com

如果你近期准备面试跳槽,建议在ddkk.com在线刷题,涵盖 一万+ 道 Java 面试题,几乎覆盖了所有主流技术面试题,还有市面上最全的技术五百套,精品系列教程,免费提供。

【声明】内容源于网络
0
0
架构师专栏
专注原创,架构设计,Java后端、微服务、算法、技术栈。资料网站 ddkk.com
内容 1254
粉丝 0
架构师专栏 专注原创,架构设计,Java后端、微服务、算法、技术栈。资料网站 ddkk.com
总阅读1.8k
粉丝0
内容1.3k