使用 Jenkins 实现 Java 项目的持续集成和持续交付

简介: 本文参考中国 DevOps 社区核心组织者刘征老师在中国 DevOps 社区济南 Meetup 活动上分享的 "用Jenkins实施CI/CD工作坊",展示如何使用 Jenkins 实现 Java 项目的 CI/CD (持续集成/持续交付)。

基于已经配置好的 Jenkins 环境,本文参考中国DevOps社区核心组织者刘征老师中国DevOps社区济南Meetup活动上分享的 "用Jenkins实施CI/CD工作坊",展示如何使用 Jenkins 实现 Java 项目的 CI/CD (持续集成/持续交付)。

软件版本和环境准备

本次安装中使用的主要软件版本如下:

  • Ubuntu

    • Ubuntu 16.04.6 LTS
    • Ubuntu 18.04.2 LTS
  • openjdk

    • openjdk version "1.8.0_212"
    • openjdk version "11.0.3"
  • Jenkins 2.164.3
  • Apache Maven 3.6.1
  • Apache Tomcat

    • Apache Tomcat/8.0.32 (Ubuntu)
    • Apache Tomcat/8.5.39 (Ubuntu)
    • Apache Tomcat/9.0.16 (Ubuntu)

Jenkins 和 Tomcat 分别安装在两台云主机中,因为未进行安全防护,为避免受到攻击,示例中的 IP 地址不是真实的 IP 地址:

  • Jenkins 节点: 114.111.111.111
  • Tomcat 节点: 114.111.111.222

在使用 GitHub hook 功能时, Jenkins 节点应能被 GitHub 访问。

下载安装最新版 Maven

Ubuntu apt 源指向的 Maven 版本不是最新的。为了使用推荐版本的 Maven, 可从 Maven 官网或镜像网站下载, 解压后配置给 Jenkins 使用。在 Ubuntu 下命令如下:

wget http://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.6.1/binaries/apache-maven-3.6.1-bin.tar.gz
wget https://www.apache.org/dist/maven/maven-3/3.6.1/binaries/apache-maven-3.6.1-bin.tar.gz.sha512
cat apache-maven-3.6.1-bin.tar.gz.sha512
sha512sum apache-maven-3.6.1-bin.tar.gz # 确保输出内容与文件 apache-maven-3.6.1-bin.tar.gz.sha512 内容一致
tar xzvf apache-maven-3.6.1-bin.tar.gz
mv apache-maven-3.6.1/ /opt/
cat /etc/passwd | grep jenkins  # 查找 jenkins 用户的主目录,以下假设为 /var/lib/jenkins/
echo 'export PATH=/opt/apache-maven-3.6.1/bin:$PATH' >> /var/lib/jenkins/.bash_profile
chown jenkins:jenkins /var/lib/jenkins/.bash_profile
service jenkins restart

修改先前建立的 Hello World 项目的 Shell Command 为:

echo $JAVA_HOME
echo $PATH
mvn -v

启动手工构建,查看构建结果中的 "Console Output", 验证 maven 版本。

安装 tomcat

安装 tomcat 用于测试应用发布,安装后替换默认监听端口,为部署应用增加管理用户,并重启服务。

apt install tomcat8 tomcat8-admin tomcat8-examples
sed -i.bak 's/8080/8050/g' /etc/tomcat8/server.xml
systemctl restart tomcat8.service
sed -i.bak "/<\/tomcat-users>/i<user username=\"cuilongbo\" password=\"my-secure-password\" roles=\"manager-gui,manager-script,manager-jmx\"\/>" /etc/tomcat8/tomcat-users.xml

在 Ubuntu 18.04.2 LTS 下,还可再安装一个 tomcat9 用于对照:

apt install tomcat9 tomcat9-admin tomcat9-examples
sed -i.bak 's/8080/8060/g' /etc/tomcat9/server.xml
vim /etc/tomcat9/tomcat-users.xml
systemctl restart tomcat9.service
sed -i.bak "/<\/tomcat-users>/i<user username=\"cuilongbo\" password=\"my-secure-password\" roles=\"manager-gui,manager-script,manager-jmx\"\/>" /etc/tomcat9/tomcat-users.xml

为了远程访问 tomcat, 可能还需要在安全组中开启 tomcat 监听端口。

安装 Jenkins 插件

进入 Manage Jenkins » Manage Plugins 页面,安装或检查以下插件:

  • Build Pipeline Plugin
  • Checkstyle Plug-in
  • Copy Artifact Plugin
  • Deploy to container
  • Git plugin
  • GitHub plugin
  • Maven Integration plugin
  • Pipeline

在 Jenkins 中添加 JDK 和 Maven

进入 Manage Jenkins » Global Tool Configuration 页面,添加 JDK, 取消 Install automatically 选项,输入已在 Ubuntu 中安装的 JDK 的 JAVA_HOME 路径并命名。

image

图1. Add JDK

在同一页面的 Maven installations 中,单击 "Add Maven", 取消 Install automatically 选项,输入已在 Ubuntu 中安装的 Maven 的 MAVEN_HOME 路径并命名。

image

图2. Add Maven

Fork 代码库并克隆到本地

为了对代码库有修改权限,登录 GitHub 访问 https://github.com/martinliu/devops-maven 并 Fork, 以下假设 Fork 出的代码库为 https://github.com/cuilongbo/devops-maven.

将代码库克隆到本地,以便于修改测试。

git clone https://github.com/cuilongbo/devops-maven.git
cd devops-maven

基于首次 commit 创建分支 test 用于体验历史提交带来的变化,切换 test 为工作分支,并同步新分支到 GitHub:

git branch test 604a6b2
git checkout test
git push origin test

创建一组 Jenkins 任务并组装成流水线

创建打包任务

在 Jenkins 主页面点击 "New Item" 或 "create new jobs", 输入任务名称 "test-maven-package", 选择 "Maven project", 然后单击 "OK"。

image

图3. 创建打包任务

在 Source Code Management 页签下选择源代码管理方式为 Git, 并填写 Repository URL, Credentials, Branch Specifier 等信息:

image

图4. 源代码管理

在 Build 页签下输入 clean package 两条指令:

image

图5. 构建指令

在 Post Steps 页签下添加类型为 "archive the artifacts" 的构建后动作,输入要打包文件为 '**/*.war'.

image

图6. 添加构建后动作

单击 "Save" 保存配置, 然后单击 "Build Now" 启动构建,验证构建结果。

创建部署任务

在 Jenkins 主页面点击 "New Item" 或 "create new jobs", 输入任务名称 "test-maven-deploy-to-staging",选择 "Freestyle project", 然后单击 "OK"。

image

图7. 创建部署任务

在 Build 页签下增加一个类型为 "copy artifacts from another project" 的构建步骤,输入源项目,选择构建和要复制的工件。

image

图8. 添加构建步骤

在 Post Steps 页签下添加类型为 "deploy war/ear to a container" 的构建后动作,配置 WAR 包文件,路径,增加类型为 Tomcat 8.x 的 Container, 并配置其地址和认证信息。

image

图9. 添加构建后动作,部署到 tomcat

单击 "Save" 保存配置, 然后单击 "Build Now" 启动构建,验证构建结果,并在浏览器中输入应用 URL 查看应用结果, 在本例子中, URL 为 http://114.111.111.222:8050/test-maven/.

创建代码风格检查任务

在 Jenkins 主页面点击 "New Item", 类似图 7, 输入任务名称 "test-maven-checkstyle", 选择 "Freestyle project", 然后单击 "OK"。

转到 Source Code Management 页签,如同图 4, 选择源代码管理方式为 Git, 并填写 Repository URL, Credentials, Branch Specifier 等信息。

在 Build 页签下增加一个类型为 "Invoke top-level Maven targets" 的构建步骤, Maven version 选择图 2 中配置的 localMaven, Goals 中输入 checkstyle:checkstyle.

单击 "Save" 保存配置, 然后单击 "Build Now" 启动构建,验证构建结果。

创建部署到生产环境任务

该步骤与前面的 "创建部署任务" 一致,只是 Container 的配置为生产环境,任务名称为 "test-maven-deploy-to-prod".

