Jenkins部署SpringBoot應用到遠端伺服器
使用SpringBoot、SpringCloud寫背景服務,也引入了當下比較流行的微服務的理念,子產品也比較多。為了友善前期測試和後期線上部署更新,使用Jenkins作為持續內建工具。
結構
伺服器結構
- 測試機器:若幹台外網測試或者生産主機。
- Jenkins伺服器:搭建Jenkins伺服器主機
- git代碼庫: 我這裡使用的碼雲
測試環境目錄結構
在根目錄下建立data
/data: 項目總目錄
/data/exec:執行腳本目錄
/data/pid:記錄各個程式運作時pid
/data/work:項目應用程式存放目錄
目錄結構思路
- 使用maven建構項目
- 建構後使用Publish Over SSH部署到遠端伺服器:
- 關閉應用
- 備份應用到lastDepoly目錄
- 上傳新版本的Jar包(或者war包)
- 啟動應用
- 其中,關閉、備份、删除和啟動應用都是由腳本來完成, 部署腳本 deploy.sh 放在 /data/exec下(内容見 相關腳本 章節)。
- Pushlish Over SSH的執行順序是先上傳檔案再執行腳本,是以對于每個應用每個伺服器我都設定了兩個 Transfer Set :
- 先執行清理腳本:關閉,備份和删除舊版應用jar包
deploy.sh cps-platform-1.0.0 clean
- 再執行啟動腳本啟動應用
deploy.sh chl-tss start
cps-platform-1.0.0 為項目打包的名稱,替換自己的 *.jar 名稱即可。
jenkins
下載下傳Jenkins
在https://jenkins.io/download/下載下傳Jenkins的最新版本。建議下載下傳LTS(LongTermSuport) jenkins.war。
建立Jenkins目錄結構,部署到jenkins伺服器
在Jenkins伺服器上建立以下結構
| - /jenkins/
| + pid # 記錄jenkins運作pid
| + conf # jenkins工作目錄
| + log
| jenkins.sh # jenkins.sh是為了友善啟動和停止jenkins伺服器
| jenkins.war
- 啟動jenkins :
./jenkins.sh start
- 關閉jenkins:
./jenkins.sh stop
将下載下傳的jenkins.war包上傳到Jenkins伺服器上,使用一下指令啟動:
nohup java -Xms256m -Xmx1024m -XX:MaxPermSize=512m -jar jenkins.war --ajp13Port=-1 --httpPort=8099 > jenkins.out 2>&1 &
–httpPort=8099指定jenkins啟動監聽的端口,這裡更改為8099(預設是8080)。
-Xms256m -Xmx1024m -XX:MaxPermSize=512m 設定了JVM參數(需要因環境而異)。
基本安裝的過程就不詳細的說了,這裡也可以參考一下,springboot 使用Jenkins實作自動化部署 是使用tomcat部署
增加 Publish Over SSH 插件
在 系統設定->插件管理->可選插件 搜尋 Publish Over SSH,選中點選立即安裝即可安裝。
設定SSH遠端伺服器
點選“進階”即可設定Push Over SSH的端口和密碼
- 勾選“Use password authentication, or use a different key”
- Passphrase / Password 設定密碼
- Port 設定端口
項目配置
建構環境中勾選 Send files or execute commands over SSH after the build runs,然後點選 Add Server,即可新增目标遠端伺服器:
- Name:新增的遠端伺服器
- Source files:需要上傳的檔案,可以使用通配符和Jenkins變量。
- Exec command:在遠端伺服器上執行的腳本,這裡我的想法是,先清理一下遠端伺服器,關閉服務并備份程式。
cd /data/exec
sh ./deploy.sh cps-platform-1.0.0 clean
點選Add Transfer Set,新增一組設定:
- Source files:需要上傳的檔案。**/cps-platform-1.0.0.jar。即maven打包生成後的jar封包件。路徑相對于maven工程的根目錄。
- Exec command:在遠端伺服器上執行的腳本。這裡需要先上傳檔案到伺服器,再執行啟動腳本
cd /data/exec
sh ./deploy.sh cps-platform-1.0.0 start
- 點開“進階”之後勾選上 Flatten files,扁平化檔案。隻上傳檔案,不上傳檔案所屬檔案夾。否則上傳到遠端檔案夾之後就會多一級 target 目錄。
相關腳本
jenkins.sh
#!/bin/sh
## java env
export JAVA_HOME=/usr/java/jdk1.8.0_261-amd64
export JRE_HOME=$JAVA_HOME/jre
export JENKINS_HOME=/jenkins/conf
## exec shell name
EXEC_SHELL_NAME=jenkins\.sh
## service name
SERVICE_NAME=jenkins
SERVICE_DIR=/jenkins
JAR_NAME=$SERVICE_NAME\.war
PID=pid/$SERVICE_NAME\.pid
cd $SERVICE_DIR
case "$1" in
start)
nohup java -Xms256m -Xmx1024m -XX:MaxPermSize=512m -jar $JAR_NAME --ajp13Port=-1 --httpPort=8099 > log/jenkins.out 2>&1 &
echo $! > $SERVICE_DIR/$PID
echo "#### start $SERVICE_NAME"
;;
stop)
kill `cat $SERVICE_DIR/$PID`
rm -rf $SERVICE_DIR/$PID
echo "#### stop $SERVICE_NAME"
sleep 8
TEMP_PID=`ps -ef | grep -w "$SERVICE_NAME" | grep "java" | awk '{print $2}'`
if [ "$TEMP_PID" == "" ]; then
echo "#### $SERVICE_NAME process not exists or stop success"
else
echo "#### $SERVICE_NAME process pid is:$TEMP_PID"
kill -9 $TEMP_PID
fi
;;
restart)
$0 stop
sleep 2
$0 start
echo "#### restart $SERVICE_NAME"
;;
esac
exit 0
deploy.sh
#!/bin/sh
## java env
export JAVA_HOME=/usr/java/jdk1.8.0_261-amd64
export JRE_HOME=$JAVA_HOME/jre
## exec shell name
EXEC_SHELL_NAME=$1\.sh
## service name
SERVICE_NAME=$1
SERVICE_DIR=/data
JAR_NAME=$SERVICE_DIR/$SERVICE_NAME\.jar
PID=pid/$SERVICE_NAME\.pid
WORK_DIR=$SERVICE_DIR/work
#function start
start(){
cd $WORK_DIR
if [ ! -d "log" ]; then
mkdir log
fi
nohup $JRE_HOME/bin/java -Xms256m -Xmx512m -jar $JAR_NAME --spring.profiles.active=test >log/$SERVICE_NAME.out 2>&1 &
echo $! > $SERVICE_DIR/$PID
echo "#### start $SERVICE_NAME"
}
# function stop
stop(){
cd $WORK_DIR
if [ -f "$SERVICE_DIR/$PID" ]; then
kill `cat $SERVICE_DIR/$PID`
rm -rf $SERVICE_DIR/$PID
fi
echo "#### stop $SERVICE_NAME"
sleep 6
TEMP_PID=`ps -ef | grep -w "$SERVICE_NAME" | grep "java" | awk '{print $2}'`
echo "#### TEMP_PID $TEMP_PID"
if [ "$TEMP_PID" == "" ]; then
echo "#### $SERVICE_NAME process not exists or stop success"
else
echo "#### $SERVICE_NAME process pid is:$TEMP_PID ."
kill -9 $TEMP_PID
fi
}
# function clean
clean(){
cd $WORK_DIR
if [ ! -d "lastDeploy" ]; then
mkdir lastDeploy
else
rm lastDeploy/$SERVICE_NAME*
fi
if [ -f "$JAR_NAME" ]; then
mv $JAR_NAME lastDeploy
fi
}
case "$2" in
start)
start
;;
stop)
stop
;;
restart)
stop
sleep 2
start
echo "#### restart $SERVICE_NAME"
;;
clean)
stop
sleep 2
clean
echo "#### clean $SERVICE_NAME"
;;
*)
## restart
stop
sleep 2
start
;;
esac
exit 0