基于Gitlab+Jenkins的代码自动化发布

栏目: Java · 发布时间: 7年前

内容简介:这里所讲的自动化发布是指代码从提交到仓库,到发布到目标服务器的整个过程。主要涉及到两个工具Gitlab,Jenkins,要完成自动化还需要rsync,qqbot,log,ant、shell脚本,python等。Gitlab:我们主要用它来做代码的仓库

这里所讲的自动化发布是指代码从提交到仓库,到发布到目标服务器的整个过程。

主要涉及到两个工具Gitlab,Jenkins,要完成自动化还需要rsync,qqbot,log,ant、 shell 脚本,python等。

Gitlab:我们主要用它来做代码的仓库

Jenkins:用来执行任务的持续集成,构建等。

一、大体的自动化思路:

开发人员push代码到gitlab,触发webhook,调用jenkins job。 jenkins job 执行拉取代码,编译,调用loadblance,下架部分服务器更新代码,验证更新后的可用性,上线;再下架另一部分服务器,更新代码,再上线。 更新完后,将本次发布的状态信息推送给项目组。

二、实际工作中,我们遇到的比以上要复杂。

服务器环境包括:测试环境,开发环境,预发布环境,生产环境等。 代码仓库又分为多个分支:master分支,开发分支,项目分支,本地分支等。

因此要完成整个过程自动化,还需要整合多分支,多环境的情况。

三、测试环境的自动化思路:

1.建一个dev分支用来专门发布测试环境,此分支只允许开发人员合并代码和push,不能直接在上面改代码。 2.开发人员开发一个功能,先在本地建一个本地分支,写完后合并到dev,然后push到gitlab,gitlab触发钩子事件,调用jenkins完成项目的自动化部署。

以上2点看似已经实现了自动化发布,但实践发现,开发人员仍需花不少时间在代码的提交 ,切换分支,合并分支,push代码等重复而繁琐的工作上。于是这里我做了对GIT操作的自动化,将提交、切换、合并、push整合整合起来成工具,后面会列出 工具 代码。

四、预发布环境的自动化思路:

1.预发布的自动化采用和测试环境一样的思路,只是dev分支换成了master分支。 2.master分支:我们用它来发布预发布和生产环境,对没错两套环境用同一分支,此分支只有项目经理有权限push,普通开发没权限操作。

以上2点看似也实现了代码的自动化发布,但实际工作中项目经理同样也要花不少时间在代码的提交 ,切换分支,合并分支,push代码等重复繁琐的工作,因此这里也要解决项目经理Git操作的自动化,后面列出工具。

五、生产环境的自动化发布:

生产环境的发布其实只是取消了webhook的自动触发jenkins job,改为手动点击发布,主要是为发布安全考虑。

六、实操:

1.设置webhook,对测试环境job和预发布环境job设置相应的钩子事件:

基于Gitlab+Jenkins的代码自动化发布

2.在jenkins中配置git插件

基于Gitlab+Jenkins的代码自动化发布

3.配置jenkins job,这里我用shell脚本做一系列的job,不需要像网上安装各种繁琐的插件。

#!/bin/bash
#本案例中WORKSPACE=/root/.jenkins/workspace/dev_test

#源目录
src="$WORKSPACE/WebRoot/"

#发布的目标目录
dest="/usr/local/apache-tomcat-6.0.39/webapps/xiangmu/"

#目标主机用户
user="root"

#目标主机,测试机1、测试机2
host1="10.111.111.1"
host2="10.111.111.2"

# 需要发布的文件列表
cd $WORKSPACE
change_file_list=`git diff --name-only HEAD~ HEAD`
echo "需要发布的文件列表:$change_file_list"

#定义机器人发布消息功能函数
function qqbot_deploy(){
proj_name=`git show $commitid --pretty=format:"%s" |sed -n 1p`

author=`git show $commitid --pretty=format:"%an" |sed -n 1p`

now_time=`date "+%Y-%m-%d %H:%M:%S"`

qq send group IT群 "
QQ消息机器人:
【测试环境】 发布时间:$now_time 自动化发布完成
项目:$proj_name 状态:$status $solution
发布的文件列表:$change_file_list
发布人:$author" &
} 

