如何在Linux系统中将Spring Boot应用程序打包为可执行jar as a Service ?这是推荐的方法吗,还是应该将这个应用程序转换为war并将其安装到Tomcat中?
目前,我可以从屏幕会话运行Spring引导应用程序,这很好,但需要在服务器重新启动后手动启动。
我正在寻找的是一般的建议/方向或样本init。D脚本,如果我的方法与可执行jar是适当的。
如何在Linux系统中将Spring Boot应用程序打包为可执行jar as a Service ?这是推荐的方法吗,还是应该将这个应用程序转换为war并将其安装到Tomcat中?
目前,我可以从屏幕会话运行Spring引导应用程序,这很好,但需要在服务器重新启动后手动启动。
我正在寻找的是一般的建议/方向或样本init。D脚本,如果我的方法与可执行jar是适当的。
当前回答
您还可以使用监控器,这是一个非常方便的守护进程,可以用来轻松地控制服务。这些服务是由简单的配置文件定义的,这些配置文件定义了在哪个目录下哪个用户执行什么,等等,有无数的选项。supervisor ord的语法非常简单,所以它是编写SysV初始化脚本的一个很好的替代方案。
这里有一个简单的监督配置文件,用于您试图运行/控制的程序。(把这个放到/etc/supervisor/conf.d/yourapp.conf)
/etc/supervisor/conf.d/yourapp.conf
[program:yourapp]
command=/usr/bin/java -jar /path/to/application.jar
user=usertorun
autostart=true
autorestart=true
startsecs=10
startretries=3
stdout_logfile=/var/log/yourapp-stdout.log
stderr_logfile=/var/log/yourapp-stderr.log
要控制应用程序,你需要执行监控器ctl,它会提示你启动、停止和状态你的应用程序。
CLI
# sudo supervisorctl
yourapp RUNNING pid 123123, uptime 1 day, 15:00:00
supervisor> stop yourapp
supervisor> start yourapp
如果监控器守护进程已经在运行,并且您已经为您的服务添加了配置,而没有重新启动守护进程,那么您可以在监控器shell中简单地执行一个重读和更新命令。
这确实为您提供了使用SysV Init脚本所具有的所有灵活性,而且易于使用和控制。看一下文档。
其他回答
作为Windows服务
如果你想在windows机器上运行,请下载winsw.exe
http://repo.jenkins-ci.org/releases/com/sun/winsw/winsw/2.1.2/
之后,将其重命名为jar文件名(例如:your-app.jar)
winsw.exe -> your-app.exe
现在创建一个xml文件your-app.xml,并将以下内容复制到该文件中
<?xml version="1.0" encoding="UTF-8"?>
<service>
<id>your-app</id>
<name>your-app</name>
<description>your-app as a Windows Service</description>
<executable>java</executable>
<arguments>-jar "your-app.jar"</arguments>
<logmode>rotate</logmode>
</service>
确保exe和xml以及jar文件在同一个文件夹中。
在此之后,在管理员权限下打开命令提示符并将其安装到windows服务。
your-app.exe install
eg -> D:\Springboot\your-app.exe install
如果失败了
Error: Registry key 'Software\JavaSoft\Java Runtime Environment'\CurrentVersion' has value '1.8', but '1.7' is required.
然后试试下面的方法:
Delete java.exe, javaw.exe and javaws.exe from C:\Windows\System32
就是这样:).
在windows下卸载服务
your-app.exe uninstall
查看/运行/停止服务: win+r并输入Administrative tools,然后从中选择服务。然后右击选择选项-运行/停止
I don't know of a "standard" shrink-wrapped way to do that with a Java app, but it's definitely a good idea (you want to benefit from the keep-alive and monitoring capabilities of the operating system if they are there). It's on the roadmap to provide something from the Spring Boot tool support (maven and gradle), but for now you are probably going to have to roll your own. The best solution I know of right now is Foreman, which has a declarative approach and one line commands for packaging init scripts for various standard OS formats (monit, sys V, upstart etc.). There is also evidence of people having set stuff up with gradle (e.g. here).
我自己刚刚抽出时间来做这件事,所以下面是到目前为止我在CentOS初始化方面的进展。D业务控制器脚本。到目前为止,它工作得很好,但我不是leet Bash黑客,所以我相信还有改进的空间,所以欢迎提出改进的想法。
首先,我为每个服务准备了一个简短的配置脚本/data/svcmgmt/conf/my-spring-boot-api.sh,用于设置环境变量。
#!/bin/bash
export JAVA_HOME=/opt/jdk1.8.0_05/jre
export APP_HOME=/data/apps/my-spring-boot-api
export APP_NAME=my-spring-boot-api
export APP_PORT=40001
我使用CentOS,所以为了确保我的服务在服务器重启后启动,我在/etc/init.d/my-spring-boot-api中有一个服务控制脚本:
#!/bin/bash
# description: my-spring-boot-api start stop restart
# processname: my-spring-boot-api
# chkconfig: 234 20 80
. /data/svcmgmt/conf/my-spring-boot-api.sh
/data/svcmgmt/bin/spring-boot-service.sh $1
exit 0
如您所见,它调用初始配置脚本来设置环境变量,然后调用我用来重新启动所有Spring Boot服务的共享脚本。共享脚本是所有内容的核心所在:
#!/bin/bash
echo "Service [$APP_NAME] - [$1]"
echo " JAVA_HOME=$JAVA_HOME"
echo " APP_HOME=$APP_HOME"
echo " APP_NAME=$APP_NAME"
echo " APP_PORT=$APP_PORT"
function start {
if pkill -0 -f $APP_NAME.jar > /dev/null 2>&1
then
echo "Service [$APP_NAME] is already running. Ignoring startup request."
exit 1
fi
echo "Starting application..."
nohup $JAVA_HOME/bin/java -jar $APP_HOME/$APP_NAME.jar \
--spring.config.location=file:$APP_HOME/config/ \
< /dev/null > $APP_HOME/logs/app.log 2>&1 &
}
function stop {
if ! pkill -0 -f $APP_NAME.jar > /dev/null 2>&1
then
echo "Service [$APP_NAME] is not running. Ignoring shutdown request."
exit 1
fi
# First, we will try to trigger a controlled shutdown using
# spring-boot-actuator
curl -X POST http://localhost:$APP_PORT/shutdown < /dev/null > /dev/null 2>&1
# Wait until the server process has shut down
attempts=0
while pkill -0 -f $APP_NAME.jar > /dev/null 2>&1
do
attempts=$[$attempts + 1]
if [ $attempts -gt 5 ]
then
# We have waited too long. Kill it.
pkill -f $APP_NAME.jar > /dev/null 2>&1
fi
sleep 1s
done
}
case $1 in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
esac
exit 0
当停止时,它将尝试使用弹簧引导驱动器来执行受控关机。但是,如果没有配置执行器或未能在合理的时间范围内关闭(我给它5秒,这真的有点短),进程将被杀死。
此外,脚本还假设运行应用程序的java进程是进程详细信息文本中唯一带有“my-spring-boot-api.jar”的进程。在我的环境中,这是一个安全的假设,这意味着我不需要跟踪pid。
以下是针对springboot 1.3及以上版本的工作:
init。d服务
可执行jar具有通常的启动、停止、重新启动和状态命令。它还将在通常的/var/run目录中设置一个PID文件,默认情况下在通常的/var/log目录中设置日志。
你只需要将你的jar文件符号链接到/etc/init.D喜欢这样
sudo link -s /var/myapp/myapp.jar /etc/init.d/myapp
OR
sudo ln -s ~/myproject/build/libs/myapp-1.0.jar /etc/init.d/myapp_servicename
之后你就可以做平常的事情了
/etc/init.d/myapp start
然后在你想启动/停止应用程序的运行级别设置一个链接。
作为一个systemd服务
要运行安装在var/myapp中的Spring Boot应用程序,可以在/etc/systemd/system/myapp.service中添加以下脚本:
[Unit]
Description=myapp
After=syslog.target
[Service]
ExecStart=/var/myapp/myapp.jar
[Install]
WantedBy=multi-user.target
注意:如果你正在使用这种方法,不要忘记让jar文件本身可执行(使用chmod +x),否则它将失败,错误“权限被拒绝”。
参考
http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/html/deployment-install.html#deployment-service
在这个问题中,@PbxMan的回答可以让你开始:
在Linux上运行Java应用程序作为服务
编辑:
还有另一种不太好的方式在重启时启动进程,使用cron:
@reboot user-to-run-under /usr/bin/java -jar /path/to/application.jar
这是可行的,但不能为应用程序提供良好的启动/停止界面。你仍然可以简单地杀死它……