草庐IT

svn全自动化更新

nginx2012 2023-03-28 原文
首先在这里我要说很多,

需求:

   1.我写任何脚本的核心要求就是必须得有一台跳板机,单方面认证即可

   2.需要一台服务器挂载前台所有web站点

   3.需要一个报警通知的接口

个人对自动的化上线的理解:

   1.执行上线脚本就可以高枕无忧,把脚本放到后台就可以了

   2.如何达到高枕无忧,svn自动化上线实现起来不简单

一.备份块

   楼主在备份这块现在还是比较犹豫,楼主有两个想法

   (1)不需要备份,可以利用-r+版本号回退到上一个版本,但是有弊端,比如测试经常会上错包,这个不能只靠着别人不犯错

   (2)每台web全路径备份,回滚会很快,但是有些没有必要,比如我这次上线,只上个jsp文件,我也要全备份吗,这样务必会影响效率


   楼主现在还是选择了第二个方案

二.上线块    

   (1)svn上线会有自己的弊端,比如手动更新线上的文件,下次再更新此包就会出现G的问题,代表此文件没有更新成功

    (2)svn上线如果之前版本库里没有此文件,而你又手动上了一个文件,在手动上线后,svn更新会报错

    (3)楼主的前台web,有23台之多,分为6个集群,每个集群的路径和进程名都不同,如何实现判断每次更新的群组

    (4)如此庞大的web集群,如何能够精简脚本的行数

三.检测块

    (1)自动化的精髓就是检测,无检测何来的自动化

    (2)检测前台集群所有web在上线过程中,500错是否正常

    (3)检测前台nginx日志,500错是否正常

    (4)检测svn上线是否文件都更新成功了,只针对上线文件比对md5码


下面贴上代码

第一部分上线篇

楼主有个公用函数脚本,这才是核心脚本

vim function.sh

