背景
因爲項目中有多個模塊,每個模塊需要打包成一個jar運行。每次更新到服務器比較麻煩,所以就想到利用腳本一鍵實現代碼的更新、編譯打包、備份、和啓動工作。項目中模塊除了一個是用gradle編譯,其他都是採用maven管理依賴。
腳本源碼
deploy.sh
#!/bin/bash
#//////////////////////////微服務啓動管理腳本//////////////////////////
#模塊列表,因爲maven和gradle構建的差異,爲了避免腳本出現過多if else判斷,所以兩部分分開。
#///////////////////////////Maven部分/////////////////////////////////
JarNames=(
discover-1.0-SNAPSHOT.jar
consumer-1.0-SNAPSHOT.jar
)
#--------------------------更新代碼----------------------------------
echo -e "\e[1;32m 開始更新代碼 \e[0m"
cd /home/boc/
git pull
echo -e "\e[1;32m 代碼更新完成 \e[0m"
#-------------------------循環對所有模塊進行編譯打包和啓動--------------
for JarName in ${JarNames[@]}
do
#查看進程ID
PID=$(ps aux | grep ${JarName} | grep -v 'grep' | awk '{print $2}')
#要將模塊名稱分割開,獲取到模塊名稱,同時也是目錄名稱。先存儲舊的分隔符
OLD_IFS="$IFS"
#設置分隔符
IFS="-"
#如下會自動分隔
arr=(${JarName})
# 將IFS恢復成原來的
IFS="$OLD_IFS"
#------------1.關閉已有進程----------------
if [[ ! -z ${PID} ]];then
echo -e "\e[1;32m ${arr[0]} 的進程ID是:$PID \e[0m"
echo -e "\e[1;32m 即將關閉${arr[0]} \e[0m"
kill -9 ${PID}
else
echo -e "\e[1;33m ${arr[0]} 沒有啓動 \e[0m"
fi
#------------2.編譯代碼--------------------
echo -e "\e[1;32m 開始編譯代碼 \e[0m"
cd /home/boc/${arr[0]}/
mvn clean package -Dmaven.test.skip=true
echo -e "\e[1;32m 編譯完成 \e[0m"
#------------3.移動備份jar包----------------
echo -e "\e[1;32m 開始備份舊jar包,備份位置在:/home/script/serverJAR/bak \e[0m"
cd /home/script/serverJAR
if [[ -e ${JarName} ]];then
mv ${JarName} /home/script/serverJAR/bak/ -f
rm -rf ${JarName}
echo -e "\e[1;32m JAR包備份完成 \e[0m"
else
echo -e "\e[1;37m JAR包不存在,直接下一步 \e[0m"
fi
#------------4.移動新jar包到執行目錄----------------
cd /home/boc/${arr[0]}/target
if [[ -e ${JarName} ]];then
mv ${JarName} /home/script/serverJAR -f
echo -e "\e[1;32m 新JAR準備好 \e[0m"
else
echo -e "\e[1;31m JAR包不存在,直接下一步 \e[0m"
fi
#------------5.開始啓動jar包----------------
cd /home/script/serverJAR
echo -e "\e[1;32m 開始啓動${arr[0]} \e[0m"
nohup java -jar ${JarName} >${arr[0]}_log 2>&1 &
echo -e "\e[1;32m 項目啓動完成 \e[0m"
#tail -f nohup.out
done
#///////////////////////////////Gradle構建的項目,該類型目前只有一個項目,所以不用循環///////////////////////////////
weId="weid-1.0-SNAPSHOT.jar"
#查看進程ID
PID_WeId=$(ps aux | grep ${weId} | grep -v 'grep' | awk '{print $2}')
#------------1.關閉已有進程----------------
if [[ ! -z ${PID_WeId} ]];then
echo -e "\e[1;32m weId 的進程ID是:${PID_WeId} \e[0m"
echo -e "\e[1;32m 即將關閉weId \e[0m"
kill -9 ${PID_WeId}
else
echo -e "\e[1;33m weId 沒有啓動 \e[0m"
fi
#------------2.編譯代碼--------------------
echo -e "\e[1;32m 開始編譯gradle項目 \e[0m"
cd /home/boc/weid
chmod +x ./gradlew && ./gradlew build -x test
echo -e "\e[1;32m 編譯完成 \e[0m"
#------------3.移動備份jar包----------------
echo -e "\e[1;32m 開始備份舊jar包,備份位置在:/home/script/serverJAR/bak \e[0m"
cd /home/script/serverJAR
if [[ -e ${weId} ]];then
mv ${weId} /home/script/serverJAR/bak/ -f
rm -rf ${weId}
echo -e "\e[1;32m JAR包備份完成 \e[0m"
else
echo -e "\e[1;37m JAR包不存在,直接下一步 \e[0m"
fi
#------------4.移動新jar包到執行目錄----------------
cd /home/boc/weid/build/libs
if [[ -e ${weId} ]];then
mv ${weId} /home/script/serverJAR -f
echo -e "\e[1;32m 新JAR準備好 \e[0m"
else
echo -e "\e[1;31m JAR包不存在,直接下一步 \e[0m"
fi
#------------5.開始啓動jar包----------------
cd /home/script/serverJAR
echo -e "\e[1;32m 開始啓動weid \e[0m"
nohup java -jar ${weId} >weid_log 2>&1 &
echo -e "\e[1;32m 項目啓動完成 \e[0m"
腳本說明
腳本總體分爲maven部分和gradle項目部分,因爲maven項目較多,所以採用一個數組定義,並在循環中處理。gradle部分主要不同時編譯命令不同,其他相似。爲了清晰,把兩部分分開寫。
總體思路就是:
- 先判斷服務進程運行情況,如果運行,則關閉進程
- 然後進行代碼更新和編譯
- 備份舊jar包,這一步很必要,如果啓動出現問題,可以方便回滾到之前的服務
- 拷貝新jar包後啓動服務
shell腳本部分語法說明:
-
字符串分隔數組
OLD_IFS="$IFS" #設置分隔符 IFS="-" #如下會自動分隔 arr=(${JarName}) # 將IFS恢復成原來的 IFS="$OLD_IFS"
IFS是系統默認的分隔符,這裏是固定語法,用自己需要的分隔符分隔數組後,恢復系統默認即可。
-
打印字符顏色
\e[1;37m xxx \e[0m
不同的顏色有不同的序號表示,根據需要查閱即可。
-
編譯jar包命令
maven項目打包並跳過測試代碼:
mvn clean package -Dmaven.test.skip=true
gradle項目打包並跳過測試:
chmod +x ./gradlew && ./gradlew build -x test
說明:如果服務器沒有裝gradle,則用gradlew命令。使用前需要先授權。如果服務器裝有gradle。也可以採用下面的命令:
gradle build -x test
腳本使用
執行腳本時,可以進入到腳本所在目錄執行下面命令:
sh deploy.sh
爲了在不同目錄執行,可以將腳本所在目錄配置到環境變量,這樣就可以在任意目錄執行
vim /etc/profile
增加PATH路徑
source /etc/profile
執行效果: