前面介绍了Jenkins的部署、插件安装。终于到了开始构建项目的时候了,是不是有点小开心,哈哈。

第一个构建的项目是java后台项目。这个应该也是我们运维人员部署的最多的一个项目。

构建一个java项目,我们在Jenkins上可以有两种方法:

1、在创建项目的时候选择"构建一个maven项目",这样可以减轻你的构建配置。

2、在创建项目的时候选择"构建一个自由风格的软件项目"。

这里我们选择第二种方法,因为"构建一个自由风格的软件项目"比较灵活,主要是我这边还想加一个回滚的功能。

一、环境准备

在开始构建项目之前,我们需要准备下以下的环境

IP地址作用
Jenkins192.168.0.111自动化打包部署
Nexus192.168.0.121maven私有仓库
MySQL192.168.0.122运行项目时用的数据库
Gitlab192.168.0.123开发人员用来托管代码
Server1192.168.0.124运行Tomcat(war包)或者jar包的服务器

这个环境大家应该很熟悉吧,基本是互联网公司自动化运维的标配。

简单介绍下流程:开发人员写好代码之后push到Gitlab上,Jenkins从Gitlab上拉取最新的代码之后进行打包,打包完成后部署到远程的Server服务器上,并运行Tomcat(war包)或者jar包。

其他的前端或者安卓项目也是一个道理,甚至还要简单些。

二、安装maven环境

前面已经准备的差不多了。但是别忘了在jenkins服务器上安装下maven环境,毕竟是要用maven来打包的啊。

下载地址:http://maven.apache.org/download.cgi,这个是最新版本maven的下载地址,直接下载二进制的tar.gz的压缩包即可。

在这里插入图片描述

历史版本的maven下载地址为https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/,你想要的这里都有。

安装步骤很简单,解压–>添加环境变量–>使环境变量生效–>验证

[root@localhost ~]# tar -zxf apache-maven-3.6.1-bin.tar.gz -C /usr/local/
[root@localhost ~]# vim /etc/profile
[root@localhost ~]# tail -n 2 /etc/profile
MAVEN_HOME=/usr/local/apache-maven-3.6.1
PATH=$PATH:$JAVA_HOME/bin:$MAVEN_HOME/bin
[root@localhost ~]# source /etc/profile 
[root@localhost ~]# mvn -v
Apache Maven 3.6.1 (d66c9c0b3152b2e69ee9bac180bb8fcc8e6af555; 2019-04-05T03:00:29+08:00)
Maven home: /usr/local/apache-maven-3.6.1
Java version: 1.8.0_202, vendor: Oracle Corporation, runtime: /usr/local/jdk1.8.0_202/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-693.el7.x86_64", arch: "amd64", family: "unix"

这里需要再在jenkins页面中配置下maven的家目录:

系统管理–>全局工具配置

在这里插入图片描述

三、开始构建前的准备

1、把jenkins服务器的私钥加入到server1服务器上–jenkins可以免密拷贝文件到server1上并免密执行远程命令
2、把jenkins服务器的私钥加入到gitlab服务器上–jenkins可以免密从gitlab中拉取最新的代码
3、在jenkins服务器上安装git客户端

[root@localhost ~]# yum -y install git

4、配置jenkins服务器上的maven与nexus服务器相连3、配置jenkins服务器上的maven与nexus服务器相连

[root@localhost ~]# vim /usr/local/apache-maven-3.6.1/conf/settings.xml
  <mirrors>
    <mirror>
        <id>nexus-wang</id>
        <name>nexus-wang</name>
        <mirrorOf>*</mirrorOf>
        <url>http://192.168.0.121:8081/nexus/content/groups/public</url>
    </mirror>
  </mirrors>

做好上面的准备工作之后,就可以开始构建maven项目了。

四、开始配置新项目

来到Jenkins主页面点击"新建任务"。
在这里插入图片描述
输入一个任务名称,这边就叫做"test_java",并选择"构建一个自由风格的软件项目"。点击"确定"。

在这里插入图片描述

当然,如果这个不是你创建的第一个项目,你可以在创建项目的时候直接复制其他项目的配置并点击"确定",这样可以省去很多相同的操作。

在这里插入图片描述

进入配置页面之后,先来看常规配置:

这边就讲下最常用的3个常规配置,这3个就基本够用了,其他的本人用的也不多。。。

在"描述"这一栏中写上你对这个项目的基本介绍

在这里插入图片描述

勾选"丢弃旧的项目"。自定义"保持构建的天数"和"保持构建的最大个数",我这里都设置为10

在这里插入图片描述

勾选"参数化构建过程"。添加一个"选项参数"用于选择部署、回滚还是重启;添加一个字符参数用于填写Git分支名称。

在这里插入图片描述

