如何在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是适当的。
当前回答
Following up on Chad's excellent answer, if you get an error of "Error: Could not find or load main class" - and you spend a couple hours trying to troubleshoot it, whether your executing a shell script that starts your java app or starting it from systemd itself - and you know your classpath is 100% correct, e.g. manually running the shell script works as well as running what you have in systemd execstart. Be sure you're running things as the correct user! In my case, I had tried different users, after quite a while of troubleshooting - i finally had a hunch, put root as the user - voila, the app started correctly. After determining it was a wrong user issue, I chown -R user:user the folder and subfolders and the app ran correctly as the specified user and group so no longer needed to run it as root (bad security).
其他回答
您还可以使用监控器,这是一个非常方便的守护进程,可以用来轻松地控制服务。这些服务是由简单的配置文件定义的,这些配置文件定义了在哪个目录下哪个用户执行什么,等等,有无数的选项。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脚本所具有的所有灵活性,而且易于使用和控制。看一下文档。
这可以在Ubuntu中使用Systemd服务完成
[Unit]
Description=A Spring Boot application
After=syslog.target
[Service]
User=baeldung
ExecStart=/path/to/your-app.jar SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
你可以点击这个链接获得更详细的描述和不同的方法。 http://www.baeldung.com/spring-boot-app-as-a-service
我最终为WAR/JAR布局做了systemd服务
我调用java -jar是因为它更灵活。我还试着把ExecStart=spring-mvc。战争,但即使是可执行的,我得到'Exec格式错误'
无论如何,现在systemd出现在所有发行版上,并提供了一个很好的解决方案来重定向日志(syserr是重要的,当你的服务甚至没有启动log4j文件位置将为空:))。
cat /etc/systemd/system/spring-mvc.service
[Unit]
Description=Spring MVC Java Service
[Service]
User=spring-mvc
# The configuration file application.properties should be here:
WorkingDirectory=/usr/local/spring-mvc
# Run ExecStartPre with root-permissions
PermissionsStartOnly=true
ExecStartPre=-/bin/mkdir -p /var/log/spring-mvc
ExecStartPre=/bin/chown -R spring-mvc:syslog /var/log/spring-mvc
ExecStartPre=/bin/chmod -R 775 /var/log/spring-mvc
#https://www.freedesktop.org/software/systemd/man/systemd.service.html#ExecStart=
ExecStart=/usr/bin/java \
-Dlog4j.configurationFile=log4j2-spring.xml \
-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector \
-Dspring.profiles.active=dev \
-Denvironment-type=dev \
-XX:+UseConcMarkSweepGC \
-XX:CMSInitiatingOccupancyFraction=80 \
-XX:NewSize=756m \
-XX:MetaspaceSize=256m \
-Dsun.net.inetaddr.ttl=5 \
-Xloggc:/var/log/spring-mvc/gc.log \
-verbose:gc \
-verbosegc \
-XX:+DisableExplicitGC \
-XX:+PrintGCDetails \
-XX:+PrintGCDateStamps \
-XX:+PreserveFramePointer \
-XX:+StartAttachListener \
-Xms1024m \
-Xmx1024m \
-XX:+HeapDumpOnOutOfMemoryError \
-jar spring-mvc.war
SuccessExitStatus=143
StandardOutput=journal
StandardError=journal
KillSignal=SIGINT
TimeoutStopSec=20
Restart=always
RestartSec=5
StartLimitInterval=0
StartLimitBurst=10
LimitNOFILE=500000
LimitNPROC=500000
#https://www.freedesktop.org/software/systemd/man/systemd.exec.html#LimitCPU=
#LimitCPU=, LimitFSIZE=, LimitDATA=, LimitSTACK=, LimitCORE=, LimitRSS=, LimitNOFILE=, LimitAS=, LimitNPROC=, LimitMEMLOCK=, LimitLOCKS=, LimitSIGPENDING=, LimitMSGQUEUE=, LimitNICE=, LimitRTPRIO=, LimitRTTIME=¶
SyslogIdentifier=spring-mvc
[Install]
WantedBy=multi-user.target
# https://www.freedesktop.org/software/systemd/man/journalctl.html
#check logs --- journalctl -u spring-mvc -f -o cat
Rsyslog -将应用程序的syslog输入重定向到特定的文件夹/文件
cat /etc/rsyslog.d/30-spring-mvc.conf
if $programname == 'spring-mvc' then /var/log/spring-mvc/spring-mvc.log
& stop
logrotate
cat /etc/logrotate.d/spring-mvc.conf
/var/log/spring-mvc/spring-mvc.log
{
daily
rotate 30
maxage 30
copytruncate
missingok
notifempty
compress
dateext
dateformat _%Y-%m-%d_%H-%M
delaycompress
create 644 spring-mvc syslog
su spring-mvc syslog
}
logrotate gc
cat /etc/logrotate.d/spring-mvc-gc.conf
/var/log/spring-mvc/gc.log
{
daily
rotate 30
maxage 30
copytruncate
missingok
notifempty
compress
dateext
dateformat _%Y-%m-%d_%H-%M
delaycompress
create 644 spring-mvc syslog
su spring-mvc syslog
}
下面是在Linux中将Java应用程序作为系统服务安装的最简单方法。
让我们假设你正在使用systemd(现在任何现代发行版都是这样):
首先,在/etc/systemd/system目录下创建一个服务文件,例如javaservice。服务内容如下:
[Unit]
Description=Java Service
[Service]
User=nobody
# The configuration file application.properties should be here:
WorkingDirectory=/data
ExecStart=/usr/bin/java -Xmx256m -jar application.jar --server.port=8081
SuccessExitStatus=143
TimeoutStopSec=10
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
其次,通知systemd新的服务文件:
systemctl daemon-reload
并启用它,以便它在引导时运行:
systemctl enable javaservice.service
最后,您可以使用以下命令来启动/停止您的新服务:
systemctl start javaservice
systemctl stop javaservice
systemctl restart javaservice
systemctl status javaservice
如果使用systemd,这是将Java应用程序设置为系统服务的最非侵入性和最干净的方法。
我特别喜欢这个解决方案的地方在于,您不需要安装和配置任何其他软件。所提供的systemd为您完成所有工作,您的服务就像任何其他系统服务一样。我现在在生产环境中使用了一段时间,在各种发行版上,它就像你期望的那样工作。
另一个优点是,通过使用/usr/bin/java,您可以轻松添加jvm参数,如-Xmx256m。
请阅读官方Spring Boot文档中的systemd部分: http://docs.spring.io/spring-boot/docs/current/reference/html/deployment-install.html
我试图使springboot应用程序呈现为“init”。D”风格的shell脚本与压缩Java应用程序钉在最后
通过符号链接这些脚本从/etc/init.D /spring-app到/opt/spring-app.jar,并chmod jar使其可执行。D /spring-app启动/etc/init。D /spring-app stop”和其他可能的状态工作
假设是init。来自springboot的d风格脚本看起来他们有必要的魔法字符串(像# Default-Start: 2 3 4 5) chkconfig将能够将其作为“服务”添加。
但是我想让它和systemd一起工作
为了做到这一点,我尝试了上面其他答案中的许多食谱,但在Centos 7.2和Springboot 1.3上,它们都不适合我。大多数情况下,它们会启动服务,但无法跟踪pid
最后,我发现下面的方法对我有用,当/etc/init.D链接也到位了。一个类似于下面的文件应该安装为/usr/lib/systemd/system/spring-app.service
[Unit]
Description=My loverly application
After=syslog.target
[Service]
Type=forking
PIDFile=/var/run/spring-app/spring-app.pid
ExecStart=/etc/init.d/spring-app start
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target