摘要: 原创出处 http://www.iocoder.cn/Jenkins/install/ 「芋道源码」欢迎转载,保留摘要,谢谢!

  1. 概述
  2. 快速入门
  3. 邮件通知
  4. 钉钉通知
  5. 彩蛋
    推荐阅读如下 Jenkins 文章:
    《芋道 Spring Boot 持续交付 Jenkins 入门》
    《芋道 Spring Cloud 持续交付 Jenkins 入门》 对应 labx-16
  6. 概述

目前国内绝大多数的团队,都采用 Jenkins 实现持续集成与持续发布。那么 Jenkins 是什么?在《Jenkins 用户文档中心》介绍如下:
Jenkins 是一款开源 CI&CD 软件,用于自动化各种任务,包括构建、测试和部署软件。
Jenkins 支持各种运行方式,可通过系统包、Docker 或者通过一个独立的 Java 程序。
Jenkins 官方在《Jenkins 用户文档中心》中,已经提供了较为详细的教程,并且已经提供中文翻译,非常友好哈。不过考虑到胖友可能想要更加简便的快速入门的教程,于是艿艿就写了本文。
2. 快速入门

在本小节,我们会一起来搭建一个 Jenkins 服务,并部署一个 Spring Boot 应用到远程服务器。整个步骤如下:
1、搭建一个 Jenkins 服务
2、配置 Jenkins 全局工具
3、创建一个 Jenkins 任务。该任务从 Git 获取的项目,并使用 Maven 构建,并将构建出来的 jar 包复制远程服务器上,最后进行 Spring Boot 应用的启动。
友情提示:如下必备软件,胖友需要自行安装。
Jenkins 所在服务器:
JDK 8+
Maven 3+
Git
远程服务器:
JDK 8+
2.1 Jenkins 搭建

2.1 下载
打开 Jenkins 下载页面,选择想要的 Jenkins 版本。这里,我们选择 jenkins.war 软件包,通用所有操作系统,切版本为 2.204.1。

#创建目录
$ mkdir -p /Users/yunai/jenkins
$ cd /Users/yunai/jenkins#下载
$ wget http://mirrors.jenkins.io/war-stable/latest/jenkins.war

2.1.2 启动 Jenkins 服务
执行 nohup java -jar jenkins.war & 命令,后台启动 Jenkins 服务。因为 jenkins.war 内置 Jetty 服务器,所以无需丢到 Tomcat 等等容器下,可以直接进行启动。
执行完成后,我们使用 tail -f nohup.out 命令,查看下启动日志。如果看到如下日志,说明启动成功:

Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:e24a2134060f4604b45708904a4f7a25This may also be found at: /Users/yunai/.jenkins/secrets/initialAdminPassword

默认情况下,Jenkins 内置一个管理员用户。其用户名为 admin,密码随机生成。这里,我们可以看到一串 e24a2134060f4604b45708904a4f7a25 就是密码。
2.2 Jenkins 配置

2.2.1 新手入门
默认情况下,Jenkins 启动在 8080 端口。所以,我们可以使用浏览器,访问 http://127.0.0.1:8080/ 地址,进入 Jenkins 首页。因为此时我们未完成 Jenkins 的入门,所以被重定向「入门」页面。如下图所示:

输入管理员密码,我们进入「新手入门」页面。如下图所示:

作为一个 Jenkins 萌新,我们当然选择「安装推荐的插件」。此时,我们需要做的就是乖乖的耐心等待 Jenkins 自动下载完插件。如下图所示:

因为插件是从国外下载,所以下载速度可能比较慢,可以打开 B 站刷会视频,哈哈哈。当然,也可能出现插件下载失败的情况,点击重试即可,保持淡定。
2.2.2 管理员配置
安装完插件之后,会跳转到「创建第一个管理员用户」界面。如下图所示:

点击「保存并完成」按钮,完成管理员账号的创建。
2.2.3 实例配置
创建完管理员账号,会要求重新登录。使用新的管理员账号登录完毕后,会跳转到「实例配置」界面。如下图所示:

点击「保存并完成」按钮,完成实例的配置。此时,通过点击「重启」按钮,完成 Jenkins 的重启。之后,耐心等待 Jenkins 完成重启,我们将会进入 Jenkins 首页。如下图所示:

2.2.4 安全其它插件
虽然我们在「2.2.1 新手入门」中,已经安装 Jenkins 推荐的一些插件,但是我们还需要安装如下插件:
Maven Integration
Maven Info
Publish Over SSH
Extended Choice Parameter
Git Parameter
从 Jenkins 首页开始,按照「Manage Jenkins -> Manage Plugins」的顺序,进入「插件管理」界面。如下图所示:

安全其它插件 - 第一步

安全其它插件 - 第二步
选择上述要安装的几个插件,然后点击「直接安装」按钮。之后,会进入「安装/更新 插件中」界面。如下图所示:

之后,耐心等待插件安装完成…
2.2.4 JDK 配置
从 Jenkins 首页开始,按照「Manage Jenkins -> Global Tool Configuration」的顺序,进入「Global Tool Configuration」界面。如下图所示:

点击「新增 JDK」按钮,并取消「Install automatically」选项。之后,输入本地的 JAVA_HOME。如下图所示:

配置完成后,点击最下面的「保存」按钮。
2.2.5 Maven 配置
从 Jenkins 首页开始,按照「Manage Jenkins -> Global Tool Configuration」的顺序,进入「Global Tool Configuration」界面。如下图所示:

点击「新增 Maven」按钮,并取消「Install automatically」选项。之后,输入本地的 MAVEN_HOME。如下图所示:

配置完成后,点击最下面的「保存」按钮。
2.2.6 SSH 配置
因为我们通过 SSH 复制构建出来的 jar 包到远程服务器上,所以我们需要进行 SSH 配置。这里,我们使用账号密码的认证方式,实现 SSH 连接到远程服务器。
从 Jenkins 首页开始,按照「Manage Jenkins -> Configure System」的顺序,进入「配置」界面,然后下拉到最底部。如下图所示:

点击「新增」按钮,并点击「高级」按钮。之后,配置远程服务器的 SSH 信息。如下图所示:

配置完成后,点击最下面的「保存」按钮。
2.3 远程服务器配置

在远程服务器上,我们需要创建 Java 项目部署的目录。每个公司制定的目录规范不同,这里艿艿分享下自己的。固定在 /work/projects 目录下,创建每个项目的部署目录。并且,每个项目独立一个子目录。例如说:

$ pwd
/work/projects/lab-41-demo01$ ls
ls -ls
total 188524 drwxr-xr-x 2 root root     4096 Jan 13 21:21 backup4 drwxr-xr-x 2 root root     4096 Jan 13 21:14 build
18840 -rw-r--r-- 1 root root 19288579 Jan 13 21:21 lab-41-demo01.jar4 drwxr-xr-x 2 root root     4096 Jan 13 21:16 shell

lab-41-demo01 目录,会放置一个项目的所有。
在每个子目录下,固定分成如下文件/目录:
lab-41-demo01.jar:项目的 jar 包。
build 目录:Jenkins 构建完项目后的新 jar 包,会上传到 build 目录下,避免对原 jar 包覆盖,导致无法正常关闭 Java 服务。
backup 目录:对历史 jar 包的备份目录。每次使用新的 jar 启动服务时,会将老的 jar 移到 backup 目录下备份。
shell 目录:脚本目录。目前只有 deploy.sh 脚本,我们来一起瞅瞅。
整个 deploy.sh 脚本,有接近 200 行不到,所以我们先来整体看看。后续,胖友可以点击 传送门 ,进行完整查看。核心代码如下:

