[ jenkins ] git+jenkins+maven + ansible 部署java程序

1. 工具介紹 

git:版本控制,通常都是託管到代碼倉庫的。如 github、coding、gitlab (本文以 coding 爲例)html

jenkins:持續集成工具之一,也是最經常使用的工具,主要工做就是將代碼從git倉庫pull下來,經過maven打包,在部署到服務器上java

maven:java 項目管理構建自動化工具,主要是將 java 源代碼打包成 jar 程序node

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

 

下面介紹的部署過程使用到了以上 4 個工具。git

 

主機介紹:github

 

實現思路:web

 

 

2. 持續集成實例

 

2.1 首先將源代碼託管到 git 倉庫,具體操做自行百度,例如:coding倉庫。shell

我這裏是一個私有倉庫,請自行建立倉庫。apache

 

2.2 安裝 jenkins 和 maven 工具vim

 

【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 來實現。

相關文章
相關標籤/搜索