springboot项目一般是打成jar包上传到服务器,然后执行启动或者重启命令。
# env用具体环境变量替换
mvn -U clean package -Dmaven.test.skip=true -Penv
scp xxx.jar user@remote_host:/aaa/bbb/
然后就可以根据打包的方式以及服务器上的工具服务对jar包进行启动了。
在服务器上,首先需要确保已经安装了java运行环境,然后进入springboot应用程序的目录,通过java -jar命令进行启动:
java -jar demo.jar
此方式只会运行在当前窗口,当关闭窗口或断开连接,jar进程就会终止。
可以使用nohup命令结合java -jar以不挂断的方式进行后台启动:
nohup java -jar demo.jar >/dev/null 2>start.log &
当然也可以编写一个简单的shell脚本来启动springboot应用程序。首先,在应用程序目录下创建一个名为start.sh的文件,并添加以下内容:
#!/bin/sh
#jar名称
APP_NAME='demo.jar'
nohup java -Djava.security.egd=file:/dev/./urandom -Xms256m -Xmx1024m -XX:NewRatio=4 -XX:SurvivorRatio=4 -Dfile.encoding=utf-8 -jar -jar $APP_NAME >/dev/null 2>start.log &
使用以下命令授予脚本执行权限:
chmod +x start.sh
在应用程序目录运行shell脚本即可启动java服务:
sh ./start.sh
当然也可以使用完整的shell脚本来控制java服务的启动、关闭、重启以及状态检查能力。
springboot项目也可以通过插件打包成完全可执行的jar。可以在项目中添加springboot打包插件:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
然后执行打包命令后,运行./xxx.jar就能启动服务了。这种方式虽然启动方便了,但是关停和重启不太友好,还需要通过其他系统命令辅助。我们可以通过改造打包配置,将项目打包成服务模式:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<layout>ZIP</layout>
<executable>true</executable>
<embeddedLaunchScriptProperties>
<mode>service</mode>
<logFolder>${logDir}</logFolder>
<pidFolder>${pidDir}</pidFolder>
</embeddedLaunchScriptProperties>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
这样打包后,上传到服务器可以执行start|stop|restart等命令了。
./xxx.jar start
./xxx.jar restart
./xxx.jar stop
需要注意的是,需要指定logFolder和pidFolder属性,否则默认访问/var/log和/var/run目录,非root用户是没有权限的,另外java服务也一般不会使用root启动,如果不配置启动会受限:
修改运行账户可以访问的log和pid目录后,服务启停都正常:
Supervisor是一个进程管理工具,可以帮助监控和管理后台进程。我们可以使用Supervisor来启动和管理SpringBoot应用程序。
安装初始化:
#安装supervisor
pip3 install supervisor
# 创建配置路径
mkdir -p /etc/supervisor/
#生成配置文件
echo_supervisord_conf > /etc/supervisor/supervisord.conf
修改主配置文件在结尾添加配置并保存:
files=/etc/supervisor/conf.d/*.conf
创建启动文件夹并配置:
[program:demo]
command=java -Djava.security.egd=file:/dev/./urandom -Xms256m -Xmx1024m -XX:NewRatio=4 -XX:SurvivorRatio=4 -Dfile.encoding=utf-8 -jar /opt/app/server/demo.jar
autorestart=true
autostart=false
startretries=1
stderr_logfile=/mnt/applogs/demo/err.log
stdout_logfile=/mnt/applogs/demo/out.log
切到非root用户启动supervisor:
supervisord -c /etc/supervisor/supervisord.conf
然后使用supervisor命令启动springboot服务:
supervisorctl start demo
这样服务就启动起来了。
将springboot应用程序打包为Docker镜像,可以在Linux上使用Docker容器启动应用程序。
首先安装并启动Docker服务。
sudo yum update -y
sudo amazon-linux-extras install docker
sudo service docker start
sudo systemctl enable docker
然后,在springboot应用程序的目录下创建一个Dockerfile文件,并添加以下内容:
FROM openjdk:8
ARG PROFILES
ARG APP_NAME_ARG
ARG SERVER_PORT_ARG
ENV PROFILES_ACTIVE ${PROFILES}
ENV APP_SERVER_PORT ${SERVER_PORT_ARG}
ENV LANG=zh_CN.UTF-8
RUN apt-get update && apt-get install -y locales && sed -i 's/# zh_CN.UTF-8 UTF-8/zh_CN.UTF-8 UTF-8/' /etc/locale.gen && locale-gen
VOLUME /tmp
ADD ${APP_NAME_ARG}.jar /app.jar
RUN bash -c 'touch /app.jar'
EXPOSE ${SERVER_PORT_ARG}
ENTRYPOINT ["sh", "-c", " date && java -XX:+
UseG1GC -Dfile.encoding=utf-8 -Dserver.port=${SERVER_PORT_ARG} \
-jar /app.jar --spring.profiles.active=${PROFILES}"]
然后在springboot程序jar所在目录添加start.sh启动脚本:
cd /opt/app/server/
docker build --build-arg PROFILES=$1 --build-arg APP_NAME_ARG=$2 --build-arg SERVER_PORT_ARG=$3 -t $2:0.0.1 .
docker stop $2
docker rm $2
docker rmi $(docker images | awk '/^<none>/ { print $3 }')
docker run -v /mnt:/mnt -p $3:$3 --restart=always --name $2 -d $2:0.0.1
先构建容器镜像,然后停止原来的容器,移除原来的容器和老的镜像,然后用新的镜像启动容器和应用程序。
最后通过命令执行start.sh脚本来启动程序:
sh /opt/app/server/start.sh test demo 8080
类Unix系统中通常使用init.d脚本来管理系统服务。
使用打包插件打成可执行的jar:
<configuration>
<executable>true</executable>
</configuration>
然后在jar包同级目录增加同名的配置文件,比如demo.jar对应demo.conf,内容如下:
UN_AS_USER="dev"
JAVA_OPTS="-Dfile.encoding=UTF-8 -Xms512M -Xmx512M -Djava.security.egd=file:/dev/./urandom -XX:InitiatingHeapOccupancyPercent=70 -XX:G1ReservePercent=15 -XX:G1HeapRegionSize=32M -XX:MaxMetaspaceSize=256m -XX:MaxDirectMemorySize=256m"
PID_FOLDER="./pid"
LOG_FOLDER="./logs"
然后将jar包软链到init.d:
sudo ln -s /opt/app/server/demo.jar /etc/init.d/demo
执行之后在/etc/init.d目录出现浅蓝色连接
然后就可以执行start|restart|status|stop等命令了
service xxx start
service xxx restart
service xxx status
service xxx stop
并且可以看到与jar同目录的配置文件生效了,不管是root还是非root启动,最终服务都是以我们指定的user启动,着实方便。
systemd是Linux上的一个系统和服务管理器,可以将Spring Boot应用程序配置为systemd服务进行管理。在使用systemd之前,需要创建一个your-app-name.service文件,该文件包含了服务的相关配置信息。
首先,在终端中使用以下命令进入/etc/systemd/system/目录:
cd /etc/systemd/system/
然后,创建一个your-app-name.service文件比如demo.jar,并添加以下内容:
[Unit]
Description=demo
After=syslog.target
[Service]
User=xxx
ExecStart=/usr/bin/java -jar /opt/app/server/demo.jar
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
其中user指定了应用程序运行时所使用的用户,ExecStart中的命令与使用java命令启动应用程序的命令相同。然后使用以下命令重新加载systemd配置文件并启动服务:
systemctl daemon-reload
systemctl start demo
可以通过以下命令查看服务运行状态:
systemctl status demo
springboot打成jar包之后有上述这么多甚至更多启动方式,而对于不同的公司和团队以及个人喜好,热衷使用的启动方式也不尽相同,如果想偷懒则可以使用supervisor,但是可维护性不好,并且它也会额外增加系统开销,对于规模成型的团队会考虑docker或者脚本启动,对于linux比较熟悉的可以使用init.d和systemd方式,也有一些开发者认为一个程序本身应该具备和包含自我运行的所有条件以及能力,那么会使用打包成可执行jar方式。对于通常情况来讲,个人推荐打包成可执行jar和注册成init.d运行(指定非root),当然也可以一起沟通看法。
本文分享自 PersistentCoder 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!