Skip to content

Jenkins教程 - 3 部署SpringBoot项目 ​

下面使用 Jenkins + Git + Maven, 自动化部署一个 SpringBoot 项目。

3.1 准备SpringBoot项目 ​

1 新建一个SpringBoot 项目 ​

新建一个 SpringBoot 项目,这里我就在 SpringBoot 中新建一个 Controller。

只提供了一个接口,证明 SpringBoot 能访问运行就好了。

java
package com.doubibiji.hellospringboot.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    @GetMapping("/hello")
    public String sayHello() {
        return "Hello SpringBoot";
    }

}

项目结构:

2 将SpringBoot项目托管码云 ​

Jenkins 服务后面需要从 git 仓库拉取代码进行构建,这里使用 gitee 码云来托管代码,所以这里将 SpringBoot 项目托管到码云。

这里细节就不介绍了,git 不太会的,可以学习本站的 git教程 。

3.2 配置插件和工具 ​

1 安装Maven插件 ​

我们现在构建项目需要使用 Maven,所以还需要安装一个 Maven 插件。


在可用的插件中,搜索 maven,在搜索结果中选中 Maven Integration 进行安装。

拉到最下面,查看安装进度

2 配置Maven工具 ​

我们的自动化构建任务是使用 Maven 构建的,需要告诉 Jenkins Maven的安装位置。


配置 Maven 的路径:

使用 mvn -v 可以查看 maven 安装的路径。

在前面已经配置了 Maven 使用阿里云的镜像。

3 安装SSH插件 ​

这个插件的作用就是将 Jenkins 构建的 SpringBoot 项目的 jar 包发布的业务服务器上。

还是刚才安装插件的步骤:

4 配置业务服务器 ​

后面需要将构建的 SpringBoot 的 jar 包发布到业务服务器,所以在这里配置一下要发布到的业务服务器的信息。

我也不知道选项为啥突然变成中文了,就是之前的 Manage Jenkins 下的 System 。

拉到最下面找到 Publish over SSH,安装完 SSH 插件才有这个选项。


新增一个 SSH Server。


配置上面几个选项就可以了,配置完成,在最下面有个测试的按钮,可以测试一下配置有没有问题,没有问题,保存配置。

3.3 创建构建任务 ​

1 新建任务 ​

在 Jenkins 管理页面,新建Item,也就是新建构建任务。

填写任务名称:

选择Maven项目,前面安装Maven插件,才有这个选项!

2 源码管理 ​

分支配置:

3 构建配置 ​

上面使用默认配置即可。

  • Pre Steps :表示构建前的工作,例如要执行一些脚本,这里我们不需要;
  • Post Steps :表示构建后的工作;
  • Root POM :指定构建使用的 pom.xml,这里表示在远程仓库的根目录下,如果远程仓库中,pom.xml不在根目录下,例如在 demo 目录下,则这里需要配置 demo/pom.xml 。

3.4 执行构建 ​

前面的配置保存后,可以在控制台查看到配置的任务。如果要修改配置,直接点击任务 --> 配置,重新进行修改即可。

现在任务已经创建了,可以在任务列表,点击任务后面的按钮,手动执行构建。

执行后,在构建执行状态列表,可以看到构建的进度。

可以点击进去查看构建的控制台信息:


如果已经构建完成,也可以点击任务进入任务信息页面,查看构建失败的原因:

摸索一下页面的功能就好了。

第一次构建需要的时间可能比较久,因为要下载很多项目依赖的 jar 包。


构建如果成功,会显示成功,并在 jenkins 的工作空间下构建出 SpringBoot 项目的 jar 包。

如果没有成功,可以看一下日志,失败的原因是什么。

3.5 部署到业务服务器 ​

上面的步骤只是在 Jenkins 服务器上生成了 jar 包,还没有一条龙执行到自动部署到业务服务器。下面继续。

1 配置传输 ​

重新进入到构建任务的配置页面,对 Post Steps 进行配置,也就是构建后的操作。

选择 Send files or execute commands over SSH 。

因为 Jenkins 服务和 业务服务不是在同一个服务器上,所以才使用 Send files or execute commands over SSH ,如果在一台服务器 上,直接选择 执行 shell 就可以了,都不用将文件推送到别的服务器,直接使用shell命令 mv 去移动文件就可以了。