# 定义执行命令成功或失败日志记录功能函数
function log(){
  if [ $? -eq 0 ];then
      echo "执行'$arg'成功"
  else
      echo "执行'$arg'失败"
      status="发布失败"
      qqbot_deploy
      exit 1
  fi
}

# 定义 java 编译功能函数
function ant_shell(){
  #jdk需要基于1.7,ant低于1.9编译
  cd $WORKSPACE
  arg="编译"
  #ant >/dev/null 2>&1
  ant
  log

  # 一套代码,定义配置文件中心,拷贝不同的配置文件到不同的环境。这里拷贝测试环境配置文件到测试环境
  \cp -rf conf/xiangmu/dev/system_dev.properties WebRoot/WEB-INF/classes/system.properties

  \cp -rf conf/xiangmu/dev/ApplicationContext_dev.xml WebRoot/WEB-INF/classes/spring/ApplicationContext.xml

  \cp -rf conf/xiangmu/dev//ApplicationContext-service_dev.xml WebRoot/WEB-INF/classes/spring/ApplicationContext-service.xml
}

# 定义java发布功能函数
function deploy_java(){
    #1.编译
    ant_shell

    #2.对e互助测试1的操作
    #2.1修改测试机1的负载均衡的值为0
    arg="修改负载均衡的值"
    python ModifyLoadBalancerBackends_test1_value0.py
    log
    sleep 3

    #2.2发布测试机1的代码,rsync安静模式同步
    arg="发布$host1代码"
    rsync -e 'ssh -o stricthostkeychecking=no -p22' -qapgolr --progress --delete $src $user@$host1:$dest
    log

   #2.3重启测试机1的tomcat
    ssh $host1 /home/tomcat/ver/restart_tomcat.sh&
    sleep 18
    status_code1=`curl -I -m 10 -o /dev/null -s -w %{http_code} http://$host1/planweb/index.do`

    if [ $status_code1 -eq 200 ]
    then
        echo "http://$host1/planweb/index.do 打开正常"
    else
        echo "http://$host1/planweb/index.do 打开失败"

        #发布失败通知消息到qq群
        solution="原因和方案:可能tomcat启动时间过长的误报,延长sleep时间,重新发布一次"
        status="发布失败"
        qqbot_deploy
        exit 1
    fi      

    #3.上线测试机1,并下线测试机2,修改测试机1的负载均衡值为10,修改测试机2的值为0
    arg="修改负载均衡的值"
    python ModifyLoadBalancerBackends_test1_value10.py   
    log

#4.对测试机2的操作
    #4.1发布代码到测试机2
    arg="发布$host2代码"
    rsync -e 'ssh -o stricthostkeychecking=no -p22' -aqpgolr --progress --delete $src $user@$host2:$dest
    log

    #4.2重启测试机2的tomcat
    ssh $host2 /home/tomcat/ver/restart_tomcat.sh&
    sleep 22
    status_code2=`curl -I -m 10 -o /dev/null -s -w %{http_code} http://$host2/planweb/index.do`

    if [ $status_code2 -eq 200 ]

    then
        echo "http://test.xiangmu.com 打开正常"
            #4.3上线测试机2,修改测试1的值为10,全部上线
            arg="修改负载均衡的值"
            python ModifyLoadBalancerBackends_test2_value10.py
            log

            echo "测试机$host1,$host2上线java代码完成"           
            #动态文件,发布成功消息通知到qq群
            status="发布成功"
            qqbot_deploy

            #退出循环
            exit 0 
    else
        echo "http://test.xiangmu.com打开失败"
        #发布失败通知消息到qq群
        status="发布失败"
        solution="原因和方案:可能tomcat启动时间过长,重置clb,查看tomcat启动log"
        qqbot_deploy
        exit 1
    fi
}

# 定义静态文件发布功能函数,无需重启tomcat
function deploy_static(){
    arg="发布$host1的静态代码"
    rsync -e 'ssh -o stricthostkeychecking=no -p22' -qapgolr --progress --delete $src $user@$host1:$dest 
    log

    arg="发布$host2的静态代码"     
    rsync -e 'ssh -o stricthostkeychecking=no -p22' -qapgolr --progress --delete $src $user@$host2:$dest
    log
}

#异步执行:代码质量分析。
function code_quality_analysis(){
    if [ ! -f "sonar-project.properties" ];then
        echo -e "sonar.projectKey=dev_test \nsonar.host.url=http://localhost:9000/sonar \nsonar.projectName=dev_test \nsonar.projectVersion=1.0 \nsonar.sources=src \nsonar.java.binaries=build/WEB-INF/classes" >sonar-project.properties  
    fi

    BUILD_ID=
    /usr/local/sonar-scanner/bin/sonar-scanner &
    echo "开始异步运行代码质量分析"
}

#定义代码发布功能函数
function deploy(){
    #标记静态文件出现的次数,解决遇到静态文件重复同步多次的问题
    count=0

    #遍历发布的文件列表
    for i in $change_file_list;
    do  
        # 遇到有java等后缀需要编译的文件,则编译发布。
        if [ "${i##*.}"x = "java"x ] || [ "${i##*.}"x = "xml"x ] || [ "${i##*.}"x = "properties"x ];then

            #发布编译的代码
            deploy_java

        # 如果是前端静态文件,则无需编译直接发布。第一次遇到静态发布一次,再遇到静态则不发布。   
        elif [ ! "${i##*.}"x = "java"x ] || [ ! "${i##*.}"x = "xml"x ] || [ ! "${i##*.}"x = "properties"x ] && [ $count -eq 0 ];then

            #发布静态文件
            deploy_static

            #标记为1,记已同步一次代码
            count+=1
        fi
     done

    #全静态文件,发送消息通知到qq群
    status="发布成功"
    echo "全静态文件发布完成"
    qqbot_deploy
  }

#紧急回滚措施,只是发布回滚,实际git上面没回滚,事后得修改原先bug重新提交发布。
function rollback(){
    cd ${WORKSPACE}
    echo "commitid:$commitid"
    if [ ! $commitid ] && [ ! $file ];then
        echo "commitid和file至少填一个"
        exit 1
    elif [ ! $commitid ] && [ $file ];then
        #回滚某个文件到上一次的更改
        num=2
        commitid=`git log -n $num --pretty=format:"%H" $file |sed -n ${num}p`

        git checkout $commitid $file
        deploy
    else
        arg="回滚"
        # 回滚到指定的commit版本,或者回滚指定版本的某个文件
        # git log WebRoot/campaign/daily/share.js 可以查看share.js最近修改的记录

        git checkout $commitid $file
        log

        #发布回滚的版本    
        deploy
    fi  
}

case $select in
    Deploy)
        echo "select:$select"
        commitid=`git rev-parse remotes/origin/dev`
        #发布
        deploy
        ;;
    Rollback)
        echo "select:$select"
        #回滚
        rollback
        ;;
    *)
        echo "*select:$select"
        commitid=`git rev-parse remotes/origin/dev`
        deploy
        ;;
esac

4.实际效果

基于Gitlab+Jenkins的代码自动化发布

开发人员自动化git工具

#coding:utf-8
#author:laocao
#date: 20181225
#测试环境运行在 python 3.6 windows上

import os
from time import sleep

code_dir = "D:\\proj\\xiangmu"
#code_dir = "D:\git\xiangmu-git"
print("------------提×××并本地分支的代码到dev----------")
print("注意:本程序运行的的前提,代码必须在D:\proj\xiangmu中")
print("")
print("")

os.chdir(code_dir)
print("当前工作目录:" + os.getcwd())

#输入分支名称,拉取远端dev最新代码到本地
my_branch=input('请输入您本地的分支名称:')
os.system("git checkout %s" % my_branch)
os.system("git pull origin dev")

#输入项目描述,并提交到本地
desc=input('请输入项目描述:')
os.system("git add -A")
os.system("git commit -am '%s'" % desc)

# 切换到dev分支,拉取dev最新代码
os.system("git checkout dev")
os.system("git pull")

#合并本地分支到dev,并推送
os.system("git merge %s" % my_branch)
os.system("git push")

#返回本地分支
os.system("git checkout %s" % my_branch)
print("提交成功,返回本地分支%s" % my_branch)
input("按任意键退出")

6.项目经理自动化git工具,根据commitid合并

#coding:utf-8
#author:jorden
#date: 20181225
#测试环境运行在python3.6 windows上
import os
from time  import sleep

code_dir = "D:\\proj\\xiangmu"
#code_dir = "D:\git\xiangmu-git"

print("------------合并dev的代码到master----------")
print("注意:本程序运行的的前提,代码必须在D:\proj\xiangmu中")
print("")
print("")

os.chdir(code_dir)
print("当前工作目录:" + os.getcwd())

# 切换到dev分支,拉取dev最新代码
os.system("git checkout dev")
os.system("git pull")

# 切换到master分支,拉取master最新代码
os.system("git checkout master")
os.system("git pull")

dev_commitid=input('请输入dev中需要合并的commitid:')
print(dev_commitid)
os.system("git cherry-pick " + dev_commitid)
print("dev_commitid: %s" % dev_commitid)
os.system("git push")
print("git自动合并完成")
input("按任意键退出")

7.项目经理自动化工具,根据文件合并版本。

#coding:utf-8
#author:laocao
#date: 20181225
#测试环境运行在python3.6 windows上

import os
from time  import sleep

code_dir = "D:\\proj\\xiangmu"
#code_dir = "D:\git\xiangmu-git"

print("------------合并dev的代码到master,按文件合并----------")
print("注意:本程序运行的的前提,代码必须在D:\proj\xiangmu中")
print("")
print("")

os.chdir(code_dir)
print("当前工作目录:" + os.getcwd())

# 切换到dev分支,拉取dev最新代码
os.system("git checkout dev")
os.system("git pull")

# 切换到master分支,拉取master最新代码
os.system("git checkout master")
os.system("git pull")

#dev_commitid=input('请输入dev中需要合并的commitid:')
file_list = input('请输入dev中需要合并的文件列表:')
os.system("git checkout dev " + file_list)
print("file_list: %s" % file_list)

#输入项目描述,并提交到本地master
desc=input('请输入项目描述:')
os.system("git add -A")
os.system("git commit -am '%s'" % desc)
os.system("git push")
print("git自动合并完成")
input("按任意键退出")

8.脚本完成了如下功能:

编译:根据实际项目,这里用的ant。也可以maven

动静分离发布:为了满足前端和后端的不同的发布需求,提高发布效率,采用了动静分离发布。纯静态文件直接同步到各服务器,只需几秒钟。动态文件发布则需编译,调用负载均衡,重启tomca等,需1-2分钟。

代码质量分析: 发布完,sonar自动分析开发人员代码仓库的代码质量,作为后期改进。

代码同步:采用rsync ssh模式进行代码同步到目标服务器

调用负载均衡api:通过python sdk调用腾讯云负载均衡api,来上下线服务器。

日志记录: 每条命令的执行结果进行记录。

定义代码配置中心:一套代码需要放在几个环境中运行,所以定义了不同的配置区分不同的环境, 发布时拷贝相对应的配置文件到目标服务器,这样就达到了只需管理一套代码,运行在不同的环境。

代码回滚:有时发布上去的代码有问题,这时可以紧急回滚,此处提供了按commitid来回滚和按文件回滚两种方式

发布过程中会对网站状态进行判断,如果打开不是200,则不上线。

9.消息通知:采用qqbot机器人自动发消息通知到群,让团队了解发布状态。qqbot采用smartqq协议,由于腾讯已下线,这里可以采用其他机器人插件(如酷Q),原理一样。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Compilers

Compilers

Alfred V. Aho、Monica S. Lam、Ravi Sethi、Jeffrey D. Ullman / Addison Wesley / 2006-9-10 / USD 186.80

This book provides the foundation for understanding the theory and pracitce of compilers. Revised and updated, it reflects the current state of compilation. Every chapter has been completely revised ......一起来看看 《Compilers》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具