最近實踐Jenkins的自動化發布,即實現指定項目的編譯-打包-上傳-發布的持續集成發版過程。中途遇到不少問題,整理如下以備后忘。
---------------------
月下孤城
mail:eagle_daiqiang@sina.com
1.Jenkins安裝
Jenkins是開源軟件,直接到官網下載最新版本安裝。具體過程不再累述,網上資料很多。本文安裝版本jenkins-2.138.2。
2.Jenkins全局設置打開Jenkins-全局工具配置 配置編譯打包的工具,我使用的是maven,按具體環境配置好相應信息。若項目工程使用其他工具,如gradle在對應項配置信息即可。


3.publish over ssh
Jenkins - 插件管理 可選插件tab頁下安裝publish over ssh插件。用于Jenkins服務器ssh傳輸文件到Linux服務器。
安裝好publish over ssh插件后,到Jenkins - 配置中 publish over ssh項設置相關上傳Linux服務器信息。
ssh server設置:
統一配置發布文件的Linux服務器,如下圖。

其中 remote directory 表示發布文件到服務器的默認目錄。若為空默認為當前登錄用戶目錄。
4.項目發布
本文以svn的訂單order項目為例,通過Jenkins工具,經過編譯-打包-上傳-發布過程,動態的將java jar發布到兩臺服務器。
4.1 新建任務
Jenkins - 新建任務,創建order發布的一個任務。由于項目是基于maven的,所以選擇'構建一個maven項目'進入配置頁面。

配置svn代碼庫信息:
build配置:對應項目輸入項目構建命令。
post steps:配置發布服務器的信息。如下圖。

由于order訂單服務是集群部署,分別設置了2臺 ssh server。
source files 是指上傳到服務器的發布文件。Jenkins默認編譯后文件在workspace目錄下,這里輸入target/{發布jar文件}. 上傳到發布服務器后,不需要target目錄,所以 remove prefix中填target/。
Remote directory可以為空,由于我們在第3步中已經設置了全局默認ssh server的remote directory ,所以這里可以不填,如這里設置將覆蓋之前的全局配置目錄。
exec command是文件上傳到發布服務器后,需要執行的shell腳本指令,用于發布order jar包的啟動備份命令。圖中app-deploy.sh為應用jar文件的啟動備份shell腳本文件,需放到發布服務器指定目錄下。其中BUILD_ID=DONTKILLME是為了kill 老的運行jar時避免當前執行進程不被誤殺。
app-deploy.sh文件:
1.先stop老的jar應用程序。先從記錄的pid文件中找kill的進程,找不到通過ps指令查找當前運行jar文件,再kill -9 殺掉。
2.將老的jar程序移動到lastDeploy目錄備份,并加上時間戳后綴。將待發布的新jar文件從tmp目錄移動到發布目錄。
3.啟動新的jar程序文件。
Jenkins - 插件管理 可選插件tab頁下安裝publish over ssh插件。用于Jenkins服務器ssh傳輸文件到Linux服務器。
安裝好publish over ssh插件后,到Jenkins - 配置中 publish over ssh項設置相關上傳Linux服務器信息。
- Passphrase - 默認上傳服務器密碼
- Path to key - Jenkins服務器ssh key目錄
- key - Jenkins服務器ssh key內容,一般為~/.ssh目錄下id_rsa.pub內容
- SSH Servers - 上傳服務器的配置
ssh server設置:
統一配置發布文件的Linux服務器,如下圖。

其中 remote directory 表示發布文件到服務器的默認目錄。若為空默認為當前登錄用戶目錄。
4.項目發布
本文以svn的訂單order項目為例,通過Jenkins工具,經過編譯-打包-上傳-發布過程,動態的將java jar發布到兩臺服務器。
4.1 新建任務
Jenkins - 新建任務,創建order發布的一個任務。由于項目是基于maven的,所以選擇'構建一個maven項目'進入配置頁面。

配置svn代碼庫信息:


post steps:配置發布服務器的信息。如下圖。