#!/bin/bash
set -e#基础
#export JAVA_HOME=/work/programs/jdk/jdk1.8.0_181
#export PATH=PATH=$PATH:$JAVA_HOME/bin
#export CLASSPATH=$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jarDATE=$(date +%Y%m%d%H%M)
#基础路径
BASE_PATH=/work/projects/lab-41-demo01
#编译后 jar 的地址。部署时,Jenkins 会上传 jar 包到该目录下
SOURCE_PATH=$BASE_PATH/build
#服务名称。同时约定部署服务的 jar 包名字也为它。
SERVER_NAME=lab-41-demo01
#环境
PROFILES_ACTIVE=prod
#健康检查 URL
HEALTH_CHECK_URL=http://127.0.0.1:8078/actuator/health/#heapError 存放路径
HEAP_ERROR_PATH=$BASE_PATH/heapError
#JVM 参数
JAVA_OPS="-Xms1024m -Xmx1024m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$HEAP_ERROR_PATH"
#JavaAgent 参数。可用于配置 SkyWalking 等链路追踪
JAVA_AGENT=#备份
function backup() {// ... 省略代码
}#最新构建代码 移动到项目环境
function transfer() {// ... 省略代码
}#停止
function stop() {// ... 省略代码
}#启动
function start() {// ... 省略代码
}#健康检查
function healthCheck() {// ... 省略代码
}#部署
function deploy() {cd $BASE_PATH# 备份原 jarbackup# 停止 Java 服务stop# 部署新 jartransfer# 启动 Java 服务start# 健康检查healthCheck
}deploy

在开头,我们定义了一堆变量,胖友可以根据其上的注释,进行理解。
在结尾,我们可以看到对 #deploy() 方法,进行项目的部署。整个步骤,分为 5 步,分别对应 5 个方法。我们逐个方法来看看。
① backup
#backup() 方法,将原 jar 包备份到 backup 目录下。代码如下:

function backup() {# 如果不存在,则无需备份if [ ! -f "$BASE_PATH/$SERVER_NAME.jar" ]; thenecho "[backup] $BASE_PATH/$SERVER_NAME.jar 不存在,跳过备份"# 如果存在,则备份到 backup 目录下,使用时间作为后缀elseecho "[backup] 开始备份 $SERVER_NAME ..."cp $BASE_PATH/$SERVER_NAME.jar $BASE_PATH/backup/$SERVER_NAME-$DATE.jarecho "[backup] 备份 $SERVER_NAME 完成"fi
}

② stop
#stop() 方法,将原 jar 包对应的 Java 进程,进行优雅关闭。代码如下:

function stop() {echo "[stop] 开始停止 $BASE_PATH/$SERVER_NAME"PID=$(ps -ef | grep $BASE_PATH/$SERVER_NAME | grep -v "grep" | awk '{print $2}')# 如果 Java 服务启动中,则进行关闭if [ -n "$PID" ]; then# 正常关闭echo "[stop] $BASE_PATH/$SERVER_NAME 运行中,开始 kill [$PID]"kill -15 $PID# 等待最大 60 秒,直到关闭完成。for ((i = 0; i < 60; i++))do  sleep 1PID=$(ps -ef | grep $BASE_PATH/$SERVER_NAME | grep -v "grep" | awk '{print $2}')if [ -n "$PID" ]; thenecho -e ".\c"elseecho '[stop] 停止 $BASE_PATH/$SERVER_NAME 成功'breakfidone# 如果正常关闭失败,那么进行强制 kill -9 进行关闭if [ -n "$PID" ]; thenecho "[stop] $BASE_PATH/$SERVER_NAME 失败,强制 kill -9 $PID"kill -9 $PIDfi# 如果 Java 服务未启动,则无需关闭elseecho "[stop] $BASE_PATH/$SERVER_NAME 未启动,无需停止"fi
}

首先,获得到 Java 服务对应的 PID 进程编号。
然后,先 kill -15 对应进程,尝试正常关闭 Java 服务。考虑到整个关闭是一个过程,所以我们需要等待一段时间,直到 Java 服务正常关闭。

友情提示:这里定义的 60 秒,如果胖友需要更短或者更长,可以自行修改。当然,也可以做成变量,嘿嘿。

最后,万一 Java 服务无法正常关闭,则 kill -9 对应进程,强制关闭 Java 服务。

友情提示:如果胖友不希望强制关闭 Java 服务,可以考虑此处进行 exit 1 ,异常退出部署,然后人工介入,进行问题的排查。

