SpringBoot 常用的部署方式

springbooot部署大概我用过这几种,做一下总结

Linux

1.executable

该方式主要借助官方的 spring-boot-maven-plugin 创建”Fully executable” jar ,这中jar包内置一个shell脚本,可以方便的将该应用设置为Unix/Linux的系统服务(init.d service),官方对该功能在CentOS和Ubuntu进行了测试,对于OS X和FreeBSD,可能需要自定义。具体步骤如下:

在 pom.xml 中引入插件

<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>

然后呢吧你打好的jar包放入linux服务器,首先呢你要赋予jar包 执行权限

chmod u+x demo.jar

其实呢现在就可以./demo.jar就可以运行了但是结束会话的话,进程就结束了,这时候呢,我们需要吧这个jar创建一个软连接到/etc/init.d/目录下

ln -s /var/app/demo.jar /etc/init.d/demo

这时候呢就可以使用这样的方式进行相关操作

/etc/init.d/demo start|stop|restart

默认PID文件路径:/var/run/appname/appname.pid

默认服务日志文件路径:/var/log/appname.log(可以通过下面.conf 的方式修改LOG_FOLDER)

是的没错但是有一点问题啊 就是启动的内存和日志这样不太好管理,可以在jar包相同路径下创建一个.conf文件,名称应该与.jar的名称相同,如demo.conf(如果我们打包的文jar文件为 demo-1.0.0.jar 那么这里的conf文件也应该是 demo-1.0.0.conf),其内容配置可以如下,自定义参数启动方式配置(更多配置参数,可以上官网)

#java的地址
JAVA_HOME=/usr/local/java/jdk1.8
#java运行参数
JAVA_OPTS=-Xmx1024M
#日志输出的地址
LOG_FOLDER=/usr/local/software/logs
#携带入参给程序
RUN_ARGS=--spring.profiles.active=dev

然后呢就可以通过service 来启动项目了

service demo start|stop|restart

假设日后有项目的迁移,和项目移动了位置 删除/etc/init.d下的软连接对应的 应用名即可

如果是centos7以上呢,还有另一种方法

编辑服务文件 vim /usr/lib/systemd/system/demo.service

[Unit]
Description=demo
After=network.target

[Service]
WorkingDirectory=/usr/local/demo
ExecStart=/usr/local/java/bin/java -Dsun.misc.URLClassPath.disableJarChecking=true -jar /usr/local/demo.jar
ExecStop=kill $MAINPID
Restart=always

[Install]
WantedBy=multi-user.target

然后就可以使用systemctl的形势进行操作了,关于更多 systemctl 命令的使用方法,谷哥有很多。

启动
systemctl start demo
停止
systemctl stop demo
重启
systemctl restart demo
查看日志
journalctl -u demo

2.自定义脚本

把脚本丢到项目文件夹, 添加执行权限即可。这里放一个我之前用的吧

#!/bin/bash

SpringBoot=$2

if [ "$1" = "" ];
then
echo -e "\033[0;31m 未输入操作名 \033[0m \033[0;34m {start|stop|restart|status} \033[0m"
exit 1
fi

if [ "$SpringBoot" = "" ];
then
echo -e "\033[0;31m 未输入应用名 \033[0m"
exit 1
fi

function start()
{
count=`ps -ef |grep java|grep $SpringBoot|grep -v grep|wc -l`
if [ $count != 0 ];then
echo "$SpringBoot is running..."
else
echo "Start $SpringBoot success..."
nohup java -jar $SpringBoot > /dev/null 2>&1 &
fi
}

function stop()
{
echo "Stop $SpringBoot"
boot_id=`ps -ef |grep java|grep $SpringBoot|grep -v grep|awk '{print $2}'`
count=`ps -ef |grep java|grep $SpringBoot|grep -v grep|wc -l`

if [ $count != 0 ];then
kill $boot_id
count=`ps -ef |grep java|grep $SpringBoot|grep -v grep|wc -l`

boot_id=`ps -ef |grep java|grep $SpringBoot|grep -v grep|awk '{print $2}'`
kill -9 $boot_id
fi
}