上面的两个名称mode和branch都是可以作为参数进程传递的,如果有必要,之后的脚本中就可以引用这两个变量的值。

这里要特别提醒下,上面的参数后面千万不能有空格,不然下面脚本中获取到的参数也是后面带空格的,脚本就会出现问题。我就是在这个地方的deploy参数后面多了空格,使得后面脚本中获取到的$mode也有空格,所以在case in 的时候总是匹配不上deploy

接着来看下"源码管理"配置

源码管理的配置就是指定Jenkins从哪个代码仓库拉取代码。毫无疑问,这里选择Git。

第一次写入地址之后,发现了128的报错:

在这里插入图片描述

这是由于jenkins是第一次用秘钥连接gitlab,需要确认。这个好办,直接在jenkins服务器上clone一下git代码仓库就好了。

在这里插入图片描述

接着来看"构建"的配置:

点击"构建"的"增加构建步骤"并选择"执行shell"

在这里插入图片描述

在这个"执行shell"里面先写入maven打包的脚本

在这里插入图片描述

到这里,先保存下配置,构建一次看看结果再说。

点击"Build with Parameters"进去,再点击"开始构建"进行构建。

在这里插入图片描述

等构建结束之后,可以在"构建历史"中查看构建的情况

在这里插入图片描述

可以看到jenkins在打包的时候从nexus上下载了很多的依赖包。最后的SUCCESS代表着编译打包成功了。

这里还要说一下,当第一次构建完一个项目之后,会在jenkins的workspace目录下生成一个以项目名称命名的目录。这个目录下,就是项目源码。因为已经变异打包完成了,所以在platform-eureka/target/目录下已经生成了相应的jar包。

[root@localhost workspace]# pwd
/root/.jenkins/workspace
[root@localhost workspace]# ls
test_java
[root@localhost workspace]# cd test_java/
[root@localhost test_java]# ls
platform-common  platform-eureka  pom.xml
[root@localhost test_java]# cd platform-eureka/
[root@localhost platform-eureka]# ls
pom.xml  src  target
[root@localhost platform-eureka]# cd target/
[root@localhost target]# pwd
/root/.jenkins/workspace/test_java/platform-eureka/target
[root@localhost target]# ll
total 59128
drwxr-xr-x 3 root root       91 Jul 31 11:24 classes
drwxr-xr-x 3 root root       25 Jul 31 11:24 generated-sources
drwxr-xr-x 3 root root       30 Jul 31 11:24 generated-test-sources
drwxr-xr-x 2 root root       28 Jul 31 11:24 maven-archiver
drwxr-xr-x 3 root root       35 Jul 31 11:24 maven-status
-rw-r--r-- 1 root root 60542506 Jul 31 11:24 platform-eureka-1.0.beta-exec.jar
-rw-r--r-- 1 root root     3963 Jul 31 11:24 platform-eureka-1.0.beta.jar
drwxr-xr-x 3 root root       17 Jul 31 11:24 test-classes

上面我们完成了编译打包,接下来要做的就是完善"执行 shell"中的脚本来实现全部的部署过程。

#!/bin/sh

. /etc/profile

project_name=platform-eureka-1.0.beta-exec
jar_name=${project_name}.jar
jar_dir=$WORKSPACE/platform-eureka/target
remote_server=192.168.0.124
remote_user=dev
remote_port=22
remote_uploaddir=/data/project/jar_upload/
remoteshell_path=/data/jenkins_shell/test_java_maven/deploy.sh

mvn2package() {
    cd $WORKSPACE
    mvn clean install -Dmaven.test.skip=true
    if [ $? -eq 0 ];then
        echo "mvn package is success!"
    else
        echo -e '\033[31m[ error ] mvn package is Failed!\033[0m' && exit 1
    fi    
    sleep 2
}

scpjar() {
    echo "transfer jar file to remote servers......"
    scp -P ${remote_port} ${jar_dir}/${jar_name} ${remote_user}@${remote_server}:${remote_uploaddir} 
    if [ $? -eq 0 ];then
        echo "transfer jar is success!"
    else
        echo -e '\033[31m[ error ] Failed to scp the jar file!\033[0m' && exit 1
    fi    
    sleep 2
}

remotedeploy() {
    mvn2package
    scpjar
    ssh -p $remote_port ${remote_user}@${remote_server} "echo "调用远程脚本" && ${remoteshell_path} ${mode} ${project_name}"
}

remoterollback() {
    ssh -p $remote_port ${remote_user}@${remote_server} "echo "调用远程脚本" && ${remoteshell_path} ${mode} ${project_name}"
}

remotereboot() {
    ssh -p $remote_port ${remote_user}@${remote_server} "echo "调用远程脚本" && ${remoteshell_path} ${mode} ${project_name}"
}

