腳本實現功能,從本地上傳war包到指定服務器的指定目錄,中止對應tomcat進程,替換上個版本的war包並進行備份(以防線上問題出現意外能夠進行回滾)。java
第一個腳本主要是上傳war包到指定服務器的指定目錄,shell腳本參考以下,在本地或者發佈機器上運行:python
#/bin/bash set -e cur_date=`date +'%Y%m%d %H:%M:%S'` current_day=`date +"%Y%m%d"` read -p "1.部署生產環境 2.測試環境 " nu echo $nu if [ ${nu} -eq 1 ] then read -p "請選擇部署服務器ip: 1. nginx-server 2. app-server 3. app-pay 4. pay-server 5. redis1 6. redis2 " nu1 case ${nu1} in 1) ip_addr=IP1 ;; 2) ip_addr=IP2 ;; 3) ip_addr=IP3 ;; 4) ip_addr=IP4 ;; 5) ip_addr=IP5 ;; 6) ip_addr=IP6 ;; *) echo -e "請輸入1~4的數字\n" exit 1 ;; esac elif [ ${nu} -eq 2 ] then read -p "請選擇部署服務器ip 1. IP7 2. IP8 " nu2 case ${nu2} in 1) ip_addr=IP7 ;; 2) ip_addr=IP8 ;; *) echo -e "請輸入1~2的數字\n" exit 1 ;; esac else echo -e "請選擇正確的部署環境\n" exit 1 fi read -p "請輸入部署服務器上傳目錄:" dir read -p "請輸入部署war包名稱:" war_name S_PATH=`pwd` echo "********** "$cur_date" *******" sleep 1 echo "******** 開始上傳war包 *******" ssh root@${ip_addr} "mkdir -p /${dir}/${current_day}" read -p "是否已經上傳過war包:1,是 2,否 " nu3 if [ $nu3 -eq 2 ] then scp ./${war_name}.war root@${ip_addr}:/${dir}/${current_day} else echo -e "跳過上傳,繼續進行部署" fi scp ./deploy_finance.sh root@${ip_addr}:/${dir}/${current_day} echo -e "********開始進行部署***********" ssh -t root@${ip_addr} "sh ${dir}/${current_day}/deploy.sh $dir $war_name"
第二個腳本即上個腳本中提到的deploy.sh腳本,主要用來中止對應tomcat進程,替換上個版本的war包並進行備份,運行在tomcat應用服務器上nginx
#/bin/bash set -e #*******設置系統臨時環境變量******** read -p "是否須要設置環境變量,請根據部署環境選擇 1.生產環境不須要 2.測試環境須要 " nu if [ ${nu} -eq 2 ] then echo -e "*****設置系統臨時環境變量******" export JAVA_HOME=/usr/local/java/jdk1.7.0_79 export PATH=$PATH:$JAVA_HOME else echo -e "跳過變量設置,繼續部署" fi #*******部署服務******* #********************* #*******中止服務******** function deploy_war { file_war=$1 echo -e "*****INFO: 中止服務*******" _PID=`ps -ef|grep -w "${deploy_dir}"|grep -v grep|awk '{print $2}'` if [ 8${_PID} -eq 8 ] then echo -e "進程不在運行,直接部署\n" else echo -e "${_PID}" cd ${deploy_dir} kill -9 ${_PID} sleep 3 _PID=`ps -ef|grep -w "${deploy_dir}"|grep -v grep|awk '{print $2}'` if [ 8${_PID} -ne 8 ];then echo -e "*********${file_war}進程中止失敗,請檢查日誌,部署腳本退出********" exit 1 else echo -e "********${file_war}進程已中止*********" fi fi #*********刪除文件目錄,備份war包********* if [ -d "${deploy_dir}/webapps" ]; then cd ${deploy_dir}/webapps echo -e "*********INFO: 切換目錄成功" rm -rf ./${file_war} if [ $? -ne 0 ];then echo -e "*********${file_war}目錄刪除失敗,退出部署************" exit 1 else echo -e "**********${file_war}目錄刪除成功,繼續部署***********" fi tar -zcvf ${file_war}${current_day}.war.tar.gz ${file_war}.war if [ $? -ne 0 ];then echo -e "************備份失敗,退出部署************" exit 1 else echo -e "***********備份成功,繼續部署*************" fi cp -a /$dir/${current_day}/${file_war}.war /${deploy_dir}/webapps if [ $? -eq 0 ];then echo -e "******************war包拷貝成功***********" else echo -e "******************war包拷貝失敗,退出部署***************" exit 1 fi else echo -e "************webapps目錄不存在,請建立tomcat目錄,退出部署******\n" exit 1 fi #********** 重啓應用 *********** echo -e "*********INFO:啓動服務***********\n" cd ${deploy_dir} rm -rf work rm -rf temp/* cd ${deploy_dir}/bin setsid ./startup.sh _PID1=`ps -ef|grep -w "${deploy_dir}"|grep -v grep|awk '{print $2}'` sleep 8 if [ 8$[_PID1] -eq 8 ];then echo -e "************** ERROR:${file_war}啓動失敗,請檢查啓動日誌***********\n" exit 1 else echo "**********${file_war}啓動完畢" fi } dir=$1 war_name=$2 current_day=`date +"%Y%m%d"` if [ -d "${dir}/${current_day}" ]; then echo -e "**********INFO: ${current_day}目錄已經存在,請忽略。\n" else mkdir -p ${dir}/${current_day} fi if [ $# -ne 2 ];then echo -e "******執行部署腳本時須要傳入安裝包存放目錄********\n" echo -e "******即將退出部署\n" echo -e "******腳本執行方式,例如: ./deploy_finance.sh /mnt app " exit 1 fi read -p "*********請選擇部署目錄: 1. dir1 2. dir2 3. dir3 4. dir4 5. dir5 6. dir6 7. dir7 8. dir8 " nu_dir case ${nu_dir} in 1) deploy_dir=dir1 ;; 2) deploy_dir=dir2 ;; 3) deploy_dir=dir3 ;; 4) deploy_dir=dir4 ;; 5) deploy_dir=dir5 ;; 6) deploy_dir=dir6 ;; 7) deploy_dir=dir7 ;; 8) deploy_dir=dir8 ;; *) echo -e "請選擇正確的部署目錄,即將退出部署/n" exit 1 esac deploy_war ${war_name}
這裏記錄踩下的兩個坑:web
1.最初腳本寫完以後是在測試環境下運行的,測試環境的JAVA目錄並無作軟鏈接到/usr/bin下,只要運行部署腳本,tomcat都會由於找不到java_home的路徑而報錯,可是ssh到服務器上是可以正常啓動的,看了一下/etc/profile文件的內容,以前的兄弟是把java環境變量放在這個文件作導入的,那麼爲何ssh到服務器上去到tomcat/bin目錄下執行./startup.sh能正常啓動呢,./startup.sh是繼承當前shell環境變量的,當你ssh 到服務器的時候,屬於login shell,會去讀取/etc/profile中的文件內容,天然會加載java的環境變量,而在遠程腳本中執行./startup.sh,此時啓動的shell子進程會繼承父進程deploy.sh的環境變量,而這對父子進程都是屬於no login shell,不會去讀取/etc/profile的內容,可是它會去讀取~/.bashrc中的內容,後來我去這個文件中設置java環境變量以後確實啓動正常了。redis
2.第二個坑是最初在deploy.sh腳本中啓動tomcat的時候,直接用的是./startup.sh,致使的結果就是每次發佈的時候,本地從服務器上分配的僞終端顯示tomcat進程啓動成功,可是登陸服務器進行檢查的時候發現對應的tomcat根本沒有啓動成功。後來想了半天,原來是由於這種方式啓動的tomcat進程是屬於對應的sshd的子進程,當腳本運行完畢以後,對應的sshd進程結束以後,服務器收到singalhup,也會把其進程樹下的子進程停掉。解決的方式就是用nohup或者setsid去啓動tomcat,相應的命令解釋有需求的同窗能夠谷歌一哈。shell
後續展望:tomcat
1.看可否用jenkins縮短髮布時間,可是由於用的是阿里金融雲且svn服務器是在公司本地的一臺物理機上,且金融雲環境和公司網絡沒法進行通信(安全第一),用jenkins作持續集成和發佈難以作到安全
2.總以爲shell語法不人性化,後面增強一下python學習,看可否用python徹底代替掉shellbash
3.不知道你們有沒有相關工具推薦一下,主要解決的痛點是要去特定的服務器上替換特定的文件服務器
*******************************************
作爲一個運維新手且木有人帶,真是壓力山大,記得以前有個前輩說過寫出來的東西纔是本身的,特此感謝博客園批准俺開通了微博來記錄本身的學習經歷和成長過程,上述文章若是有錯誤的地方或者童鞋們有更好的想法歡迎你們指出,也能夠加我微信你們一塊兒交流