zoukankan      html  css  js  c++  java
  • 使用shell脚本完成自动化部署及秒级回滚

    一、部署机代码目录结构

      使用www用户进行代码部署,所有部署机上需要创建www用户,并赋予根目录权限,同时配置公私钥认证建立信任关系。

    [www@ansible-node1 deploy]$ tree
    .
    ├── code
    │?? └── web-demo  #存放代码
    │??     ├── index.html
    │??     └── 351227256
    ├── config             #存放服务器配置文件
    │?? └── web-demo
    │??     ├── base
    │??     │?? └── config.ini
    │??     └── other
    │??         └── 192.168.226.130.crontab.xml  #不同机器之间的差异匹配值文件
    ├── tar  
    └── tmp

    二、部署节点

    ip:192.168.226.130、192.168.226.132 分别模拟两个主机组来部署不同代码

    web根目录: /webroot/webdemo、同时赋予www用户权限

    历史代码版本保存路径: /opt/webroot、同时赋予www用户权限

    三、使用gitlab来管理代码(在此不做介绍)

    四、主要作用

      通过脚本,模拟线上环境,实现代码的半自动化部署,以及秒级回滚。

    五、脚本实现  

      流程:获取代码(直接拉取)-----> 编译(可选)-------> 配置文件 ------>打包 -----> scp到目标服务器---->将目标机服务器移除集群----->解压---->放置到webroot----->scp差异文件----->重启(可选)----->测试----->加入集群

    [www@ansible-node1 ~]$ cat deploy.sh
    #!/bin/bash
    
    #Node List
    GROUP1_LIST="192.168.226.130"
    GROUP2_LIST="192.168.226.132"
    ROLLBACK_LIST="192.168.226.130 192.168.226.132"
    
    #Date/Time Veriables
    LOG_DATE=`date "+%Y-%m-%d"`
    LOG_CTIME=`date "+%H-%M-%S"`
    
    CDATE=$(date "+%Y-%m-%d")
    CTIME=$(date "+%H-%M-%S")
    
    #Shell Env
    SHELL_NAME="deploy.sh"
    SHELL_DIR="/home/www/"
    SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log"
    
    #Code Env
    PRO_NAME="web-demo"
    CODE_DIR="/deploy/code/web-demo"
    CONFIG_DIR="/deploy/config/web-demo"
    TMP_DIR="/deploy/tmp"
    TAR_DIR="/deploy/tar"
    LOCK_FILE="/tmp/deploy.lock"
    
    usage(){
            echo $"Usage: $0 {deploy | rollback  [ list | version]}"
    }
    
    writelog(){
            LOGINFO=$1
            echo "${CDATE} ${CTIME}: ${SHELL_NAME} : ${LOGINFO}" >> ${SHELL_LOG}
    }
    
    shell_lock(){
            touch ${LOCK_FILE}
    }
    
    shell_unlock(){
            rm -rf ${LOCK_FILE}
    }
    
    code_get(){
            writelog code_get
            cd $CODE_DIR && git pull    #需要提前从git仓库clone代码到部署机代码存放目录$CODE_DIR
            cp -r ${CODE_DIR} ${TMP_DIR}/
            API_VERL=$(git show | grep commit  | cut -d ' ' -f2)
            API_VER=$(echo ${API_VERL:0:6})
    }
    
    code_build(){
            echo code_build
    }
    
    code_config(){
            echo code_config
            /bin/cp -r $CONFIG_DIR/base/* $TMP_DIR/"${PRO_NAME}"
            PKG_NAME="${PRO_NAME}_"${API_VER}"_"${CDATE}-${CTIME}""
            cd ${TMP_DIR} && mv ${PRO_NAME} ${PKG_NAME}
    }
    
    code_tar(){
            writelog "code_tar"
            cd ${TMP_DIR} && tar czf ${PKG_NAME}.tar.gz ${PKG_NAME}
            writelog "${PKG_NAME}.tar.gz"
    }
    
    code_scp(){
            writelog "code_scp"
            for node in $GROUP1_LIST;do
                    scp ${TMP_DIR}/${PKG_NAME}.tar.gz  $node:/opt/webroot
            done
            for node in $GROUP2_LIST;do
                    scp ${TMP_DIR}/${PKG_NAME}.tar.gz  $node:/opt/webroot
            done
    
    }
    
    cluster_node_remove(){
            writelog "iluster_node_remove"
    }
    
    url_test(){
            URL=$1
            curl -s --head $URL | grep "200 OK"
            if [ $? -ne 0 ];then
                    shell_unlock;
                    writelog "test error" && exit;
            fi
    }
    
    group1_deploy(){
            echo code_deploy
            for node in $GROUP1_LIST;do
                    ssh $node "cd /opt/webroot && tar zxf ${PKG_NAME}.tar.gz"
                    ssh $node "rm -rf /webroot/web-demo && ln -sf /opt/webroot/${PKG_NAME} /webroot/web-demo"
        done
    }
    
    group1_test(){
            url_test "http://192.168.226.130/index.html"
            echo "add to cluster"
    }
    group2_deploy(){
            echo code_deploy
            for node in $GROUP2_LIST;do
                    ssh $node "cd /opt/webroot && tar zxf ${PKG_NAME}.tar.gz"
                    ssh $node "rm -rf /webroot/web-demo && ln -sf /opt/webroot/${PKG_NAME} /webroot/web-demo"
        done
    }
    
    group2_test(){
            url_test "http://192.168.226.132/index.html"
            echo "add to cluster"
    }
    
    config_diff(){
            echo config_diff
            scp ${CONFIG_DIR}/other/192.168.226.130.crontab.xml 192.168.226.130:/webroot/web-demo/crontab.xml
    }
    
    code_test(){
            echo code_test
    }
    
    cluster_node_in(){
            echo cluster_node
    }
    
    rollback_fun(){
            for node in $ROLLBACK_LIST;do
                    ssh $node "rm -rf /webroot/web-demo && ln -sf /opt/webroot/$1 /webroot/web-demo"
        done
    
    }
    
    rollback(){
            if [ -z $1 ];then 
                    shell_unlock;
                    echo "Please input rollback version" && exit
            fi
            case $1 in
                    list)
                            ssh $GROUP1_LIST "ls -l /opt/webroot/*.tar.gz"
                            ;;
                    *)
                            rollback_fun $1
            esac
    }
    
    
    main(){
            if [ -f $LOCK_FILE ];then
                    echo "Deploy  is running" && exit;
            fi
            DEPLOY_METHOD=$1
            ROLLBACK_VER=$2
            case $DEPLOY_METHOD in
                    deploy)
    
                                    shell_lock;
                                    code_get;
                                    code_build;
                                    code_config;
                                    code_tar;
                                    code_scp;
                                    cluster_node_remove;
                                    group1_deploy;
                                    config_diff;
                                    group1_test;
                                    group2_deploy;
                                    group2_test;
                                    cluster_node_in;
                                    shell_unlock;
                                    ;;
                    rollback)
    
                                    shell_lock
                                    rollback $ROLLBACK_VER;
                                    shell_unlock;
                                    ;;
                    *)
                                    usage;
            esac
    }
    main $1 $2

    六、执行脚本

    [www@ansible-node1 ~]$ bash deploy.sh 
    Usage: deploy.sh {deploy | rollback  [ list | version]}
    [www@ansible-node1 ~]$ bash deploy.sh deploy  #部署代码
    
    [www@ansible-node1 ~]$ bash deploy.sh rollback list  #列出代码版本
    -rw-rw-r-- 1 www www  228 Mar  7 17:03 /opt/webroot/web-demo_123_2018-03-07-17-03-52.tar.gz
    -rw-rw-r-- 1 www www  231 Mar  7 17:05 /opt/webroot/web-demo_123_2018-03-07-17-05-24.tar.gz
    -rw-rw-r-- 1 www www  233 Mar  7 17:07 /opt/webroot/web-demo_123_2018-03-07-17-07-02.tar.gz
    -rw-rw-r-- 1 www www  231 Mar  7 17:10 /opt/webroot/web-demo_123_2018-03-07-17-10-36.tar.gz
    -rw-rw-r-- 1 www www  234 Mar  8 16:24 /opt/webroot/web-demo_123_2018-03-08-16-24-17.tar.gz
    -rw-rw-r-- 1 www www  230 Mar  8 16:26 /opt/webroot/web-demo_123_2018-03-08-16-26-51.tar.gz
    -rw-rw-r-- 1 www www  230 Mar  8 16:30 /opt/webroot/web-demo_123_2018-03-08-16-30-15.tar.gz
    -rw-rw-r-- 1 www www  229 Mar  8 16:31 /opt/webroot/web-demo_123_2018-03-08-16-31-25.tar.gz
    
    
    [www@ansible-node1 ~]$  bash deploy.sh rollback web-demo_3d9c99_2018-03-12-16-27-54  #回滚到指定版本
  • 相关阅读:
    一些有关时间的获取
    Devexpress xaf用代码打开菜单(Navigation Item)
    Devexpress xaf BO中字段为RuleRequiredField必输字段时,文本标签默认添加*标记
    Devepxress xaf Dashboard中DetailView控件使其可编辑
    Devexpress WinForm TreeList的三种数据绑定方式(DataSource绑定、AppendNode添加节点、VirtualTreeGetChildNodes(虚拟树加载模式))
    Devexpress xaf针对某个用户登录后在面板中设置导航无效的解决方法
    IIS不能下载config配置文件的解决方法
    DevExpress WPF控件记录
    Devexpress WinForm GridControl实现单元格可编辑状态更改
    Devexpress GridControl中 repositoryItemCheckEdit作为选择列以及作为显示列的使用方法
  • 原文地址:https://www.cnblogs.com/lwf-blog/p/8550411.html
Copyright © 2011-2022 走看看