拓扑:

control_server

192.168.1.200

 

lb1

192.168.1.202

 

lamp1

192.168.1.101

 

lamp2

192.168.1.102

 

网站:

www.aaa.com

 

注意点:

1.所有服务器之间通过hosts来解析主机名

2.control_server与其他被管理主机基于密钥方式进行ssh通信

3.所有服务器的ssh端口号已改为2222

 

实验目的:

基于灰度发布模型,在control_server上使用shell脚本,自动向多台lamp服务器发布新版本的php应用

 

实现思路:

  1. 各服务器上的配置文件以及文件路径要保持一致

  2. 更新web应用时,使用软链接的方式来实现。如果新版本有严重BUG,方便回滚到旧版本

使用shell脚本实现php应用的批量更新_第1张图片

 

  1. Load Balance上的nginx配置要规范:

   不同的站点使用独立的配置文件

使用shell脚本实现php应用的批量更新_第2张图片

 

    配置upstream时可以自定义标记,方便正则表达式匹配

使用shell脚本实现php应用的批量更新_第3张图片

 

 

具体实现过程:

  1. 向lamp1传送项目包

  2. 修改所有Load Balance节点的nginx配置文件,标记lamp1服务器为down,使新的请求不会再发往lamp1,并重载nginx

  3. 脚本等待1分钟,让lamp1处理完已接收的请求

  4. 将网站目录的软连接指向新版本,并重载httpd

  5. 重新修改所有Load Balance节点的nginx配置文件,取消lamp1服务器的down标记,并重载nginx

  6. 以此类推,向其他lamp服务器更新web应用

  7. 脚本执行完毕后,列出执行过程中发生异常的lamp服务器列表,之后可以对这些服务器进行进一步的人工检查及更新

 

 

使用方法:

使用shell脚本实现php应用的批量更新_第4张图片

 

使用shell脚本实现php应用的批量更新_第5张图片

 

 

 

脚本:

#!/bin/bash
#
 
read -p "请输入项目包路径:" webappPath
#压缩项目文件,便于传输
webappName=`basename ${webappPath}`
webappPackage=/tmp/${webappName}.tar.gz
 
#web服务器存放网站的路径以及web服务的用户名,每个服务器的配置需要统一
remoteWebappPath=/data/webapps
remoteWebUser=apache
 
#相应网站的nginx配置文件路径
nginxConfPath=/etc/nginx/conf.d/www_aaa_com.conf
 
remoteSSHport=2222
 
tar -czf ${webappPackage} ${webappPath}&> /dev/null
[ $? -ne 0 ] && echo "tarwrong" && exit 1
 
#Load Balance服务器列表
lbServers=(lb1)
 
#Lamp服务器列表
lampServers=(lamp1 lamp2)
 
#更新过程中发生异常的服务器列表
declare -a failureServers
 
check()
{
   if [ $? -ne 0 ]; then
       failureServers[${#failureServers[@]}]=$1
       continue
   fi
}
 
for lampServer in ${lampServers[@]}; do
   scp -P ${remoteSSHport} ${webappPackage} ${lampServer}:/tmp &>/dev/null
   check ${lampServer}
 
   ssh -p ${remoteSSHport} ${lampServer} tar -xf /tmp/${webappName}.tar.gz-C /data/webapps
   check ${lampServer}
 
   ssh -p ${remoteSSHport} ${lampServer} chown -R${remoteWebUser}:${remoteWebUser} /data/webapps/${webappName}
   check ${lampServer}
   
   declare -i flag=0
   for lbServer in ${lbServers}; do
       ssh -p ${remoteSSHport} ${lbServer} "grep'[^[:space:]].*;.*#${lampServer}\>' $nginxConfPath &> /dev/null"
       check ${lampServer}
 
       ssh -p ${remoteSSHport} ${lbServer} "sed -i -r 's@([^[:space:]].*);(.*#'"${lampServer}"'\>)@\1 down;\2@'${nginxConfPath}"
       check ${lampServer}
          
       ssh -p ${remoteSSHport} ${lbServer} "nginx -s reload"
       check ${lampServer}
       
       let flag+=1
   done
   [ $flag -ne ${#lbServers[@]} ] && failureServers[${#failureServers[@]}]=${lampServer} && continue
   
   sleep 1m
   ssh -p ${remoteSSHport} ${lampServer} "rm -f/data/webapps/aaa"
   check ${lampServer}
 
   ssh -p ${remoteSSHport} ${lampServer} "ln -s/data/webapps/${webappName} /data/webapps/aaa"
   check ${lampServer}
 
   ssh -p ${remoteSSHport} ${lampServer} "service httpd reload&> /dev/null"    
   check ${lampServer}
 
   flag=0
   for lbServer in ${lbServers}; do
       ssh -p ${remoteSSHport} ${lbServer} "grep'[^[:space:]].*down;.*#${lampServer}\>' $nginxConfPath &>/dev/null"
       check ${lampServer}
 
       ssh -p ${remoteSSHport} ${lbServer} "sed -i -r 's@([^[:space:]].*)[[:space:]]down;(.*#'"${lampServer}"'\>)@\1;\2@'${nginxConfPath}"
       check ${lampServer}
          
       ssh -p ${remoteSSHport} ${lbServer} "nginx -s reload"
       check ${lampServer}
       
       let flag+=1
   done
   [ $flag -ne ${#lbServers[@]} ] && failureServers[${#failureServers[@]}]=${lampServer}
 
   ssh -p ${remoteSSHport} ${lampServer} "rm -f/tmp/${webappName}.tar.gz"
 
done
 
rm -f ${webappPackage}
echo "任务执行完成"
 
if [ ${#failureServers[@]} -gt 0 ]; then
   echo
   echo "下列服务器未能正常更新,请进一步检查:"
   for failureServer in ${failureServers[@]}; do
       echo ${failureServer}
   done
fi