一般来说,生产环境的软件版本应与测试环境一致。为了简便配置,此处选择同一云主机下的 tomcat9 作为生产环境。看起来 "Deploy to container" 插件的 Tomcat 8.x 选项也可用于 Tomcat 9 实例。

创建 Folder 并把以上相关任务移动到其中(可选)

任务太多看起来就会比较混乱。在 Jenkins 主页面点击 "New Item", 类似图 7, 输入名称 "test-maven", 选择 "Folder", 然后单击 "OK" 并单击 "Save" 保存。把上面建立的 4 个任务移动到 test-maven 下。

建立 Jenkins 流程

上面建立的 4 个任务现在都是手动触发的,一般情况下,我们希望:

  1. 代码库的某个分支出现改动后,自动触发 test-maven-package.
  2. test-maven-package 成功后自动启动 test-maven-checkstyle 和 test-maven-deploy-to-staging.
  3. 代码评审和测试通过后,由部署经理手工启动 test-maven-deploy-to-prod.

首先修改 test-maven-package 的配置, 在 Post-build Actions 中添加 Build other projects, 输入下游任务名称 test-maven-checkstyle, test-maven-deploy-to-staging 后单击 "Save" 保存。现在手动触发 test-maven-package, 可以看到 test-maven-package 成功完成后,会触发 test-maven-checkstyle 和 test-maven-deploy-to-staging.

然后修改 test-maven-deploy-to-staging 的配置, 在 Post-build Actions 中添加 Build other projects (manual step), 输入下游任务名称 test-maven-deploy-to-prod 后单击 "Save" 保存。

最后,修改 test-maven-package 的配置, 在 Build Triggers 中勾选 "GitHub hook trigger for GITScm polling", 并且在 https://github.com/cuilongbo/devops-maven/settings/hooks 中增加一个 Webhook. 按照 GitHub Plugin 中的说明, Webhook URL 的格式是 $JENKINS_BASE_URL/github-webhook/, 在本例中 为 http://114.111.111.111:8080/github-webhook/.

现在,合并代码库 https://github.com/cuilongbo/devops-maven 描述信息为 "Update main page" 的那次提交到 test 分支,并 push 到 GitHub:

git merge a980c76
git push origin test

push 成功后就可以看到 test-maven-package, test-maven-checkstyle 和 test-maven-deploy-to-staging 依次被触发,访问测试环境 http://114.111.111.222:8050/test-maven/ 也可以看到代码变更后的效果。

Build Pileline 视图

在 Folder test-maven 下单击 New View 输入视图名称 test-maven-pipeline, 选择 Build Pipeline View, 单击 "OK" 创建 Build Pileline 视图。

在接下来的视图配置页面中,选择 test-maven-package 作为 Initial Job.

image

图10. 选择 Initial Job

单击 "Save" 保存配置后可以看到创建好的 Build Pileline 视图。

image

图11. Build Pileline 视图

在 Build Pileline 视图下,可以清楚地看到与项目相关的所有任务以及每项任务的最近一次构建时间、消耗时间、构建状态等信息,并且可以通过点击任务卡片右下角的图标触发重新运行 (re-run) 或触发手工运行 (trigger).

在 CI/CD 的最后一步,部署到生产环境,一般都需要由授权人员确认测试通过手工执行。在 Build Pileline 视图中,单击 test-maven-deploy-to-prod 卡片右下角的 trigger 图标,即可完成生产环境部署。

致谢

感谢刘征老师和在中国DevOps社区济南社区的组织者,让我重新体验到 Jenkins 的魅力。

以上步骤参考刘征老师中国DevOps社区济南 Meetup 活动上分享的 "用Jenkins实施CI/CD工作坊" 和济南社区的同学分享的笔记整理。