由于order訂單服務是集群部署,分別設置了2臺 ssh server。
source files 是指上傳到服務器的發布文件。Jenkins默認編譯后文件在workspace目錄下,這里輸入target/{發布jar文件}. 上傳到發布服務器后,不需要target目錄,所以 remove prefix中填target/。
Remote directory可以為空,由于我們在第3步中已經設置了全局默認ssh server的remote directory ,所以這里可以不填,如這里設置將覆蓋之前的全局配置目錄。
exec command是文件上傳到發布服務器后,需要執行的shell腳本指令,用于發布order jar包的啟動備份命令。圖中app-deploy.sh為應用jar文件的啟動備份shell腳本文件,需放到發布服務器指定目錄下。其中BUILD_ID=DONTKILLME是為了kill 老的運行jar時避免當前執行進程不被誤殺。
app-deploy.sh文件:
#!/bin/sh
## java env
## service name
SERVICE_NAME=$1
SERVICE_DIR=/usr/service/
JAR_NAME=$SERVICE_NAME\.jar
PID=$SERVICE_NAME\.pid
#function start
start(){
cd $SERVICE_DIR
source /etc/profile
## nohup java -Xms256m -Xmx512m -jar $JAR_NAME >log/$SERVICE_NAME.out 2>&1 &
nohup java -jar -Xms256m -Xmx256m $JAR_NAME >/dev/null 2>&1 &
echo $! > $SERVICE_DIR/$PID
echo "#### start $SERVICE_NAME"
}
# function stop
stop(){
cd $SERVICE_DIR
if [ -f "$SERVICE_DIR/$PID" ]; then
kill `cat $SERVICE_DIR/$PID`
rm -rf $SERVICE_DIR/$PID
fi
echo "#### stop $SERVICE_NAME"
sleep 3
PROCESS=`ps -ef|grep $JAR_NAME |grep -v grep|grep -v PPID|awk '{ print $2}'`
for i in $PROCESS
do
echo "Kill the $SERVICE_NAME process [ $i ]"
kill -9 $i
done
}
# function clean
clean(){
echo "---start do do clean phase."
cd $SERVICE_DIR
if [ ! -d "lastDeploy" ]; then
mkdir lastDeploy
fi
if [ -f "$JAR_NAME" ]; then
echo "backup $JAR_NAME"
mv $JAR_NAME lastDeploy/$JAR_NAME\_`date "+%Y%m%d%H%M%S"`
fi
if [ -d "tmp" ]; then
mv -f tmp/$JAR_NAME ./
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"
;;
deploy)
stop
clean
start
echo "#### deploy $SERVICE_NAME"
;;
esac
exit 0
以上腳本發布邏輯如下:## java env
## service name
SERVICE_NAME=$1
SERVICE_DIR=/usr/service/
JAR_NAME=$SERVICE_NAME\.jar
PID=$SERVICE_NAME\.pid
#function start
start(){
cd $SERVICE_DIR
source /etc/profile
## nohup java -Xms256m -Xmx512m -jar $JAR_NAME >log/$SERVICE_NAME.out 2>&1 &
nohup java -jar -Xms256m -Xmx256m $JAR_NAME >/dev/null 2>&1 &
echo $! > $SERVICE_DIR/$PID
echo "#### start $SERVICE_NAME"
}
# function stop
stop(){
cd $SERVICE_DIR
if [ -f "$SERVICE_DIR/$PID" ]; then
kill `cat $SERVICE_DIR/$PID`
rm -rf $SERVICE_DIR/$PID
fi
echo "#### stop $SERVICE_NAME"
sleep 3
PROCESS=`ps -ef|grep $JAR_NAME |grep -v grep|grep -v PPID|awk '{ print $2}'`
for i in $PROCESS
do
echo "Kill the $SERVICE_NAME process [ $i ]"
kill -9 $i
done
}
# function clean
clean(){
echo "---start do do clean phase."
cd $SERVICE_DIR
if [ ! -d "lastDeploy" ]; then
mkdir lastDeploy
fi
if [ -f "$JAR_NAME" ]; then
echo "backup $JAR_NAME"
mv $JAR_NAME lastDeploy/$JAR_NAME\_`date "+%Y%m%d%H%M%S"`
fi
if [ -d "tmp" ]; then
mv -f tmp/$JAR_NAME ./
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"
;;
deploy)
stop
clean
start
echo "#### deploy $SERVICE_NAME"
;;
esac
exit 0
1.先stop老的jar應用程序。先從記錄的pid文件中找kill的進程,找不到通過ps指令查找當前運行jar文件,再kill -9 殺掉。
2.將老的jar程序移動到lastDeploy目錄備份,并加上時間戳后綴。將待發布的新jar文件從tmp目錄移動到發布目錄。
3.啟動新的jar程序文件。
---------------------
月下孤城
mail:eagle_daiqiang@sina.com