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