自动且不中断双版本上线(灰度及正式版本)
jenkins: extend choice permetes负责前端页面、编辑参数,及pipeline。
shell: 流程逻辑判断
ansible: 批量及任务执行
#!/bin/bash
########################################################################################################################################
##定义变量###
##1、jenkins传值变量
prodName=$1
brancheVersion=$2
select_project=$3
jkworkspace=$4
service_port=$5
web_port=$6
service_port2=$7
web_port2=$8
xms=$9
xmx=${10}
##2、本地变量
Server_ip1=xxx.xxx.xxx.xxx
Server_ip2=yyy.yyy.yyy.yyy
Server_ip1_intra=172.19.18.7
Server_ip2_intra=172.19.18.8
VERSION=$(ssh root@${Server_ip1} “ps -aux |grep -v lsmc-oss|grep -v grep|grep -v tail|grep -v vim|grep ${prodName}-${select_project}”|awk ‘{print $NF}’|awk -F [-] ‘{print $4}’)
VERSION2=$(ssh root@${Server_ip2} “ps -aux |grep -v lsmc-oss|grep -v grep|grep -v tail|grep -v vim|grep ${prodName}-${select_project}”|awk ‘{print $NF}’|awk -F [-] ‘{print $4}’)
ip_a1=$(ssh root@${Server_ip1} “ifconfig eth0|grep netmask”|awk ‘{print $2}’)
ip_a2=$(ssh root@${Server_ip2}”ifconfig eth0|grep netmask”|awk ‘{print $2}’)
nginx_dir=/data/tengine-2.3.0/conf
source /etc/profile
Date_now=`date “+%Y-%m-%d-%H:%M:%S”`
#############################################################################################################################################################
#############################################################################################################################################################
##3.定义用到的函数
function version1_lt() { test “$(echo “$@” | tr ” ” “\n” | sort -rV | head -n 1)” != “$1”; }
function version2_lt() { test “$(echo “$@” | tr ” ” “\n” | sort -rV | head -n 1)” != “$1”; }