function restart()
{
stop
sleep 2
start
}

function status()
{
count=`ps -ef |grep java|grep $SpringBoot|grep -v grep|wc -l`
if [ $count != 0 ];then
echo "$SpringBoot is running..."
else
echo "$SpringBoot is not running..."
fi
}

case $1 in
start)
start;;
stop)
stop;;
restart)
restart;;
status)
status;;
*)

echo -e "\033[0;31m Usage: \033[0m \033[0;34m sh $0 {start|stop|restart|status} {SpringBootJarName} \033[0m
\033[0;31m Example: \033[0m
\033[0;33m sh $0 start esmart-test.jar \033[0m"
esac

使用的时候呢放入jar同级目录,然后赋予权限

chmod +x boot.sh

然后就可以这样启动了

./boot.sh  start|stop|status|restart demo.jar

原理是用nohup了,用法很多了可以自行谷哥

Docker

Docker 技术发展为微服务落地提供了更加便利的环境

1.Dockfile

目前我只用过maven插件的哪种~

plugins 中添加 Docker 构建插件:

<properties>
<docker.image.prefix>springboot</docker.image.prefix>
</properties>
<build>
<plugins>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.0.0</version>
<configuration>
<imageName>${docker.image.prefix}/${project.artifactId}</imageName>
<dockerDirectory>src/main/docker</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>

然后传件一个根目录src/main/docker 文件名就叫Dockerfile

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD demo.jar app.jar
RUN sh -c 'touch /app.jar'
ENV JAVA_OPTS=""
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar"]
  • FROM ,表示使用 Jdk8 环境 为基础镜像,如果镜像不是本地的会从 DockerHub 进行下载
  • VOLUME ,VOLUME 指向了一个/tmp的目录,由于 Spring Boot 使用内置的Tomcat容器,Tomcat 默认使用/tmp作为工作目录。这个命令的效果是:在宿主机的/var/lib/docker目录下创建一个临时文件并把它链接到容器中的/tmp目录
  • ADD ,拷贝文件并且重命名
  • ENTRYPOINT ,为了缩短 Tomcat 的启动时间,添加java.security.egd的系统属性指向/dev/urandom作为 ENTRYPOINT

然后

mvn package -DskipTests
mvn dockerfile:build

如果只是单纯的使用下dockerfile构建一下镜像,只需要 docker build -t demo 一行命令即可。

其实在以后项目多的情况下下,通常建立一个Docker-Compose 然后一键的依次部署。

给下总结

实际项目中还需要让spring boot应用在后台运行,并且能实现启动服务器后自动启动docker容器。其思路是,通常会使用supervisord来辅助完成,思路是在supervisord的配置文件中执行shell脚本。然而这同样不完美,而最好的做法是实现“持续集成”,其思路是使用jenkins来结合git钩子,当提交新版本的代码后,jenkins去执行shell脚本pull代码,然后maven打包,接下来生成最新版的docker镜像,最后推送新镜像和运行docker容器。这边就先不说了,以后出总结。

Windows

winws

windows没什么好说的我平时经常用

首先要下载winsw。它是一个单个的可执行文件,我们到Github release这里就可以下载winsw了。一般来说当然是下载最新的。winsw可以运行在.NET2和.NET4两个版本上,当然如果使用Win10等比较新的系统,最好下载更新版本的.NET。

我们需要编写一个和程序同名的XML文件作为winsw的配置文件。文件大体上长这样,这是官网的例子。

下载exe文件,假设改名成demo.exe

同目录下创建一个同名的xml文件,如demo.xml

配置如下:

<service>
<id>demo</id>
<name>demo</name>
<description>this is my service</description>
<executable>java</executable>
<arguments>-Xmx256m -jar c:\demo.jar</arguments>
<logmode>rotate</logmode>
</service>

安装服务命令:demo.exe install

卸载服务命令:demo.exe uninstall

打开系统服务功能:运行——输入services.msc,即可看见自己命名的服务demo,设置服务为自动,并启用即可