相关文章
|
9天前
|
JavaScript 前端开发 Java
解决跨域问题大集合:vue-cli项目 和 java/springboot(6种方式) 两端解决(完美解决)
这篇文章详细介绍了如何在前端Vue项目和后端Spring Boot项目中通过多种方式解决跨域问题。
178 1
解决跨域问题大集合:vue-cli项目 和 java/springboot(6种方式) 两端解决(完美解决)
|
3天前
|
存储 JavaScript 数据库
ToB项目身份认证AD集成(一):基于目录的用户管理、LDAP和Active Directory简述
本文介绍了基于目录的用户管理及其在企业中的应用,重点解析了LDAP协议和Active Directory服务的概念、关系及差异。通过具体的账号密码认证时序图,展示了利用LDAP协议与AD域进行用户认证的过程。总结了目录服务在现代网络环境中的重要性,并预告了后续的深入文章。
|
3天前
|
人工智能 JavaScript 网络安全
ToB项目身份认证AD集成(三完):利用ldap.js实现与windows AD对接实现用户搜索、认证、密码修改等功能 - 以及针对中文转义问题的补丁方法
本文详细介绍了如何使用 `ldapjs` 库在 Node.js 中实现与 Windows AD 的交互,包括用户搜索、身份验证、密码修改和重置等功能。通过创建 `LdapService` 类,提供了与 AD 服务器通信的完整解决方案,同时解决了中文字段在 LDAP 操作中被转义的问题。
|
9天前
|
jenkins Java 测试技术
如何使用 Jenkins 自动发布 Java 代码,通过一个电商公司后端服务的实际案例详细说明
【10月更文挑战第8天】本文介绍了如何使用 Jenkins 自动发布 Java 代码,通过一个电商公司后端服务的实际案例,详细说明了从 Jenkins 安装配置到自动构建、测试和部署的全流程。文中还提供了一个 Jenkinsfile 示例,并分享了实践经验,强调了版本控制、自动化测试等关键点的重要性。
21 5
|
6天前
|
Java Apache Maven
Java/Spring项目的包开头为什么是com?
本文介绍了 Maven 项目的初始结构,并详细解释了 Java 包命名惯例中的域名反转规则。通过域名反转(如 `com.example`),可以确保包名的唯一性,避免命名冲突,提高代码的可读性和逻辑分层。文章还讨论了域名反转的好处,包括避免命名冲突、全球唯一性、提高代码可读性和逻辑分层。最后,作者提出了一个关于包名的问题,引发读者思考。
Java/Spring项目的包开头为什么是com?
|
9天前
|
运维 Java Maven
Dockerfile实践java项目
通过上述实践,我们可以看到,Dockerfile在Java项目中扮演着至关重要的角色,它不仅简化了部署流程,提高了环境一致性,还通过多阶段构建、环境变量配置、日志管理、健康检查等高级特性,进一步增强了应用的可维护性和可扩展性。掌握这些实践,将极大地提升开发和运维团队的工作效率。
14 1
|
10天前
|
算法 Java Linux
java制作海报五:java 后端整合 echarts 画出 折线图,项目放在linux上,echarts图上不显示中文,显示方框口口口
这篇文章介绍了如何在Java后端整合ECharts库来绘制折线图,并讨论了在Linux环境下ECharts图表中文显示问题。
24 1
|
3天前
|
安全 Java 测试技术
ToB项目身份认证AD集成(二):快速搞定window server 2003部署AD域服务并支持ssl
本文详细介绍了如何搭建本地AD域控测试环境,包括安装AD域服务、测试LDAP接口及配置LDAPS的过程。通过运行自签名证书生成脚本和手动部署证书,实现安全的SSL连接,适用于ToB项目的身份认证集成。文中还提供了相关系列文章链接,便于读者深入了解AD和LDAP的基础知识。
|
3月前
|
监控 druid Java
spring boot 集成配置阿里 Druid监控配置
spring boot 集成配置阿里 Druid监控配置
242 6
|
3月前
|
Java 关系型数据库 MySQL
如何实现Springboot+camunda+mysql的集成
【7月更文挑战第2天】集成Spring Boot、Camunda和MySQL的简要步骤: 1. 初始化Spring Boot项目,添加Camunda和MySQL驱动依赖。 2. 配置`application.properties`,包括数据库URL、用户名和密码。 3. 设置Camunda引擎属性,指定数据源。 4. 引入流程定义文件(如`.bpmn`)。 5. 创建服务处理流程操作,创建控制器接收请求。 6. Camunda自动在数据库创建表结构。 7. 启动应用,测试流程启动,如通过服务和控制器开始流程实例。 示例代码包括服务类启动流程实例及控制器接口。实际集成需按业务需求调整。
289 4