function Server_1 {
#############服务判断#####################
old_version=$VERSION
run_version=$VERSION2
run_ip_port=$(ssh root@$Server_ip1 “cat $nginx_dir/nginx.conf|grep -A 1 $prodName-runip|grep -v $prodName-runip|awk -F ‘[/]’ ‘{print \$3}'”)
old_ip_port=$(ssh root@$Server_ip1 “cat $nginx_dir/nginx.conf|grep -A 1 $prodName-oldip|grep -v $prodName-oldip|awk -F ‘[/]’ ‘{print \$3}'”)

if [ “$select_project” == “web” ];then
echo “step2:项目为前端web”
now_port=$(ssh root@$Server_ip1 “ps -aux |grep $prodName-$select_project|grep port|grep -v grep|awk -F [=] ‘{print \$2}’|awk ‘{print \$1}'”)
elif [ “$select_project” == “service” ];then
echo “step2:项目为后端service”
now_port=$(ssh root@$Server_ip1 “ps -aux |grep $prodName-$select_project|grep port|grep -v grep|awk -F [=] ‘{print \$3}’|awk ‘{print \$1}'”)
else
echo “step2:目标机器不存在启动端口,可能存在手工启动的情况,请登陆服务器检查”
exit 0
fi
#######端口异常的判断##################
w_port=$(ssh root@$Server_ip1 “ps -aux |grep $prodName-$select_project|grep port|grep -v grep|grep -v lsmc-oss|wc -l”)
if [ $w_port -eq 0 ] ; then
echo “step3:线上不存在启动的端口,可能存在人工启动或服务停止的情况,请登陆服务器检查”
exit 0
elif [ $w_port -gt 2 ] ; then
echo “step3:存在两个同样的端口,可能存在人工启动的情况,请登陆服务器检查”
exit 0
else
echo “step3:端口状态检测正常现在将进行下一步”
fi
############替换NGINX配置文件#############
if [ “$select_project” == “web” ] && [ “$now_port” == “$web_port” ] ;then
echo “step4:项目为前端web,目前使用$now_port 现在开始替换NGINX配置文件,使用$web_port2 端口”
###替换版本号####
ssh root@$Server_ip1 “sed -i ‘/$prodName-runver/{n;s/$run_version/$brancheVersion/;}’ $nginx_dir/nginx.conf”
echo “替换$prodName-runver 下的$run_version 为$brancheVersion”
ssh root@$Server_ip1 “sed -i ‘/$prodName-oldver/{n;s/$old_version/$run_version/;}’ $nginx_dir/nginx.conf”
echo “替换$prodName-oldver 下的$old_version 为 $run_version”
#ssh root@$Server_ip1 “sed -i ‘/$prodName-update-info/{n;s/$old_version/$run_version/;}’ $nginx_dir/nginx.conf”
#echo “替换通知更新$prodName-update-info下的$old_version 为 $run_version”

###替换IP及端口##
ssh root@$Server_ip1 “sed -i s/$run_ip_port/$ip_a1:$web_port2/g $nginx_dir/nginx.conf”
echo “替换$run_ip_port 为 $ip_a1:$web_port2”
ssh root@$Server_ip1 “sed -i s/$old_ip_port/$run_ip_port/g $nginx_dir/nginx.conf”
echo “替换$old_ip_port 为$run_ip_port”

###执行ANSBILE-PALYBOOK 1
echo “step5:开始使用ansibl-playbook部署启动”
cd /etc/ansible
ansible-playbook prod_fix_lsmc_web1_1.yml –extra-vars “prodName=${prodName} brancheVersion=${brancheVersion} old_ver=$VERSION run_ver=$VERSION2 select_project=${select_project} jkworkspace=${jkworkspace} service_port=${service_port} web_port=${web_port} service_port2=${service_port2} web_port2=${web_port2} xms=${xms} xmx=${xmx}”

elif [ “$select_project” == “web” ] && [ “$now_port” == “$web_port2” ] ; then
echo “step4:项目为前端web,目前使用$now_port 现在开始替换NGINX配置文件,使用$web_port 端口”
###替换版本号####
ssh root@$Server_ip1 “sed -i ‘/$prodName-runver/{n;s/$run_version/$brancheVersion/;}’ $nginx_dir/nginx.conf”
echo “替换$prodName-runver 下的$run_version 为$brancheVersion”
ssh root@$Server_ip1 “sed -i ‘/$prodName-oldver/{n;s/$old_version/$run_version/;}’ $nginx_dir/nginx.conf”
echo “替换$prodName-oldver 下的$old_version 为 $run_version”
#ssh root@$Server_ip1 “sed -i ‘/$prodName-update-info/{n;s/$old_version/$run_version/;}’ $nginx_dir/nginx.conf”
#echo “替换通知更新$prodName-update-info下的$old_version 为 $run_version”

###替换IP及端口##
ssh root@$Server_ip1 “sed -i s/$run_ip_port/$ip_a1:$web_port/g $nginx_dir/nginx.conf”
echo “替换$run_ip_port 为 $ip_a1:$web_port2”
ssh root@$Server_ip1 “sed -i s/$old_ip_port/$run_ip_port/g $nginx_dir/nginx.conf”
echo “替换$old_ip_port 为$run_ip_port”

###执行ANSBILE-PALYBOOK 2
echo “step5:开始使用ansibl-playbook部署启动”
cd /etc/ansible
ansible-playbook prod_fix_lsmc_web2_1.yml –extra-vars “prodName=${prodName} brancheVersion=${brancheVersion} old_ver=$VERSION run_ver=$VERSION2 select_project=${select_project} jkworkspace=${jkworkspace} service_port=${service_port} web_port=${web_port} service_port2=${service_port2} web_port2=${web_port2} xms=${xms} xmx=${xmx}”

elif [ “$select_project” == “service” ] && [ “$now_port” == “$service_port” ] ; then
echo “step4:项目为后端service,目前使用$now_port 现在开始启动新版后端服务,使用$service_port2端口”
###执行ANSBILE-PALYBOOK 3
echo “step5:开始使用ansibl-playbook部署启动”
cd /etc/ansible
ansible-playbook prod_fix_lsmc_service1_1.yml –extra-vars “prodName=${prodName} brancheVersion=${brancheVersion} old_ver=$VERSION run_ver=$VERSION2 select_project=${select_project} jkworkspace=${jkworkspace} service_port=${service_port} web_port=${web_port} service_port2=${service_port2} web_port2=${web_port2} xms=${xms} xmx=${xmx}”

elif [ “$select_project” == “service” ] && [ “$now_port” == “$service_port2” ] ; then
echo “step4:项目为后端service,目前使用$now_port 现在开始启动新版后端服务,使用$service_port端口”
###执行ANSBILE-PALYBOOK 4
echo “step5:开始使用ansibl-playbook部署启动”
cd /etc/ansible
ansible-playbook prod_fix_lsmc_service2_1.yml –extra-vars “prodName=${prodName} brancheVersion=${brancheVersion} old_ver=$VERSION run_ver=$VERSION2 select_project=${select_project} jkworkspace=${jkworkspace} service_port=${service_port} web_port=${web_port} service_port2=${service_port2} web_port2=${web_port2} xms=${xms} xmx=${xmx}”
else
echo “step4:不存在端口及服务的匹配项目,脚本将自动退出”
fi
#########################################
}
#####################################################################################################################
function Server_2 {
#############服务判断#####################
old_version=$VERSION2
run_version=$VERSION
run_ip_port=$(ssh root@$Server_ip1 “cat $nginx_dir/nginx.conf|grep -A 1 $prodName-runip|grep -v $prodName-runip|awk -F ‘[/]’ ‘{print \$3}'”)
old_ip_port=$(ssh root@$Server_ip1 “cat $nginx_dir/nginx.conf|grep -A 1 $prodName-oldip|grep -v $prodName-oldip|awk -F ‘[/]’ ‘{print \$3}'”)

if [ “$select_project” == “web” ];then
echo “step2:项目为前端web”
now_port=$(ssh root@$Server_ip2 “ps -aux |grep $prodName-$select_project|grep port|grep -v grep|awk -F [=] ‘{print \$2}’|awk ‘{print \$1}'”)
elif [ “$select_project” == “service” ];then
echo “step2:项目为后端service”
now_port=$(ssh root@$Server_ip2 “ps -aux |grep $prodName-$select_project|grep port|grep -v grep|awk -F [=] ‘{print \$3}’|awk ‘{print \$1}'”)
else
echo “step2:目标机器不存在启动端口,可能存在手工启动的情况,请登陆服务器检查”
exit 0
fi
#######端口异常的判断##################
w_port=$(ssh root@$Server_ip2 “ps -aux |grep $prodName-$select_project|grep port|grep -v grep|grep -v lsmc-oss|wc -l”)
if [ $w_port -eq 0 ] ; then
echo “step3:线上不存在启动的端口,可能存在人工启动或服务停止的情况,请登陆服务器检查”
exit 0
elif [ $w_port -gt 2 ] ; then
echo “step3:存在两个同样的端口,可能存在人工启动的情况,请登陆服务器检查”
exit 0
else
echo “step3:端口检测正常现在将进行下一步”
fi
############替换NGINX配置文件#############
if [ “$select_project” == “web” ] && [ “$now_port” == “$web_port” ] ;then
echo “step4:项目为前端web,目前使用$now_port 现在开始替换NGINX配置文件,使用$web_port2 端口 ”
###替换版本号####
ssh root@$Server_ip1 “sed -i ‘/$prodName-runver/{n;s/$run_version/$brancheVersion/;}’ $nginx_dir/nginx.conf”
echo “替换$prodName-runver 下的$run_version 为$brancheVersion”
ssh root@$Server_ip1 “sed -i ‘/$prodName-oldver/{n;s/$old_version/$run_version/;}’ $nginx_dir/nginx.conf”
echo “替换$prodName-oldver 下的$old_version 为 $run_version”
#ssh root@$Server_ip1 “sed -i ‘/$prodName-update-info/{n;s/$old_version/$run_version/;}’ $nginx_dir/nginx.conf”
#echo “替换通知更新$prodName-update-info下的$old_version 为 $run_version”
###替换IP及端口##
ssh root@$Server_ip1 “sed -i s/$run_ip_port/$ip_a2:$web_port2/g $nginx_dir/nginx.conf”
echo “替换$run_ip_port 为 $ip_a2:$web_port2”
ssh root@$Server_ip1 “sed -i s/$old_ip_port/$run_ip_port/g $nginx_dir/nginx.conf”
echo “替换$old_ip_port 为$run_ip_port”

###执行ANSBILE-PALYBOOK 1
echo “step5:开始使用ansibl-playbook部署启动”
cd /etc/ansible
ansible-playbook prod_fix_lsmc_web1_2.yml –extra-vars “prodName=${prodName} brancheVersion=${brancheVersion} old_ver=$VERSION run_ver=$VERSION2 select_project=${select_project} jkworkspace=${jkworkspace} service_port=${service_port} web_port=${web_port} service_port2=${service_port2} web_port2=${web_port2} xms=${xms} xmx=${xmx}”

elif [ “$select_project” == “web” ] && [ “$now_port” == “$web_port2” ] ; then
echo “step4:项目为前端web,目前使用$now_port 现在开始替换NGINX配置文件。使用$web_port 端口”
###替换版本号####
ssh root@$Server_ip1 “sed -i ‘/$prodName-runver/{n;s/$run_version/$brancheVersion/;}’ $nginx_dir/nginx.conf”
echo “替换$prodName-runver 下的$run_version 为$brancheVersion”
ssh root@$Server_ip1 “sed -i ‘/$prodName-oldver/{n;s/$old_version/$run_version/;}’ $nginx_dir/nginx.conf”
echo “替换$prodName-oldver 下的$old_version 为 $run_version”
#ssh root@$Server_ip1 “sed -i ‘/$prodName-update-info/{n;s/$old_version/$run_version/;}’ $nginx_dir/nginx.conf”
#echo “替换通知更新$prodName-update-info下的$old_version 为 $run_version”
###替换IP及端口##
ssh root@$Server_ip1 “sed -i s/$run_ip_port/$ip_a2:$web_port/g $nginx_dir/nginx.conf”
echo “替换$run_ip_port 为 $ip_a2:$web_port2”
ssh root@$Server_ip1 “sed -i s/$old_ip_port/$run_ip_port/g $nginx_dir/nginx.conf”
echo “替换$old_ip_port 为$run_ip_port”

###ANSBILE-PALYBOOK 2
echo “step5:开始使用ansibl-playbook部署启动”
cd /etc/ansible
ansible-playbook prod_fix_lsmc_web2_2.yml –extra-vars “prodName=${prodName} brancheVersion=${brancheVersion} old_ver=$VERSION run_ver=$VERSION2 select_project=${select_project} jkworkspace=${jkworkspace} service_port=${service_port} web_port=${web_port} service_port2=${service_port2} web_port2=${web_port2} xms=${xms} xmx=${xmx}”

elif [ “$select_project” == “service” ] && [ “$now_port” == “$service_port” ] ; then
echo “step4:项目为后端service,目前使用$now_port 现在开始启动新版后端服务,使用$service_port2端口”
###ANSBILE-PALYBOOK 3
echo “step5:开始使用ansibl-playbook部署启动”
cd /etc/ansible
ansible-playbook prod_fix_lsmc_service1_2.yml –extra-vars “prodName=${prodName} brancheVersion=${brancheVersion} old_ver=$VERSION run_ver=$VERSION2 select_project=${select_project} jkworkspace=${jkworkspace} service_port=${service_port} web_port=${web_port} service_port2=${service_port2} web_port2=${web_port2} xms=${xms} xmx=${xmx}”

elif [ “$select_project” == “service” ] && [ “$now_port” == “$service_port2” ] ; then
echo “step4:项目为后端service,目前使用$now_port 现在开始启动新版后端服务,使用$service_port端口”
###ANSBILE-PALYBOOK 4
echo “step5:开始使用ansibl-playbook部署启动”
cd /etc/ansible
ansible-playbook prod_fix_lsmc_service2_2.yml –extra-vars “prodName=${prodName} brancheVersion=${brancheVersion} old_ver=$VERSION run_ver=$VERSION2 select_project=${select_project} jkworkspace=${jkworkspace} service_port=${service_port} web_port=${web_port} service_port2=${service_port2} web_port2=${web_port2} xms=${xms} xmx=${xmx}”

#########################################
else
echo “step4:不存在端口及服务的匹配项目,脚本将自动退出”
fi
}
#########################################
function Server_1_no {
if [ “$select_project” == “web” ];then
echo “step2:项目为前端web”
cd /etc/ansible
ansible-playbook prod_lsmc_web1_def.yml –extra-vars “prodName=${prodName} brancheVersion=${brancheVersion} old_ver=$VERSION run_ver=$VERSION2 select_project=${select_project} jkworkspace=${jkworkspace} service_port=${service_port} web_port=${web_port} service_port2=${service_port2} web_port2=${web_port2}”

elif [ “$select_project” == “service” ];then
echo “step2:项目为后端service”
cd /etc/ansible
ansible-playbook prod_lsmc_service1_def.yml –extra-vars “prodName=${prodName} brancheVersion=${brancheVersion} old_ver=$VERSION run_ver=$VERSION2 select_project=${select_project} jkworkspace=${jkworkspace} service_port=${service_port} web_port=${web_port} service_port2=${service_port2} web_port2=${web_port2}”

else
echo “发送的服务或目标服务器存在不匹配的情况,请检查”
exit 0
fi
}
#########################################################
function Server_2_no {
if [ “$select_project” == “web” ];then
echo “step2:项目为前端web”
cd /etc/ansible
ansible-playbook prod_lsmc_web2_def.yml –extra-vars “prodName=${prodName} brancheVersion=${brancheVersion} old_ver=$VERSION run_ver=$VERSION2 select_project=${select_project} jkworkspace=${jkworkspace} service_port=${service_port} web_port=${web_port} service_port2=${service_port2} web_port2=${web_port2}”

elif [ “$select_project” == “service” ];then
echo “step2:项目为后端service”
cd /etc/ansible
ansible-playbook prod_lsmc_service2_def.yml –extra-vars “prodName=${prodName} brancheVersion=${brancheVersion} old_ver=$VERSION run_ver=$VERSION2 select_project=${select_project} jkworkspace=${jkworkspace} service_port=${service_port} web_port=${web_port} service_port2=${service_port2} web_port2=${web_port2}”

else
echo “发送的服务或目标服务器存在不匹配的情况,请检查”
exit 0
fi
}

#####判断是否为新版本上线####################################################################
if [ $VERSION == $brancheVersion ]; then
echo “$VERSION eq $brancheVersion”
echo “step1:发现要升级的版本和172.31.100.171上的版本一样,这不是正常升级操作,如果是修复本版本BUG请使用BUG修复脚本,现在程序将退出。”
exit 1

elif [ $VERSION2 == $brancheVersion ]; then
echo “$VERSION2 eq $brancheVersion”
echo “step1:发现要升级的版本和172.31.100.172上的版本一样,这不是正常升级操作,如果是修复本版本BUG请使用BUG修复脚本,现在程序将退出。”
exit 1

####################自动判断发布类型,根据不同情况进行相应的部署##############################
#1.初次上线新项目的情况
elif [ ! -n “$VERSION” ] && [ ! -n “$VERSION2” ]; then
echo “$VERSION $VERSION2 两台机器上都不存在要上线的版本,这应是本程序的首次发布,现在选择$Server_ip2 发布此版本”
#临时关闭目标机器上的CROND服务,避免LSMC-JAVA保活进程运行
ssh root@$Server_ip2 “service crond stop”
echo “******临时关闭目标机器上的crond服务,避免lsmc-java保活出现误操作******”
Server_2_no
ssh root@$Server_ip2 “service crond start”
echo “******重新开启目标机器的crond服务******”
echo “******温馨提示:请记得在Ngnix中添加对应配置项******”
############################################################################################
elif [ ! -n “$VERSION” ] && [ “$VERSION2″ != ” ” ] && [ “$VERSION2” != “$brancheVersion” ]; then
echo “$VERSION2 $Server_ip2 目标服务器中仅有该程序的一个版本,现在选择$Server_ip1 发布此版本”
#临时关闭目标机器上的CROND服务,避免LSMC-JAVA保活进程运行
ssh root@$Server_ip1 “service crond stop”
echo “******临时关闭目标机器上的crond服务,避免lsmc-java保活出现误操作******”
Server_1_no
ssh root@$Server_ip1 “service crond start”
echo “******重新开启目标机器的crond服务******”
echo “******温馨提示:请记得在Ngnix中添加对应配置项******”

############################################################################################
elif [ ! -n “$VERSION2” ] && [ “$VERSION” != ” ” ] && [ “$VERSION” != “$brancheVersion” ]; then
echo “$VERSION $Server_ip1 目标服务器中仅有该程序的一个版本,现在选择$Server_ip2 发布此版本”
#临时关闭目标机器上的CROND服务,避免LSMC-JAVA保活进程运行
ssh root@$Server_ip2 “service crond stop”
echo “******临时关闭目标机器上的crond服务,避免lsmc-java保活出现误操作******”
Server_2_no
ssh root@$Server_ip2 “service crond start”
echo “******重新开启目标机器的crond服务******”
echo “******温馨提示:请记得在Ngnix中添加对应配置项******”
############上线服务器选择判断####################################################
elif version1_lt $VERSION $VERSION2; then
echo “$VERSION is less than $VERSION2”
echo “step1:发现旧版本在$Server_ip1 上,版本为$VERSION 现在开始在此台机运行ansbile-playbook升级部署”
old_ver=$VERSION
cd /etc/ansible
#临时关闭目标机器上的CROND服务,避免LSMC-JAVA保活进程运行
ssh root@$Server_ip1 “service crond stop”
echo “******临时关闭目标机器上的crond服务,避免lsmc-java保活出现误操作******”
echo “备份nginx.conf配置文件”
ssh root@$Server_ip1 “cp -aRp /data/tengine-2.2.0/conf/nginx.conf /data/shell/file_bak/nginx.conf_${Date_now}”
Server_1
#执行完成后打开目标机器上的CROND服务
ssh root@$Server_ip1 “service crond start”
echo “******重新开启目标机器的crond服务******”

elif version2_lt $VERSION2 $VERSION; then
echo “$VERSION2 is less than $VERSION”
echo “step1:发现旧版本在$Server_ip2 上,版本为$VERSION2 现在开始在此台机运行ansbile-playbook升级部署”
old_ver=$VERSION2
cd /etc/ansible
#临时关闭目标机器上的CROND服务,避免LSMC-JAVA保活进程运行
ssh root@$Server_ip2 “service crond stop”
echo “******临时关闭目标机器上的crond服务,避免lsmc-java保活出现误操作******”
echo “备份nginx.conf配置文件”
ssh root@$Server_ip1 “cp -aRp /data/tengine-2.2.0/conf/nginx.conf /data/shell/file_bak/nginx.conf_${Date_now}”
Server_2
#执行完成后打开目标机器上的CROND服务
ssh root@$Server_ip2 “service crond start”
echo “******重新开启目标机器的crond服务******”

else
###如果选择比较不出版本,请检查是否存在错误#############
echo “step1:需要上线的机器上可能存在错误,1.如不存在2个版本 2.服务版本号异常 3.启动的进程里存在异常导致无法判断版本号。请登录目标服务器检查!!!”
fi
echo “========> 已成功完成 $prodName-$select_project 的升级部署”
################################################################################

最后修改日期:2020年9月8日

作者

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。