因为是不同服务器,所以需要使用SSH将文件传输到服务器,这里配置远程服务器信息,填写如下配置:

  • SSH Server:需要配置业务服务器,这里才有选择,看一下 3.2.4。

  • Source files :在 Jenkins 服务器上,构建的 jar 包在 Jenkins 的工作空间下,也就 ~/.jenkins/workspace ,我这里构建的任务名称叫 hello-jenkins ,所以 jar 包的地址是 /home/doubi/.jenkins/workspace/hello-jenkins/target/hello-springboot-0.0.1-SNAPSHOT.jar。这里填写的地址是从构建的任务所在的文件夹开始算的,也就是 /home/doubi/.jenkins/workspace/hello-jenkins 算起,所以这里我填写了 target/*.jar ,使用了通配符,表示 target 目录下所有的 jar 包。

  • Remote directory :表示传输到的远程服务器的路径,也是从家目录 ~ 开始算起,表示传输到 ~/projects 目录下,也就是传输到 /home/doubi/projects 目录下,则传输完成,在业务服务器上 jar 包的路径是 /home/doubi/projects/hello-springboot-0.0.1-SNAPSHOT.jar ,如果路径不存在,会自动创建。

  • Remove prefix :这个表示删除的路径的前缀,如果不填写,则复制到远程后,会将 target 目录一起复制,会变成 /home/doubi/projects/target/hello-springboot-0.0.1-SNAPSHOT.jar ,这里将 target 路径删掉。

  • Exec command :表示上传完成执行的命令,这里直接运行 jar 包,注意要使用 nohup 命令,在后台运行,并指定日志的输出,否则可能以为执行超时而失败。

执行的命令:

shell
nohup java -jar /home/doubi/projects/hello-springboot-0.0.1-SNAPSHOT.jar > hello-springboot.log 2>&1 &

命令就是在后端运行jar包。

2 重新构建 ​

除了可以点击 Dashboard 页面,任务列表后面的构建按钮,可以构建。


还可以在任务详情页面,点击 立即构建 按钮。


在 Jekins 的控制台页面,可以查看构建日志:

可以看到是否构建和传输成功,根据提示信息修改即可,如果传输成功,运行不成功,可以查看业务服务器上 jar 包有没有传输到对应的目录。

在 Post Steps 的 Send files or execute commands over SSH 的高级中,有一个 Exec timeout 选项,表示执行超时时间,默认是2分钟,如果任务构建时间比较长,可以将时间设置的长一些。

我这里是 201ms 就成功的。

3 访问SpringBoot项目 ​

访问 SpringBoot 项目测试的接口,发现可以访问。

注意,上面传输完成的脚本只是启动了jar包,没有涉及到其他的操作,所以如果重新再执行构建,并不会将之前的 SpringBoot 项目停掉,而是会再次运行 SpringBoot 项目,会出现端口冲突,启动失败。

下面来处理这个问题。

4 执行脚本 ​

在上面构建的时候,最终执行的命令是 nohup java -jar /home/doubi/projects/hello-springboot-0.0.1-SNAPSHOT.jar > hello-springboot.log 2>&1 & ,这个只是启动项目,没有备份、停止操作。

我们可以在业务服务器中,新建一个脚本文件,在脚本文件中进行备份、停止、启动项目的操作,然后在构架的时候,在 Post Steps 中执行这个脚本文件即可。

下面就是编写这个脚本文件,我这里起名叫 deploy.sh

shell
#!/bin/bash

# jar包的名字
fileName=hello-springboot-0.0.1-SNAPSHOT.jar

# 这里是获取正在运行的程序的PID,通过PID来杀掉之前运行的程序
PID=$(ps -ef | grep $fileName | grep -v grep | awk '{ print $2 }')

# 如果PID不为空
if [ -n "${PID}" ]; 
then
  # 杀掉程序
  kill -9 $PID
  echo 'Application is stopping...'
else
  echo 'Application is not running'
fi

# 创建日志目录
mkdir -p "./logs/"

# 运行jar包
nohup java -jar ./$fileName > ./logs/hello-springboot.log 2>&1 &

# 创建备份目录(如果不存在)
mkdir -p "./packages/"

# 备份jar包
backupTimestamp=$(date +%Y%m%d%H%M)
cp $fileName ./packages/$backupTimestamp-$fileName
echo "backup jar success!"

在上面的脚本中,进行了杀掉原来的程序、运行新的jar包,备份jar包的操作,编写完脚本文件,最好先本地执行测试一下,确保可用。

上面的 PID=$(ps -ef | grep $fileName | grep -v grep | awk '{ print $2 }') 就是从下面查询到的进程信息中获取正在运行的项目的PID 赋值给 PID 变量。

grep $fileName 就是过滤名称带有 hello-springboot-0.0.1-SNAPSHOT.jar 的进程,如下图:

grep -v grep 就是再过滤掉含有 grep 的进程,那么就剩下第一条记录,awk '{ print $2 }' 表示取出这个记录中的第二个字段,也就是PID 2483 。


然后给这个文件添加执行权限:

shell
chmod +x deploy.sh


脚本写好了,现在让 Jenkins 直接在上传完文件执行这个脚本就可以了。

重新配置 Post Steps :

配置完成,重新直接构建,可以看到,每次SpringBoot项目都会重启启动执行。

5 修改SpringBoot项目 ​

现在重新修改SpringBoot项目,上传到gitee码云,然后使用 Jenkins 重新执行构建,看看能否自动拉取代码,完成自动部署更新。

重新修改 SpringBoot Controller的代码:

java
@RestController
public class HelloController {

    @GetMapping("/hello")
    public String sayHello() {
        return "Hello www.doubibiji.com";
    }

}

并推送到 gitee。

然后重新使用 Jekins 执行构建。构建完成,访问 SpringBoot 项目。发现自动构建更新完成。

至此,完成了整个 SpringBoot 项目的自动构建。