前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于php+shell的发布系统

基于php+shell的发布系统

作者头像
用户3094376
发布2018-09-12 11:05:46
9280
发布2018-09-12 11:05:46
举报
文章被收录于专栏:gaoqin31gaoqin31

一.发布系统要解决的问题

  一个比较完善的发布系统首先肯定是要能发布文件,其次当发布出现问题时要能支持撤销,避免长时间无法解决问题影响产品的正常运营。 对于发布脚本语言如PHP,shell加入语法检查,有语法错误阻止本次发布。

二.原理

  我们正在使用的发布系统基于PHP+shell开发,发布的时候填好文件列表,从当前机器A发布到目标机器B,发布之前A机器通过ssh协议认证登陆到B机器执行shell命令备份待发布的文件列表 然后使用rsync从A机器同步文件列表到B机器,发布完成后写入当前发布记录到数据库,当需要回滚的时候将对应的备份文件覆盖到B机器即可。

三.要解决的问题

1.使用rsync以及备份目标机器文件需要免密登陆

  A机器到B机器实现免密登陆,需要使用ssh-keygen生成当前用户的登陆秘钥,把当前用户的公钥追加到目标机器用户的 .ssh/authorized_keys文件中 以下shell是把当前机器的公钥追加到目标机器的authorized_keys文件

代码语言:javascript
复制
USER=www
IP=192.168.1.100 #B机器ip
PORT=22 #B机器SSH协议端口
cat /home/${USER}/.ssh/id_rsa.pub | ssh ${USER}@${IP} 'cat>>/home/${USER}/.ssh/authorized_keys'

后续无需输入密码即可在A机器免密登陆B机器

2.发布到多台机器   如果目标机器有多台,可以循环发布到目标机器。如果每次更新的文件过大,可以发布到一台中心节点服务器,然后使用sersync同步到其它机器。https://code.google.com/archive/p/sersync/downloads 修改config.xml rsync节点<ssh start="true"/>,并使用免密登陆的用户启动sersync服务

代码语言:javascript
复制
#!/bin/bash
#-------------------------------------------------------------------------------------------------------
#从当前机器发布文件到远程机器,如果是分布式机器,以一台机器为主节点通过sersync同步到其它节点
#
#
#参数说明
#    发布
#$1:执行动作send
#$2:远程目标机器ip
#$3:远程目标机器端口
#$4:当前机器发布根目录
#$5:远程目标机器发布根目录
#$6:远程目标机器备份根目录
#$7:发布版本号
#$8:文件列表 多个文件或者目录使用","隔开

#
#
#    回滚
#$1:执行动作roll
#$2:远程目标机器ip
#$3:远程目标机器端口
#$4:当前机器发布根目录
#$5:远程目标机器发布根目录
#$6:远程目标机器备份根目录
#$7:回滚版本号
#----------------------------------------------------------------------------------------------------

source /etc/profile
umask 022

readonly TARGET_IP=$2                        #远程目标机器ip
readonly TARGET_PORT=$3                        #远程目标机器ip
readonly USER=www                            #执行远程shell命令用户
readonly SOURCE_ROOT=$4                        #当前机器发布根目录
readonly TARGET_ROOT=$5                        #远程目标机器发布目录
readonly BACKUP_ROOT=$6                        #远程目标机器备份路径

readonly execssh="/usr/bin/ssh -p ${TARGET_PORT} -o StrictHostKeyChecking=no ${USER}@${TARGET_IP}" #在远程目标机器执行shell命令

#发布
function send(){
    IFS=","
    error=0
    aFile=($1)
    for file in ${aFile[@]}
    do
        if [ ! -e "${SOURCE_ROOT}/${file}" ];then
            fileList+={$file}
            error=1
        fi
    done

    if [ "${error}" != 0 ];then
        echo "file list is not exists in ${SOURCE_ROOT}"
        echo $fileList
        exit 1
    fi

    eval "${execssh} ${TARGET_ROOT}/cron/sendfile.sh backup ${1} ${2} ${TARGET_ROOT} ${BACKUP_ROOT}"
    
    if [ "$?" == 0 ];then
        cd ${SOURCE_ROOT}
        fileList=$(echo "${1}" | tr "," " ")
        #/usr/bin/rsync -avzR -e ssh ${fileList} ${USER}@${TARGET_IP}:${TARGET_ROOT}
        eval "/usr/bin/rsync -avzR '-e ssh -p ${TARGET_PORT}' ${fileList} ${USER}@${TARGET_IP}:${TARGET_ROOT}"
    else
        echo "back up faild!!!"
        exit 2
    fi
    exit 0
}

#回滚
function roll(){
    $execssh "tar zxf ${BACKUP_ROOT}/${1}.bak.tar.gz -C ${TARGET_ROOT}"
    echo 'ok'
}

#备份
function backup(){
    target_root=$3
    back_root=$4
    cd ${target_root}
    IFS=","
    aFile=($1)
    fileList=""
    for file in ${aFile[@]}
    do
        if [ -e "${target_root}/${file}" ];then
            fileList+="$file "
        fi
    done
    if [ -n "${fileList}" ];then
        if [ ! -d ${back_root} ];then
            mkdir -p ${back_root}
            if [ "$?" != 0 ];then
                echo "mkdir backup dir ${back_root} fail"
                exit 1
            fi
        fi
        tar czf ${back_root}/${2}.bak.tar.gz $1
        if [ "$?" == 0 ];then
            echo "backup file ${back_root}/${2}.bak.tar.gz!"
        fi 
    fi
}