case $mode in
    deploy)
        remotedeploy
        ;;
    rollback)
        remoterollback
        ;;
    reboot)
        remotereboot
        ;;
    *)
        echo "Usage: $0 { deploy | rollback | reboot }"
        exit 1
        ;;
esac

上面的"执行 shell"中的脚本实现了maven的打包并把jar包拷贝到了远程的server1服务器上的/data/project/jar_upload目录中,所以这里要现在server1上创建jar包拷贝过去的目录。

[dev@localhost ~]$ mkdir -p /data/project/jar_upload

接着调用远程服务器的部署脚本(就是下面的这个脚本)来实现jar包的deploy、rollback、reboot的动作。

#!/bin/sh

. /etc/profile

project_name=$2
jar_name=${project_name}.jar
jar_dir=/data/project
jar_bakdir=/data/project/jar_bak
jar_upload_dir=/data/project/jar_upload
opt_port=9090
opt_active=dev
opt_xms=256m
opt_xmx=512m
log_path=/data/logs
time=`date '+%Y%m%d%H%M%S'`

check_dir() {
    for dir in {${jar_dir},${jar_bakdir}}
    do
        if [ ! -d $dir  ];then
            mkdir -p $dir
        fi
    done
}

getpid() {
   echo `ps -ef | grep ${jar_name} | grep -v grep | awk '{print $2}'`
}

stopjar()
{
    pid=$(getpid)
    if [ X"$pid" != "X" ];then
        kill -9 $pid
    elif [ X"$pid" == "X" ];then
        echo "jar is already stopped."
    fi  
}

startjar() {
    pid=$(getpid)
    if [ X"$pid" != "X" ];then
        echo "jar is already started."
    elif [ X"$pid" == "X" ];then
        cd ${jar_dir}
        nohup java -Xms${opt_xms} -Xmx${opt_xmx} -jar ${jar_dir}/${jar_name} --server.port=${opt_port} --spring.profiles.active=${opt_active} >> ${log_path}/${project_name}.log &
    fi
}

check_progress() {
    pid=$(getpid)
    if [ X"$pid" != "X" ];then
        echo "this jar progress start successfully."
    elif [ X"$pid" == "X" ];then
        echo "this jar progress start failed."
        exit 1
    fi  
}

deploy() {
    check_dir
    
    if [ ! -f "${jar_upload_dir}/${jar_name}" ];then
        echo "no jar file found in ${jar_upload_dir}."
        exit 1
    fi
    
    echo "stop jar."
    stopjar
    
    echo "backup jar."
    cp ${jar_dir}/${jar_name} ${jar_bakdir}/${project_name}_${time}.jar && mv ${jar_dir}/${project_name}.{jar,jarbak}  
    sleep 1
    mv ${jar_upload_dir}/${jar_name} ${jar_dir}/
    sleep 2
    
    echo "start jar." 
    startjar
    sleep 10
    
    echo "check progress."
    check_progress
    sleep 2
}

rollback() {
    echo "stop jar."
    stopjar    
    
    echo "rollback."
    rm -f ${jar_dir}/${jar_name} && mv ${jar_dir}/${project_name}.{jarbak,jar}
    
    echo "start jar."
    startjar
    sleep 10
    
    echo "check progress."
    check_progress
    sleep 2  
}

reboot() {
    echo "stop jar."
    stopjar 
    
    echo "start jar."
    startjar
    sleep 10

    echo "check progress."
    check_progress
    sleep 2       
}

case $1 in
    deploy)
        deploy
        echo "deploy success."
        ;;
    rollback)
        rollback
        echo "rollback success."
        ;;
    reboot)
        reboot
        echo "reboot success."
        ;;
    *)
        echo "Usage: $0 { deploy | rollback | reboot }"
        exit 1
        ;;
esac

这个脚本放置的位置需要和上一个脚本的指定位置保持一致(即/data/jenkins_shell/test_java_maven/deploy.sh)。

上面的jar包启动时的标准输出路径我是放在/data/logs目录中的,所以需要在server1上创建这个目录

[dev@localhost ~]$ mkdir -p /data/logs

然后重新来点击"开始构建",构建完成之后控制台的输出结果如下

在这里插入图片描述

回滚的操作也很简单,在开始构建之前,mode选择"rollback"即可。注意:这里回滚的是上次deploy的结果。回滚完成后控制台的输出如下

在这里插入图片描述

这样就实现了一个简单的java项目的jar包的自动化部署过程,如果是tomcat(war包)的话也是一个道理,稍作修改就可以了。

实际生产环境,我们还可以根据实际情况做相应的调整。

好了,java项目的构建就到此为止了,其实总体思路还是比较简单的,就是写脚本的时候注意点就是了,因为确实变量有点多!

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