#!/bin/bash
one=$1    
two=$2
three=/svnlog/$3
date=`date +%Y%m%d%H%M`
function youyuanjar(){
  echo "--------------------------resin restart--------------------------------"  2>&1 | tee -a /tmp/shangxianlog/svn.$one
  echo "---------------------------------$one------------------------------------"  2>&1 | tee -a /tmp/shangxianlog/svn.$one
  ssh $two "sh /usr/local/resin/bin/resin.sh stop -server youyuan" 2>&1 | tee -a /tmp/shangxianlog/svn.$one
  echo "$one stopped" 2>&1 | tee -a /tmp/shangxianlog/svn.$one
  sleep 3
  ssh $two "cp -rf /www/youyuan.com.1/htdocs /opt/$date"
  e=`cat  $three |grep -v Updated|awk -F "/" '{print $(NF-1)"/"$NF}'`
       for i in $e
       do
               ssh $two "rm -f /www/youyuan.com.1/$e"
               if [ "$?" -eq 0 ]; then
                       echo delet ok
               fi
       done
  ssh $two "svn up $svnversion /www/youyuan.com.1/htdocs" 2>&1 | tee -a /tmp/shangxianlog/svn.$one
  echo "$one svnup ok " 2>&1 | tee -a /tmp/shangxianlog/svn.$one
  sleep 15
  b=($(cat  $three |grep -v Updated|awk -F "/" '{print $NF}'|awk -F "." '{print $1}'))
  c=($(cat  $three |grep -v Updated|awk -F "/" '{print $(NF-1)"/"$NF}'))
       echo $c
       for ((d=0;d<${#c[@]};d++))
       do
               touch /home/shangxianlog/${b[$d]}
               a=`ssh $two "md5sum /www/youyuan.com.1/${c[$d]}"`
               echo $two $a >> /home/shangxianlog/${b[$d]}
       done
  ssh $two "sh /usr/local/resin/bin/resin.sh restart -server youyuan" 2>&1 | tee -a /tmp/shangxianlog/svn.$one
  sleep 20
  echo "$one restart " 2>&1 | tee -a /tmp/shangxianlog/svn.$one
}
function iosjar(){
  touch /tmp/shangxianlog/svni.$one
  echo "--------------------------resin restart--------------------------------"  2>&1 | tee -a /tmp/shangxianlog/svni.$one
  echo "---------------------------------$one------------------------------------"  2>&1 | tee -a /tmp/shangxianlog/svni.$one
  ssh $two "sh /usr/local/resin/bin/resin.sh stop -server ios" 2>&1 | tee -a /tmp/shangxianlog/svni.$one
  echo "$one stopped" 2>&1 | tee -a /tmp/shangxianlog/svni.$one
  sleep 3
  ssh $two "cp -rf /www/ios.youyuan.com/htdocs /opt/ios$three"
    c=`cat  $three |egrep '(ios|iosui|css|lib)'|grep -v Updated|awk -F "/" '{print $(NF-1)"/"$NF}'`
       echo $c
       for d in $c
       do
               ssh $two "rm -f /www/ios.youyuan.com/$d"
               if [ "$?" -eq 0 ]; then
                       echo delet ok
               fi
       done
  ssh $two "svn up $svnversion /www/ios.youyuan.com/htdocs/WEB-INF/lib" 2>&1 | tee -a /tmp/shangxianlog/svni.$one
  ssh $two "svn up $svnversion /www/ios.youyuan.com/htdocs/WEB-INF/ios" 2>&1 | tee -a /tmp/shangxianlog/svni.$one
  ssh $two "svn up $svnversion /www/ios.youyuan.com/htdocs/WEB-INF/iosui" 2>&1 | tee -a /tmp/shangxianlog/svni.$one
  ssh $two "svn up $svnversion /www/ios.youyuan.com/htdocs/css/" 2>&1 | tee -a /tmp/shangxianlog/svni.$one
  echo "$one svnup ok " 2>&1 | tee -a /tmp/shangxianlog/svni.$one
  ssh $two "sh /usr/local/resin/bin/resin.sh restart -server ios" 2>&1 | tee -a /tmp/shangxianlog/svni.$one
  sleep 20
  echo "$one restart " 2>&1 | tee -a /tmp/shangxianlog/svni.$one
}
function ios(){
  touch /tmp/shangxianlog/svni.$one
  echo "---------------------------------$oneios------------------------------------"  2>&1 | tee -a /tmp/shangxianlog/svni.$one
    ssh $two "cp -rf /www/ios.youyuan.com/htdocs /opt/ios$three"
    c=`cat  $three |egrep '(ios|iosui|css)'|grep -v Updated|awk -F "/" '{print $(NF-1)"/"$NF}'`
       echo $c
       for d in $c
       do
               ssh $two "rm -f /www/ios.youyuan.com/$d"
               if [ "$?" -eq 0 ]; then
                       echo delet ok
               fi
       done
  ssh $two "svn up $svnversion /www/ios.youyuan.com/htdocs/WEB-INF/ios" 2>&1 | tee -a /tmp/shangxianlog/svni.$one
  ssh $two "svn up $svnversion /www/ios.youyuan.com/htdocs/WEB-INF/iosui" 2>&1 | tee -a /tmp/shangxianlog/svni.$one
  ssh $two "svn up $svnversion /www/ios.youyuan.com/htdocs/css/" 2>&1 | tee -a /tmp/shangxianlog/svni.$one
  sleep 3
 echo "53ios svnupok" 2>&1 | tee -a /tmp/shangxianlog/svni.$one
}
function youyuan(){
 echo "---------------------------------$one------------------------------------"  2>&1 | tee -a /tmp/shangxianlog/svn.$one
#1.备份
 ssh $two "cp -rf /www/youyuan.com.1/htdocs /opt/"
#2.上线之前先把本次需要上线的文件全部删除,为的就是彻底避免svn上线存在的一些问题
  e=`cat  $three |grep -v Updated|awk -F "/" '{print $(NF-1)"/"$NF}'`
       for i in $e
       do
               ssh $two "rm -f /www/youyuan.com.1/$e"
               if [ "$?" -eq 0 ]; then
                       echo delet ok
               fi
       done
#3.版本更新
  ssh $two "svn up $svnversion /www/youyuan.com.1/htdocs" 2>&1 | tee -a /tmp/shangxianlog/svn.$one
  echo "$one svnup ok " 2>&1 | tee -a /tmp/shangxianlog/svn.$one
  sleep 15
#4.没更新一个文件,都会和跳板机的正确文件版本号进行md5码比对
       a=($(cat /svnlog/$filename|grep -v Updated|awk '{print $2}'|awk -F "/" '{print $3"/"$4}'))
       h=($(cat  /svnlog/$filename |grep -v Updated|awk -F "/" '{print $NF}'|awk -F "." '{print $1}'))
  for ((z=0;z<${a[@]};z++))
  do
       b=`ssh $two "md5sum /www/youyuan.com.1/${a[$z]}"|awk '{print $NF}'`
       grep -w $b /home/shangxianlog/${h[$z]}
       if [ "$?" -eq 0 ]; then
               echo good
       else
               sh /www/shell/syslog_2.sh $two-/www/youyuan.com.1/${a[$z]}-uploaderror `hostname` 1 2 1 6
               ssh $two "rm -f /www/youyuan.com.1/${a[$z]}"
               ssh $two "svn up /www/youyuan.com.1/htdocs"
       fi
  done
#   o=`cat /tmp/shangxianlog/svn.$one|grep "G"|wc -l`
#   if [ "$o" -gt 0 ]; then
#        b=`cat /tmp/shangxianlog/svn.$one|awk '/G/{print $NF}'`
#        #c=`cat /svnlog/$a|egrep -o "(([0-9]{3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}||G))"|grep -B1 G|sed -n '1'p`
#        #c=`cat /svnlog/$a|egrep -o "((192.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}||G))"|grep -B1 G|grep "192"`
#        e=`date +%H%M%S`
#        for i in $b
#        do
#                ssh  $two "cp -f $i /tmp/$e"
#                if [ "$?" == 0 ]; then
#                        echo ok
#                        ssh  $two "rm -f $i"
#                        if [ "$?" == 0 ]; then
#                                echo ok
#                                ssh  $two "svn up /www/youyuan.com.1/htdocs"| tee -a /tmp/$e
#                        fi
#                fi
#        done
#   fi
 sleep 3
 echo "$one svnupok" 2>&1 | tee -a /tmp/shangxianlog/svn.$one
}

如何调用函数

分为4个调用函数脚本

iosjar.sh

#!/bin/bash
source /opt/shangxian/function.sh
iosjar


ios.sh

#!/bin/bash
source /opt/shangxian/function.sh
ios


youyuanjar.sh

#!/bin/bash
source /opt/shangxian/function.sh
youyuanjar


youyuan.sh

#!/bin/bash
source /opt/shangxian/function.sh
youyuan


svn上线脚本

svn.sh

#!/bin/bash
source /opt/shangxian/function.sh
youyuanjar
[root@02 shangxian]# cat youyuan.sh
#!/bin/bash
source /opt/shangxian/function.sh
youyuan
[root@02 shangxian]# cat svn.sh
#!/bin/bash
###创建日志###
filename=`date '+%Y%m%d_%H%M%S.svnup.log'`
svnversion=''
touch /svnlog/$filename
#ip=`cat /tmp/ip.txt|awk -F "." '{print $NF}'`
#for i in $ip
#do
#touch /tmp/shangxianlog/svn.$i
#done

a=($(cat /opt/shangxian/shangxiantest.txt|awk '{print $2}'))
b=($(awk '$2~/youyuan/{print $1}' /opt/shangxian/shangxiantest.txt))
d=($(awk '$2~/ios/{print $1}' /opt/shangxian/shangxiantest.txt))
c=($(awk '$2~/youyuan/{print $1}' /opt/shangxian/shangxiantest.txt|awk -F "." '{print $NF}'))
e=($(awk '$2~/ios/{print $1}' /opt/shangxian/shangxiantest.txt|awk -F "." '{print $NF}'))

#在跳板机上先把需要上线的文件写入日志中,以便后面进行判断
/usr/bin/svn up $svnversion /svnsignal/htdocs 2>&1 | tee -a /svnlog/$filename

#记录本次上线正确文件的md5码,以便让所有前台服务器对比本次上线是否更新成功
f=($(cat /svnlog/$filename|grep -v Updated|awk '{print $2}'|awk -F "/" '{print $3"/"$4}'))
g=($(cat  /svnlog/$filename |grep -v Updated|awk -F "/" '{print $NF}'|awk -F "." '{print $1}'))
for ((z=0;z<${#a[@]};z++))
do
       svn up /www/youyuan.com.1/${a[$z]}
       touch /home/shangxianlog/${h[$z]}
       md5sum /www/youyuan.com.1/${a[$z]} >> /home/shangxianlog/${h[$z]}
done

###判断是否重启###
restartsignal=`cat /svnlog/$filename | awk '/.jar$|.conf$|classes|lib/' | wc -l`
if [ $restartsignal -gt 0 ]
then
#根据/opt/shangxian/shangxiantest.txt这个文件的第二列来判断运用那些函数,并把参数传入函数中,因为我们这里不同的站点都放在一个svn更新脚本中
       for (( i=0;i<${#i[@]};i++ ))
       do
               if [ "${a[i]}" == youyuan ]; then
                       sh /opt/shangxian/youyuanjar.sh ${c[i]} ${b[i]} $filename
               else
                       sh /opt/shangxian/iosjar.sh ${e[$i]} ${d[$]} $filename
               fi
       sleep 5
       done
else
       for (( i=0;i<${#i[@]};i++ ))
       do
               if [ "${a[i]}" == youyuan ]; then
                       sh /opt/shangxian/youyuan.sh ${c[i]} ${b[i]} $filename
               else
                       sh /opt/shangxian/ios.sh ${e[$i]} ${d[$]} $filename
               fi
       sleep 5
       done
fi
#h=`cat  /svnlog/$filename |grep -v Updated|awk -F "/" '{print $NF}'|awk -F "." '{print $1}'`
#       k=`awk '!a[$2$3]++' /home/shangxianlog/$h|wc -l`
#       if [ $k -gt 1 ]; then
#               i=`awk '!a[$2$3]++' /home/shangxianlog/$g|awk 'END{print}'|awk '{print $1}'`
#               j=`awk '!a[$2$3]++' /home/shangxianlog/$g|awk 'END{print}'|awk '{print $NF}'`
#               y=`awk '!a[$2$3]++' /home/shangxianlog/$g|awk 'END{print}'|awk -F "/" '{print $1"/"$2"/"$3"/"$4"/"}'`
#               ssh $i "rm -f $j && svn up $y"
#               if [ "$?" -eq 0 ]; then
##                      echo ok
#               fi
#       fi


二.检测篇

检测nginx500错

#!/bin/bash
a=($(tail -n20000  /usr/local/nginx/logs/access.log  | grep "\" 500 " |awk '{++a[$(NF-2)]}END{for ( i in a )print i,a[i]}'|sort -k2 -rn|head -n10|awk '{print $1}'))
b=($(tail -n20000  /usr/local/nginx/logs/access.log  | grep "\" 500 " |awk '{++a[$(NF-2)]}END{for ( i in a )print i,a[i]}'|sort -k2 -rn|head -n10|awk '{print $2}'))
for ((i=0;i<${#a[@]};i++ ))
do
if [ "${b[i]}" -gt 20 ]; then
#       ssh ${b[i]} "/usr/local/resin/bin/resin.sh restart -server youyuan"
       sh /www/shell/syslog_2.sh nginx500error-must-${a[i]}- ${b[i]} 1 2 1 6
fi
done


检测resin500错

#!/bin/bash
time=`date +%Y-%m-%d" "%H`

for  station in   23  41  42  43  44  51  53  123 132 130 131 128 211 126 127 138 139 56
do

  for line in `find /logs/youyuan.com.?/$station -name root-error.log`
    do
       echo $station
       count=`cat $line | grep "$time" | egrep  '(500error|500错误)' |wc -l`
       echo $count
       a=`awk 'END{print}' /home/$station/500error.txt`
       echo $a
       countjia=`echo "scale=0;$count-$a"|bc`
       if [ "$countjia" -gt 20 ]; then
               sh /www/shell/syslog_2.sh 192.168.0.$line-resin-500erroradd-$countjia `hostname` 1 2 1 6
       fi
       cat $line | grep "$time" | egrep  '(500error|500错误)' |wc -l>>/home/$station/500error.txt
    done
done




有关svn全自动化更新的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  3. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  4. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  5. ruby-on-rails - 从应用程序中自定义文件夹内的命名空间自动加载 - 2

    我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty

  6. objective-c - 在设置 Cocoa Pods 和安装 Ruby 更新时出错 - 2

    我正在尝试为我的iOS应用程序设置cocoapods但是当我执行命令时:sudogemupdate--system我收到错误消息:当前已安装最新版本。中止。当我进入cocoapods的下一步时:sudogeminstallcocoapods我在MacOS10.8.5上遇到错误:ERROR:Errorinstallingcocoapods:cocoapods-trunkrequiresRubyversion>=2.0.0.我在MacOS10.9.4上尝试了同样的操作,但出现错误:ERROR:Couldnotfindavalidgem'cocoapods'(>=0),hereiswhy:U

  7. ruby-on-rails - 有没有一种工具可以在编码时自动保存对文件的增量更改? - 2

    我最喜欢的Google文档功能之一是它会在我工作时不断自动保存我的文档版本。这意味着即使我在进行关键更改之前忘记在某个点进行保存,也很有可能会自动创建一个保存点。至少,我可以将文档恢复到错误更改之前的状态,并从该点继续工作。对于在MacOS(或UNIX)上运行的Ruby编码器,是否有具有等效功能的工具?例如,一个工具会每隔几分钟自动将Gitcheckin我的本地存储库以获取我正在处理的文件。也许我有点偏执,但这点小保险可以让我在日常工作中安心。 最佳答案 虚拟机有些人可能讨厌我对此的回应,但我在编码时经常使用VIM,它具有自动保存功

  8. ruby-on-rails - Rails Associations 的更新方法是什么? - 2

    这太简单了,太荒谬了,我在任何地方都找不到关于它的任何信息,包括API文档和Rails源代码:我有一个:belongs_to关联,我开始理解当您没有关联时您在Controller中调用的正常模型方法与您有关联时调用的方法略有不同。例如,我的关联在创建Controller操作时运行良好:@user=current_user@building=Building.new(params[:building])respond_todo|format|if@user.buildings.create(params[:building])#etcetera但我找不到关于更新如何工作的文档:@user

  9. ruby - 在 ruby​​ 中使用自动创建插入数组 - 2

    我想知道是否可以通过自动创建数组来插入数组,如果数组不存在的话,就像在PHP中一样:$toto[]='titi';如果尚未定义$toto,它将创建数组并将“titi”压入。如果已经存在,它只会推送。在Ruby中我必须这样做:toto||=[]toto.push('titi')可以一行完成吗?因为如果我有一个循环,它会测试“||=”,除了第一次:Person.all.eachdo|person|toto||=[]#with1billionofperson,thislineisuseless999999999times...toto.push(person.name)你有更好的解决方案吗?

  10. ruby-on-rails - OSX Yosemite 更新破坏了 pow.cx - 2

    升级到OSXYosemite后,我现有的pow.cx安装不起作用。升级到最新的pow.cx无效。通过事件监视器重新启动它也没有成功。 最佳答案 卸载(!)并重新安装解决了这个问题。curlget.pow.cx/uninstall.sh|shcurlget.pow.cx|sh 关于ruby-on-rails-OSXYosemite更新破坏了pow.cx,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/q

随机推荐