③ transfer
#transfer() 方法,将 build 目录的新 jar 包,“覆盖”到老的 jar 包上。代码如下:

 function transfer() {echo "[transfer] 开始转移 $SERVER_NAME.jar"# 删除原 jar 包if [ ! -f "$BASE_PATH/$SERVER_NAME.jar" ]; thenecho "[transfer] $BASE_PATH/$SERVER_NAME.jar 不存在,跳过删除"elseecho "[transfer] 移除 $BASE_PATH/$SERVER_NAME.jar 完成"rm $BASE_PATH/$SERVER_NAME.jarfi# 复制新 jar 包echo "[transfer] 从 $SOURCE_PATH 中获取 $SERVER_NAME.jar 并迁移至 $BASE_PATH ...."cp $SOURCE_PATH/$SERVER_NAME.jar $BASE_PATHecho "[transfer] 转移 $SERVER_NAME.jar 完成"}

这里,我们并不是直接覆盖,因为 cp 命令覆盖时,系统会提示是否尽心覆盖,需要手动输入 y 指令,显然无法满足我们自动化部署的需要。
④ start
#start() 方法,使用新的 jar 包,启动 Java 服务。代码如下:

function start() {# 开启启动前,打印启动参数echo "[start] 开始启动 $BASE_PATH/$SERVER_NAME"echo "[start] JAVA_OPS: $JAVA_OPS"echo "[start] JAVA_AGENT: $JAVA_AGENT"echo "[start] PROFILES: $PROFILES_ACTIVE"# 开始启动BUILD_ID=dontKillMe nohup java -server $JAVA_OPS $JAVA_AGENT -jar $BASE_PATH/$SERVER_NAME.jar --spring.profiles.active=$PROFILES_ACTIVE &echo "[start] 启动 $BASE_PATH/$SERVER_NAME 完成"
}

比较简单,核心就是通过 java -jar 命令,通过 jar 包来启动 Java 服务。
④ healthCheck
#healthCheck() 方法,通过健康检查 URL ,判断 Java 服务是否启动成功。代码如下:

function healthCheck() {# 如果配置健康检查,则进行健康检查if [ -n "$HEALTH_CHECK_URL" ]; then# 健康检查最大 60 秒,直到健康检查通过echo "[healthCheck] 开始通过 $HEALTH_CHECK_URL 地址,进行健康检查";for ((i = 0; i < 60; i++))do# 请求健康检查地址,只获取状态码。result=`curl -I -m 10 -o /dev/null -s -w %{http_code} $HEALTH_CHECK_URL || echo "000"`# 如果状态码为 200,则说明健康检查通过if [ "$result" == "200" ]; thenecho "[healthCheck] 健康检查通过";break# 如果状态码非 200,则说明未通过。sleep 1 秒后,继续重试elseecho -e ".\c"sleep 1fidone# 健康检查未通过,则异常退出 shell 脚本,不继续部署。if [ ! "$result" == "200" ]; thenecho "[healthCheck] 健康检查不通过,可能部署失败。查看日志,自行判断是否启动成功";tail -n 10 nohup.outexit 1;# 健康检查通过,打印最后 10 行日志,可能部署的人想看下日志。elsetail -n 10 nohup.outfi# 如果未配置健康检查,则 slepp 60 秒,人工看日志是否部署成功。elseecho "[healthCheck] HEALTH_CHECK_URL 未配置,开始 sleep 60 秒";sleep 60echo "[healthCheck] sleep 60 秒完成,查看日志,自行判断是否启动成功";tail -n 50 nohup.outfi
}

和 Java 服务的关闭一样,Java 服务的启动也是一个过程。这里,我们提供了两种策略:1)通过健康检查 URL,自动判断应用是否启动成功。2)未配置健康检查 URL 的情况下,我们通过 sleep 60 秒,然后查看日志,人工判断是否启动成功。
健康检查的 URL,我们通过 Spring Boot Actuator 提供的 health 端点,判断请求返回的状态码是否为 200 。如果是,则说明应用健康,启动完成。对 Spring Boot Actuator 不了解的胖友,可以后续看看 《芋道 Spring Boot 监控端点 Actuator 入门》的「4. health 端点」小节。现在,胖友暂时可以只需要知道这个设定就好。
当然,为了满足胖友的“好奇心”,艿艿最后还是打印了 N 行日志,满足胖友希望看到启动日志的诉求,哈哈哈。
嘿嘿,虽然有 5 个步骤,200 行不到的 Shell 代码,实际还是比较简单,嘻嘻。
2.4 Jenkins 部署任务配置

从 Jenkins 首页开始,点击「新建Item」按钮,进入 Jenkins 任务创建界面。输入任务名,并选择构建一个 Maven 项目。如下图所示:

点击「确认」按钮后,进行该任务的配置界面。配置项比较多,如下图所示:

2.4.1 详细配置
下面,我们一个一个配置项,逐个来看看哈。
① General

General
比较简单,只需要配置下描述即可。
② Maven Info Plugin Configuration

Maven Info Plugin Configuration
Discard old builds 配置项:设置保留的构建。因为我们会不断的重新构建项目,如果不进行设置,Jenkins 所在服务器的磁盘可能会不够用噢。
This project is parameterized 配置项:参数化构建。这里,我们使用 Git Parameter 插件,创建了参数名为 BRANCH,值为 Git 项目的 Branch/Tag。如此,我们在后续的项目构建中,可以选择构建的 Git 项目的分支/标签啦。
③ 源码管理

源码管理
选择 Git,从而选择 Git 仓库。
Repositories 配置项:设置使用的 Git 仓库。这里可以直接使用 https://github.com/YunaiV/SpringBoot-Labs 仓库,艿艿已经准备好了示例项目。
Branches to build 配置项:设置使用的 Git 分支/标签。这里,我们使用「② Maven Info Plugin Configuration」配置的构建参数 BRANCH 。
④ 构建触发器

构建触发器
暂时不需要配置,可无视哈。
⑤ 构建环境

暂时不需要配置,可无视哈。
⑥ Pre Steps

Pre Steps
暂时不需要配置,可无视哈。
⑦ Build

Build
Root POM 配置项:设置根 pom.xml 配置文件。一般情况下,设置 pom.xml 即可。
Goals and options 配置项:设置 Maven 构建命令。
这里,因为我们只想构建 lab-41/lab-41-demo01 子 Maven 模块,所以使用 -pl lab-41/lab-41-demo01 参数。其它 Maven 参数,不了解的话,自己搜索哈。
如果胖友要构建整个项目,可以考虑使用 clean package -Dmaven.test.skip=true 命令。
⑧ Post Steps

暂时不需要配置,可无视哈。
⑧ 构建设置

构建设置
暂时不需要配置,可无视哈。
⑨ 构建后操作
点击「增加构建后操作步骤」按钮,选择「Send build artifacts over SSH」选项,配置将 Maven 构建出来的 jar 包,通过 SSH 发送到远程服务器,并执行相应脚本,进行启动 Java 服务。如下图所示:

Name 配置项:选择部署的远程服务器。这里,我们选择「2.3 远程服务器配置」的服务器。
Transfer Set Sources files 配置项:设置传输的文件。这里,我们输入 lab-41/lab-41-demo01/target/*.jar 地址,表示传输的是 lab-41/lab-41-demo01 子 Maven 模块构建出来的 jar 包。
使用 lab-41/lab-41-demo01 在开头的原因是,因为我们构建的是 lab-41/lab-41-demo01 子 Maven 模块。
使用 target 在中间的原因是,Maven 构建的结果,在 target 目录下。
使用 .jar 在结尾的原因是,我们只传输 Maven 构建出来的 jar 包。
如果胖友是使用 clean install -Dmaven.test.skip=true 命令时,则此处配置 target/
.jar 即可。
Remove prefix 配置项:设置传输的文件,需要移除的前缀。这里,我们输入了 lab-41/lab-41-demo01/target/ 地址,表示传输到远程时,文件名仅为 *.jar 的名字。
Remote directory 配置项:传输到远程服务器的目录。这里,我们输入了 /work/projects/lab-41-demo01/build 地址,表示传输到远程服务器的 lab-41-demo01 项目的 build 目录。
Exec command 配置项:设置传输完文件后,执行的 Shell 命令。这里,我们输入了 cd /work/projects/lab-41-demo01/shell && ./deploy.sh 命令,表示执行部署脚本,进行启动 Java 服务。。
Exec in pty 配置项:必须勾选上,表示模拟一个终端执行脚本。

Jenkins + 钉钉 + SpringBoot 极简入门,一键打包部署项目相关推荐

  1. [转载]芋道 Soul 极简入门(国产微服务网关)

    摘要: 原创出处 http://www.iocoder.cn/Soul/install/ 「芋道源码」欢迎转载,保留摘要,谢谢! 由于原著写作时间时间有点久了:有部分类容需要更新,后去个人会再发布文章 ...

  2. 芋道 Apollo 极简入门

    点击上方"芋道源码",选择"设为星标" 做积极的人,而不是积极废人! 源码精品专栏 原创 | Java 2020 超神之路,很肝~ 中文详细注释的开源项目 RP ...

  3. 为 AI 初学者打造的《机器学习极简入门》面世了!

    随着人工智能技术的发展,机器学习已成为软件 / 互联网行业的常用技能,并开始向更多行业渗透.对越来越多的 IT 技术人员及数据分析从业者而言,机器学习正在成为必备技能之一. 今天我们就来聊聊机器学习的 ...

  4. Docker极简入门

    原 Docker极简入门 2018年05月22日 20:25:12 阅读数:44 一.Docker概述 Docker通过一个包括应用程序运行时所需的一切的可执行镜像启动容器,包括配置有代码.运行时.库 ...

  5. .Net Core in Docker极简入门(下篇)

    点击上方蓝字"小黑在哪里"关注我吧 Docker-Compose 代码修改 yml file up & down 镜像仓库 前言 上一篇[.Net Core in Dock ...

  6. Nginx 极简入门教程

    Nginx 极简入门教程 基本介绍 Nginx 是一个高性能的 HTTP 和反向代理 web 服务器,同时也提供了 IMAP/POP3/SMTP服务. Nginx 是由伊戈尔·赛索耶夫为俄罗斯访问量第 ...

  7. jenkins shell 权限_使用Jenkins一键打包部署SpringBoot应用,就是这么6!

    任何简单操作的背后,都有一套相当复杂的机制.本文将以SpringBoot应用的在Docker环境下的打包部署为例,详细讲解如何使用Jenkins一键打包部署SpringBoot应用. Jenkins简 ...

  8. Python极简入门教程

    前言 为了方便各位小白能轻松入门Python,同时加深自己对Python的理解,所以创造了"Python极简入门教程",希望能帮到大家,若有错误请多指正,谢谢.极简入门教程代表着不 ...

  9. SkyWalking 极简入门

    1. 概述 1.1 概念 SkyWalking 是什么? FROM http://skywalking.apache.org/ 分布式系统的应用程序性能监视工具,专为微服务.云原生架构和基于容器(Do ...

最新文章

  1. ListView用法
  2. JavaScript基础——Date对象
  3. c语言运算程序,C语言运算符
  4. 和华为云一起做件“伟大的事”,24万奖金等你来!
  5. SAP License:SAP Netweaver
  6. android pie华为更新,华为多款机型近期将迎来Android Pie系统更新,下列这几款肯定有你...
  7. 转:基于Jmeter的MQTT测试插件
  8. C#根据银行卡号获取银行
  9. WordPress插件 UberGrid 高级相册图片分享中文插件[更新至v2.0.13]
  10. CSP201609-3炉石传说
  11. 源码阅读|怒肝了9道 HashMap经典面试题,需要的快速来取(不包邮哦)
  12. 【Typora】 自定义背景颜色(护眼绿) 高亮颜色 选中内容颜色 高亮快捷键
  13. keepalived健康检查
  14. 别被“僵尸”吃掉大脑!学会用Kubernetes (K8s)思考
  15. 面试真题:经典智力题最详汇总
  16. 以太空为主题的Golang简介
  17. 高通平台手机开发之LCD
  18. Echarts 水波图实现
  19. cadence_allegro_查看dra文件所用pad_查看封装文件用的引脚列表
  20. 数据销毁,对于数据中心运营意味着什么?

热门文章

  1. 骨传导耳机的音质怎么样?
  2. 在Windows 7 Media Center中创建幻灯片放映
  3. 力扣刷题笔记:1438. 绝对差不超过限制的最长连续子数组(滑窗模板题,选择有序列表SortedList()数据类型就不会超时)
  4. 如何加声调口诀_汉语拼音声调标注口诀 涨知识了
  5. mate7安装android o,华为Mate7怎么刷机 华为Mate7刷机教程【步骤详解】
  6. LVGL:模拟器仿真
  7. 你认识细菌吗?一文带你读懂了解它
  8. 读datasheet遇到的名词,Assert,De-assert,component
  9. ubuntu alise设置
  10. FastQC 与 质控