function argsCheck(){
    if [ -z $2 ] || [ -z $3 ] || [ -z $4 ] || [ -z $5 ] || [ -z $6 ] || [ -z $7 ];then
        echo "useage ${0} send|roll TARGET_IP TARGET_PORT SOURCE_ROOT TARGET_ROOT BACKUP_ROOT VER"
        exit 1
    fi
    if [ ! -d $4 ];then
        echo "SOURCE_ROOT ${SOURCE_ROOT} is not exsists!"
        exit 2
    fi
}

case $1 in
    "send")
        argsCheck "$@"
        send $8 $7 #文件列表版本号
    ;;
    
    "backup")
        backup $2 $3 $4 $5
    ;;
    
    "roll")
        argsCheck "$@"
        roll $7 #版本号
    ;;
    
    *)
    echo "useage ${0} send|roll TARGET_IP TARGET_PORT SOURCE_ROOT TARGET_ROOT BACKUP_ROOT VER"
    ;;
esac
代码语言:javascript
复制
#!/bin/bash
#-------------------------------------------------------------------------------------------------------
#从当前机器发布文件到远程机器,如果是分布式机器,以一台机器为主节点通过sersync同步到其它节点
#
#
#参数说明
#    发布
#$1:执行动作send
#$2:远程目标机器ip
#$3:远程目标机器端口
#$4:当前机器发布根目录
#$5:远程目标机器发布根目录
#$6:远程目标机器备份根目录
#$7:发布版本号
#$8:文件列表 多个文件或者目录使用","隔开

#
#
#    回滚
#$1:执行动作roll
#$2:远程目标机器ip
#$3:远程目标机器端口
#$4:当前机器发布根目录
#$5:远程目标机器发布根目录
#$6:远程目标机器备份根目录
#$7:回滚版本号
#----------------------------------------------------------------------------------------------------

source /etc/profile
umask 022

readonly TARGET_IP=$2                        #远程目标机器ip
readonly TARGET_PORT=$3                        #远程目标机器ip
readonly USER=www                            #执行远程shell命令用户
readonly SOURCE_ROOT=$4                        #当前机器发布根目录
readonly TARGET_ROOT=$5                        #远程目标机器发布目录
readonly BACKUP_ROOT=$6                        #远程目标机器备份路径

readonly execssh="/usr/bin/ssh -p ${TARGET_PORT} -o StrictHostKeyChecking=no ${USER}@${TARGET_IP}" #在远程目标机器执行shell命令

#发布
function send(){
    IFS=","
    error=0
    aFile=($1)
    for file in ${aFile[@]}
    do
        if [ ! -e "${SOURCE_ROOT}/${file}" ];then
            fileList+={$file}
            error=1
        fi
    done

    if [ "${error}" != 0 ];then
        echo "file list is not exists in ${SOURCE_ROOT}"
        echo $fileList
        exit 1
    fi

    eval "${execssh} ${TARGET_ROOT}/cron/sendfile.sh backup ${1} ${2} ${TARGET_ROOT} ${BACKUP_ROOT}"
    
    if [ "$?" == 0 ];then
        cd ${SOURCE_ROOT}
        fileList=$(echo "${1}" | tr "," " ")
        #/usr/bin/rsync -avzR -e ssh ${fileList} ${USER}@${TARGET_IP}:${TARGET_ROOT}
        eval "/usr/bin/rsync -avzR '-e ssh -p ${TARGET_PORT}' ${fileList} ${USER}@${TARGET_IP}:${TARGET_ROOT}"
    else
        echo "back up faild!!!"
        exit 2
    fi
    exit 0
}

#回滚
function roll(){
    $execssh "tar zxf ${BACKUP_ROOT}/${1}.bak.tar.gz -C ${TARGET_ROOT}"
    echo 'ok'
}

#备份
function backup(){
    target_root=$3
    back_root=$4
    cd ${target_root}
    IFS=","
    aFile=($1)
    fileList=""
    for file in ${aFile[@]}
    do
        if [ -e "${target_root}/${file}" ];then
            fileList+="$file "
        fi
    done
    if [ -n "${fileList}" ];then
        if [ ! -d ${back_root} ];then
            mkdir -p ${back_root}
            if [ "$?" != 0 ];then
                echo "mkdir backup dir ${back_root} fail"
                exit 1
            fi
        fi
        tar czf ${back_root}/${2}.bak.tar.gz $1
        if [ "$?" == 0 ];then
            echo "backup file ${back_root}/${2}.bak.tar.gz!"
        fi 
    fi
}

function argsCheck(){
    if [ -z $2 ] || [ -z $3 ] || [ -z $4 ] || [ -z $5 ] || [ -z $6 ] || [ -z $7 ];then
        echo "useage ${0} send|roll TARGET_IP TARGET_PORT SOURCE_ROOT TARGET_ROOT BACKUP_ROOT VER"
        exit 1
    fi
    if [ ! -d $4 ];then
        echo "SOURCE_ROOT ${SOURCE_ROOT} is not exsists!"
        exit 2
    fi
}

case $1 in
    "send")
        argsCheck "$@"
        send $8 $7 #文件列表版本号
    ;;
    
    "backup")
        backup $2 $3 $4 $5
    ;;
    
    "roll")
        argsCheck "$@"
        roll $7 #版本号
    ;;
    
    *)
    echo "useage ${0} send|roll TARGET_IP TARGET_PORT SOURCE_ROOT TARGET_ROOT BACKUP_ROOT 
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-07-28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档