zoukankan      html  css  js  c++  java
  • [ jenkins ] git+jenkins+maven + ansible 部署java程序

    1. 工具介绍 

    git:版本控制,一般都是托管到代码仓库的。如 github、coding、gitlab (本文以 coding 为例)

    jenkins:持续集成工具之一,也是最常用的工具,主要工作就是将代码从git仓库pull下来,通过maven打包,在部署到服务器上

    maven:java 项目管理构建自动化工具,主要是将 java 源代码打包成 jar 程序

    ansible:批量部署程序所使用的工具。

    下面介绍的部署过程使用到了以上 4 个工具。

    主机介绍:

    实现思路:

    2. 持续集成实例

    2.1 首先将源代码托管到 git 仓库,具体操作自行百度,例如:coding仓库。

    我这里是一个私有仓库,请自行创建仓库。

    2.2 安装 jenkins 和 maven 工具

    【jenkins 安装过程】

    这里最好将 jenkins 配置文件修改如下:

    [root@192.168.118.17 ~]#vim /etc/sysconfig/jenkins
    ...
    JENKINS_USER="root"
    ...
    

    修改为 root 这样可以直接使用 root用户打包,不用在其他用户家目录下构建依赖包

    本次构建使用了 jenkins 的 pipeline 功能,这里需要安装一些插件:

    系统管理 -> 插件管理 -> 可选插件  搜索一下插件进行安装:

    Blue Ocean

    插件安装完成后,重启下服务:

    [root@192.168.118.17 ~]#systemctl restart jenkins
    

    安装 git 和 maven

    安装git

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

    安装 maven

    下载地址:http://maven.apache.org/download.cgi
    [root@192.168.118.17 /usr/local/src]#tar xf apache-maven-3.1.1-bin.tar.gz -C /usr/local/
    [root@192.168.118.17 /usr/local/src]#cd /usr/local/
    [root@192.168.118.17 /usr/local]#ln -vs /usr/local/apache-maven-3.1.1/ /usr/local/maven
    ‘/usr/local/maven’ -> ‘/usr/local/apache-maven-3.1.1/’
    
    [root@192.168.118.17 /usr/local]#ln -vs /usr/local/maven/bin/mvn /usr/bin/
    ‘/usr/bin/mvn’ -> ‘/usr/local/maven/bin/mvn’
    

    安装好两个工具后,首先通过 git 将源代码克隆下来,通过 maven 进行测试。

    [root@192.168.118.17 ~]#git clone https://git.dev.tencent.com/hukey/winstar-common-api.git
    [root@192.168.118.17 ~]#cd winstar-common-api/
    [root@192.168.118.17 ~/winstar-common-api]#mvn clean package -Dmaven.test.skip=true
    

    第一次通过 mvn 打包时间会长一点。

    出现如上信息,则打包完成。

    2.3 通过 ansible 将程序推送到需要部署的节点

    接下来的思路:

      通过 ansible 将 xxx.jar 文件推送到需要部署的服务器上,启动起来。

    安装 ansible 并配置:

    [root@192.168.118.17 ~]#yum install ansible -y
    

    (1)将 ansible 主机连接 程序部署主机设置为免密码登录

    [root@192.168.118.17 ~]#ssh-keygen -t rsa -P ''
    [root@192.168.118.17 ~]#ssh-copy-id root@192.168.118.19
    [root@192.168.118.17 ~]#ssh-copy-id root@192.168.118.20
    

    (2)配置 ansible 组

    [root@192.168.118.17 ~]#vim /etc/ansible/hosts
    ...
    [common-api]
    192.168.118.19:22 ansible_ssh_user=root adrser=/app/node-1/
    192.168.118.20:22 ansible_ssh_user=root adrser=/app/node-1/
    ...
    

     格式:
    ip:port ansible_ssh_user=用户名 adrser=设置一个变量,这里设置的变量为一个程序部署目录,这两台主机目录必须存在。

    (3)测试 ansible 无密码验证

    [root@192.168.118.17 ~]#ansible common-api -m ping
    192.168.118.20 | SUCCESS => {
        "changed": false, 
        "ping": "pong"
    }
    192.168.118.19 | SUCCESS => {
        "changed": false, 
        "ping": "pong"
    }
    

    (4)通过 ansible 为两台程序节点部署环境

    创建启动程序目录:
    [root@192.168.118.17 ~]#ansible common-api -m file  -a "path=/app/node-1 state=directory" 
    192.168.118.19 | SUCCESS => {
        "changed": true, 
        "gid": 0, 
        "group": "root", 
        "mode": "0755", 
        "owner": "root", 
        "path": "/app/node-1", 
        "size": 6, 
        "state": "directory", 
        "uid": 0
    }
    192.168.118.20 | SUCCESS => {
        "changed": true, 
        "gid": 0, 
        "group": "root", 
        "mode": "0755", 
        "owner": "root", 
        "path": "/app/node-1", 
        "size": 6, 
        "state": "directory", 
        "uid": 0
    }
    

    为两台程序节点安装jdk

    # 将jdk拷贝到远程主机,并解压到 /usr/local/ 目录
    [root@192.168.118.17 ~]#ansible common-api -m unarchive -a "src=/usr/local/src/jdk-8u77-linux-x64.tar.gz dest=/usr/local/"
    
    # 创建软链接文件
    [root@192.168.118.17 ~]#ansible common-api -m file -a "path=/usr/bin/java src=/usr/local/jdk1.8.0_77/bin/java state=link"
    
    [root@192.168.118.17 ~]#ansible common-api -m file -a "path=/usr/bin/javac src=/usr/local/jdk1.8.0_77/bin/javac state=link"
    

    (5)首先将 jar 包推送到两台服务器上,是为了编写启动脚本比较方便。

    [root@192.168.118.17 ~]#ansible common-api -m copy -a "src=/root/winstar-common-api/target/winstar-common-api-1.0.0-SNAPSHOT.jar dest={{adrser}}"
    

    (6)编写程序启动脚本

    [root@192.168.118.19 /app/node-1]#vim service.sh 
    #!/bin/bash
    cd /app/node-1
    start(){
      if [ -f `ls *.jar` ];then
        APP=$(ls *.jar)
        nohup java -jar $APP &
      else
        echo "Error: no app!"
      fi
    }
    
    stop(){
      pkill -9 java
    }
    
    update(){
      if [ ! -d backup ];then
        mkdir -p backup
      fi
      mv -f *.jar backup
      rm -rf nohup.out
    }
    
    
    case $1 in
    start)
      start
      ;;
    stop)
      stop
      ;;
    update)
      stop
      update
      ;;
    *)
      echo "Usage: $0 [start | stop | update]"
    esac
    

    编写了一个比较简单的脚本,这个脚本只是用来测试使用,如果生产环境使用,还有许多地方需要进行改善。

    将这个脚本放在两个程序节点 /app/node-1/目录下。

    (7)通过 ansible 测试程序能否正常启动成功

    第一步,将程序从控制节点拷贝到程序节点:

    # 安装 net-tools 包,主要用到 netstat 命令
    [root@192.168.118.17 ~]#ansible common-api -m yum -a "name=net-tools state=present"
    # 查看目前在工作的端口信息
    [root@192.168.118.17 ~]#ansible common-api  -a "netstat -ntplu"
    192.168.118.19 | SUCCESS | rc=0 >>
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
    tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      891/sshd            
    tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1454/master         
    tcp6       0      0 :::22                   :::*                    LISTEN      891/sshd            
    tcp6       0      0 ::1:25                  :::*                    LISTEN      1454/master         
    
    192.168.118.20 | SUCCESS | rc=0 >>
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
    tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      882/sshd            
    tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1369/master         
    tcp6       0      0 :::22                   :::*                    LISTEN      882/sshd            
    tcp6       0      0 ::1:25                  :::*                    LISTEN      1369/master
    
    # 将应用程序拷贝到程序节点
    [root@192.168.118.17 ~]#ansible common-api -m copy -a "src=/root/winstar-common-api/target/winstar-common-api-1.0.0-SNAPSHOT.jar dest={{adrser}}"
    

    第二步,启动程序,查看程序端口

    # 启动应用程序
    [root@192.168.118.17 ~]#ansible common-api  -a "sh {{adrser}}/service.sh start"
    # 启动完毕间隔一段时间,查看应用程序端口是否启动完成
    [root@192.168.118.17 ~]#ansible common-api  -a "netstat -ntplu"
    192.168.118.19 | SUCCESS | rc=0 >>
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
    tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      891/sshd            
    tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1454/master         
    tcp6       0      0 :::3090                 :::*                    LISTEN      3447/java           
    tcp6       0      0 :::3091                 :::*                    LISTEN      3447/java           
    tcp6       0      0 :::22                   :::*                    LISTEN      891/sshd            
    tcp6       0      0 ::1:25                  :::*                    LISTEN      1454/master         
    
    192.168.118.20 | SUCCESS | rc=0 >>
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
    tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      882/sshd            
    tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1369/master         
    tcp6       0      0 :::3090                 :::*                    LISTEN      3200/java           
    tcp6       0      0 :::3091                 :::*                    LISTEN      3200/java           
    tcp6       0      0 :::22                   :::*                    LISTEN      882/sshd            
    tcp6       0      0 ::1:25                  :::*                    LISTEN      1369/master
    

    应用端口:3090,管理端口:3091 说明启动成功。

    至于 stop 和 update 可以自行测试,必须要保证脚本的可用性,因为后面会用到。

    2.4 配置 jenkins pipeline流水线

    登录 jenkins -> 新建任务

    应用并保存,这样 jenkins 配置已经完成。要使用 jenkins 的 pipeline 功能,要需要在 git 仓库里新增几个配置文件。

    2.5 在 git 仓库配置 pipeline 文件

     登录到仓库页面

    Jenkinsfile 文件内容如下:

    pipeline{
        agent any
        stages {
            stage('Build') {
                steps{
                    sh 'mvn clean package -Dmaven.test.skip=true'
                    echo 'Build success.'
                }
            }
            stage('Test') {
                steps{
                    sh 'mvn test'
                }
                post {
                    always {
                        junit 'target/surefire-reports/*.xml' 
                    }
                }
            }
            stage('Deliver') { 
                steps {
                    sh 'sh ./jenkins/scripts/deliver.sh' 
                }
            }
        }
    }
    

    代码内容很简单,分为三段:

    1. 打包
    2. 测试
    3. 发布

    重点关注下 第三个 发布是通过出一个脚本来实现的。因此这个目录和脚本必须也放置到 git 仓库。 将 jenkins pipeline 配置文件和脚本放置到 git仓库,这样更易于维护,而且对 jenkins 的使用会更加灵活。

    注意脚本放置的目录,脚本内容如下:

    #!/bin/bash
    # Author: hukey
    # date: 2019-07-16 17:23:20
    #
    function status(){
    ansible common-api -a "netstat -ntplu"
    }
    
    function update(){
      if [ ! -f target/*.jar ];then
          echo '[Error]:java.jar not exist, update failed.'
          exit 1
      fi
      JAR=$(ls target/*.jar)
      ansible 'common-api' -m shell -a '{{adrser}}/service.sh update'
      ansible 'common-api' -m copy -a "src=$JAR dest={{adrser}}"
    }
    
    function start(){
      ansible 'common-api' -m shell -a '{{adrser}}/service.sh start'
    }
    
    update
    sleep 3
    start
    

    上面的脚本,必须和 app-node 中的脚本对应着来看,简要说下:

    首先 执行 update 操作,将 app-node 上的应用程序停止并备份到backup目录,将本地的 jar 程序拷贝到 app-node 节点;

    再次 通过 start 将 app-node 上的程序启动起来。

    这样一个持续性的流水线工作就完成了。

    3. 持续集成测试

    点击构建,然后查看后台日志输出信息:

    当返回 SUCCESS 说明构建成功了。也可以通过 Blue Ocean 查看

    到这里, 采用 jenkins 构建 java 项目持续集成已经完毕,这里采用的是手动触发构建,如果需要自动构建可以通过 webHook 来实现。

  • 相关阅读:
    SQL Server 2008 Windows身份验证改为混合模式身份验证
    SQL中给datetime类型变量赋值
    结婚三周年特此@Mark一下
    搞笑的【国庆出游五大注意事项】
    利用SVNListParentPath增加http浏览仓库根目录的功能
    如果年底买不到CC就出手小指吧
    svn备份策略
    缺乏配置管理造成的常见问题
    高速公路开车必看的注意事项
    山雨欲来踏上Java学习之路
  • 原文地址:https://www.cnblogs.com/hukey/p/11232424.html
Copyright © 2011-2022 走看看