Jenkins是一个用java编写的开源的持续集成平台。
我的理解:项目周期 = 程序开发 + 环境部署 + 功能测试 + 项目上线。一个完整的项目,从开发到上线要经过多次的测试、调优。一个多人开发的项目,如果项目开发与运维分开,那最后的项目整合一定是痛苦的。而持续集成的作用就是:在项目的开发过程中不断地进行环境构建、功能的测试与集成。也就是说开发与运维在同时进行,项目如果会出现问题是在第一时间发现的,而不是等到将要上线时一大堆问题才引面而来。
一个多人开发的项目中,在代码提交(CHECK-IN
)到版本库(SOURCE REPOSITORY
)后,集成工具Jenkins能够进行: 环境的构建(BUILD
)|
测试环境(TEST
)的功能测试|
过渡环境(STAGING
)的功能测试|
正式环境(PRODUCTION
)的功能测试。这种流水线式的流程,能够保证项目中的BUG及时被发现(在正式环境测试之前)。
这篇博客的内容就是演示:如何从零开始,在虚拟机上用Jenkins部署java-maven项目,并通过Jenkins实现该项目的持续集成。还想深入了解持续集成、持续交付、持续部署,可参考什么是持续集成?
首先,需要配置JDK,MAVEN环境。
# 获取本机的位数
getconf LONG_BIT
# 我的虚拟机:64位。下载的jdk版本为(Linux64 jdk-8u161-linux-x64.tar.gz),将压缩包放在(/usr/local/env/java8)下,进行解压
cd /usr/local/env/java8
tar -xzvf jdk-8u161-linux-x64.tar.gz
# 编辑/etc/profile
vim /etc/profile
# 加入如下配置
export JAVA_HOME=/usr/local/env/java8/jdk1.8.0_161
export JRE_HOME=/usr/local/env/java8/jdk1.8.0_161/jre
export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
export PATH=$PATH:$JAVA_HOME/bin
# 保存退出后,使该配置文件即刻生效
source /etc/profile
# 使用如下命令,能正确显示信息,说明环境配置成功
java -version
如果安装的版本不对,会报错如下:-bash: /usr/local/env/java8/jdk1.8.0_161/bin/java: /lib/ld-linux.so.2: bad ELF interpreter: 没有那个文件或目录,需要根据自己虚拟机位数选择正确的JDK安装包。
# 在官网下载(apache-maven-3.5.3-bin.tar.gz),将压缩包放在(/usr/local/env/maven),进行解压
cd /usr/local/env/maven
tar -xzvf apache-maven-3.5.3-bin.tar.gz
# 编辑/etc/profile
vim /etc/profile
# 加入如下配置
MAVEN_HOME=/usr/local/env/maven/apache-maven-3.5.3
export MAVEN_HOME
export PATH=${PATH}:${MAVEN_HOME}/bin
# 保存退出后,使该配置文件即刻生效
source /etc/profile
# 使用如下命令,能正确显示信息,说明环境配置成功
mvn -version
出现如下页面,则说明环境部署成功。
# 导入最新版jenkins的资源
wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
# 获取最新版jenkins的密钥(证书错误的信息可以忽略)
rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.key
# 安装jenkins
yum install jenkins
# 由于jenkins提供的服务默认暴露在8080端口,可能被占用。
# 修改配置文件
vim /etc/sysconfig/jenkins
# 改为在8081端口提供服务
JENKINS_PORT="8081"
# 修改jdk配置
vim /etc/init.d/jenkins
# 在candidates=""中加入JAVA_HOME
/usr/local/env/java8/jdk1.8.0_161/bin/java
# 启动jenkins服务
service jenkins start
安装Jenkins成功后,Jenkins的目录结构如下:
功能模块 | 路径 |
---|---|
主目录 | /var/lib/jenkins |
war包 | /usr/lib/jenkins/jenkins.war |
配置文件 | /etc/sysconfig/jenkins |
启动脚本 | /etc/init.d/jenkins |
日志 | /var/log/jenkins |
在浏览器地址栏输入jenkins_server_ip:8081
,即可看到如下页面:
第一次使用Jenkins,需要核对密钥,该密钥在上述路径的文件中。
将该密码复制粘贴到输入框中,点击继续。进入如下页面,直接选择安装推荐的插件。
这些插件,都是协助jenkins进行项目的集成的。这里直接默认安装推荐插件即可。
插件安装成功后,后跳转到如下的用户注册页面。
之前用的是管理员身份,注册成功后,请牢记身份和密码。
注册之后,需要重新启动jenkins。
service jenkins stop
service jenkins restart
再次访问jenkins_server_ip:8081
,能够进入jenkins的主界面如下:
由于我们通常都是用Maven管理我们开发的Java项目,因此还需要安装相应的Maven插件。操作过程如下:
同时,我们还需要配置全局的JDK/MAVEN
环境。操作过程如下:
在 系统管理 > 全局工具配置 中指定对应的的JDK以及MAVEN环境
(JDK以及MAVEN名称可以随便指定,这里为了增加可读性,分别配置如下: java8:/usr/local/env/java8/jdk1.8.0_161 , maven3.5.3:/usr/local/env/maven/apache-maven-3.5.3),这里的地址就是java8,maven3.5.3在虚拟机上安装的地址
在所有必需的插件安装成功后,点击新建一个maven项目如下:
对该项目进行如下配置:
Genernal配置,即基础配置。
Project url
中的内容,就是Jenkins帮助我们自动构建的项目地址。同时Jenkins会默认保留所有的构建版本。但是实际开发过程中,我们一般只保留近期的几个构建版本。要保证最新版本项目不适用时,能够回滚到之前的构建版本即可。如这里就可以勾选丢弃旧的构建
,并只保留最新的3
个构建版本即可。
由于演示项目是放在Github上面,即learnJenkins项目是用
Git
来管理的。因此这里的Repository URL
就是我们需要自动构建的源代码地址,这里也需要确定将要构建的分支。实际开发中,我们也可能是用SVN
来管理项目的,配置方法是一样的。同时还需要当前用户有构建的权限,即需要预先进行认证Credentials
。由于这里我没有设置任何权限,因此可以不认证。
触发器,就是设置满足什么条件时,Jenkins才会帮我们进行自动构建。如下面的设置项内容就是:每3分钟会去扫描一次
Repository URL
中的提交历史,并对比最新的Jenkins构建和最近一次提交,如果这两者不同,Jenkins就会帮我们再进行一次构建。
构建方式。
ROOT POM
就是指定当前项目的根POM文件位置(POM文件中维护的是当前项目所需要的依赖包)。如果是一个多模块项目即有多个POM文件的项目,我们这里应该填写的是根POM文件位置。Goal and options
就是我们具体要执行的命令。这里就是告知Jenkins执行命令mvn clean package
。如果我们需要跳过单元测试,可以加上参数-DskipTests=true
。
此时,构建应用的相关配置已经设置完毕。
点击应用。返回主界面,可以点击立即构建。点击控制台输出,构建成功后的日志如下:
构建成功后,再次修改代码如下:
3分钟后,发现Jenkins检测到了GitHub上项目版本的更新,并自动帮我们进行了构建。
也就是此时,jenkins会根据触发器规则,自动检测最近构建的镜像是否与代码仓库中的最新版本的代码一致。如果两者不一致,则jenkins会自动再次把我们的最新版本源代码进行构建(现在其实就是仅仅做了一个打包处理)。
如果仅仅是自动构建,那Jenkins仅仅是帮我们做了一个自动打包的操作,这个操作,我们使用一些常用的IDE工具(如:IDEA/Eclipse/MyEclipse等)都能够很简单地完成。我们需要的是Jenkins能够自动部署最新版本的项目。
现在我们仔细查看上面的构建日志,查找jenkins将当前项目源代码打包后的默认存放位置。
如上图所示,当前项目的的jar包位置:/var/lib/jenkins/workspace/learnjenkins/target/learnjenkins-0.0.1-SNAPSHOT.jar
。
如果我们希望jenkins在自动构建的同时,能够帮我们自动部署。我们需要在当前项目的配置—Post Steps
中输入如下图命令:
# 加入这一行,防止jenkins自动杀死启动的tomcat进程导致项目停止
BUILD_ID=DONTKILLME
echo "即将自动部署learnjenkins项目..."
# 自动部署---需要杀死之前该项目对应的活动进程,防止由于端口占用无法启动项目
pid=`ps -ef|grep learnjenkins|grep -v 'grep' | awk '{print $2}'`
if [ -z $pid ];
then echo "learnjenkins is not running, so just to start it..."
else
echo "learnjenkins[pid=${pid}] is running, so i should kill the progress and restart it... "
kill -9 $pid
fi
# 利用nohup命令后台启动当前项目
nohup java -server -Xms256m -Xmx256m -Xmn128m -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=64m -Duser.timezone=GMT+08 -jar /var/lib/jenkins/workspace/learnJenkins/target/learnjenkins-0.0.1-SNAPSHOT.jar &
echo "成功自动部署learnjenkins项目..."
配置完成后,点击自动构建即可。如果输入的命令没有问题,则自动构建并部署的日志如下图所示:
我们可以在浏览器或通过curl
命令测试当前项目是否正确部署。两种效果是一样的,出现如下图所示情况,则说明项目已经部署成功。
额外说明:
我上述实现jenkins的自动部署的方式是:springboot项目内置tomcat容器,通过java -jar *.jar
命令的方式能够使java-web项目在内置tomcat容器中运行。
而在我们实际的开发过程中,常常是在外置tomcat容器或者docker容器中运行web项目。其实弄懂了jenkins的具体机能,自己熟悉如何在tomcat或docker中部署web项目,就很容易利用jenkins帮我们进行项目的自动构建部署。那就是题外话了,不适合在本篇博客中进行扩展了(有兴趣的话,可以参考我之前的博客—springboot整合docker)。