如何在Linux系统中将Spring Boot应用程序打包为可执行jar as a Service ?这是推荐的方法吗,还是应该将这个应用程序转换为war并将其安装到Tomcat中?

目前,我可以从屏幕会话运行Spring引导应用程序,这很好,但需要在服务器重新启动后手动启动。

我正在寻找的是一般的建议/方向或样本init。D脚本,如果我的方法与可执行jar是适当的。


当前回答

在systemd单元文件中,您可以通过目录或EnvironmentFile设置环境变量。我建议这样做,因为这似乎是最小的摩擦。

示例单元文件

$ cat /etc/systemd/system/hello-world.service
[Unit]
Description=Hello World Service
After=systend-user-sessions.service

[Service]
EnvironmentFile=/etc/sysconfig/hello-world
Type=simple
ExecStart=/usr/bin/java ... hello-world.jar

然后在/etc/sysconfig/hello-world下设置一个文件,其中包含Spring Boot变量的大写名称。例如,一个名为server的变量。port将遵循SERVER_PORT形式作为环境变量:

$ cat /etc/sysconfig/hello-world
SERVER_PORT=8081

这里所利用的机制是Spring Boot应用程序将获取属性列表,然后转换它们,将所有内容都改为大写,并将点替换为下划线。一旦Spring Boot应用程序完成了这个过程,它就会寻找匹配的环境变量,并相应地使用找到的环境变量。

在这篇题为:如何通过环境变量在其名称中设置带有下划线的Spring Boot属性的SO Q&A中强调了更多细节?

参考文献

第四部分。弹簧引导功能- 24。外部化配置

其他回答

对于SpringBoot 2.4.4,除了由 @ismael

我在maven pom.xml中有以下内容,使其成为可执行jar

<build>
    <plugins>
        <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>
    </plugins>
</build>

您正在使用Maven吗?那么你应该试试AppAssembler插件:

Application Assembler Plugin是一个Maven插件,用于生成启动java应用程序的脚本. ...所有工件(依赖项+项目中的工件)都被添加到生成的bin脚本中的类路径中。 支持平台: unix变体 Windows NT(不支持Windows 9x) Java服务包装器(JSW)

参见:http://mojo.codehaus.org/appassembler/appassembler-maven-plugin/index.html

构建中需要以下配置。Spring Boot项目中的gradle文件。

build.gradle

jar {
    baseName = 'your-app'
    version = version
}

springBoot {
    buildInfo()
    executable = true   
    mainClass = "com.shunya.App"
}

可执行文件= true

这是使jar在unix系统(Centos和Ubuntu)上完全可执行所必需的。

创建一个.conf文件

如果您想配置自定义JVM属性或Spring Boot应用程序运行参数,那么您可以创建一个与Spring Boot应用程序名称相同的.conf文件,并将其与jar文件并行放置。

考虑到your-app.jar是Spring Boot应用程序的名称,那么您可以创建以下文件。

JAVA_OPTS="-Xms64m -Xmx64m"
RUN_ARGS=--spring.profiles.active=prod
LOG_FOLDER=/custom/log/folder

此配置将为Spring Boot应用程序设置64 MB ram并激活prod配置文件。

在linux中创建一个新用户

为了增强安全性,我们必须创建一个特定的用户来运行Spring Boot应用程序作为服务。

创建新用户

sudo useradd -s /sbin/nologin springboot

在Ubuntu / Debian环境下,修改如下命令:

sudo useradd -s /usr/sbin/nologin springboot

设置密码

sudo passwd springboot

使springboot成为可执行文件的所有者

chown springboot:springboot your-app.jar

防止修改jar文件

chmod 500 your-app.jar

这将配置jar的权限,这样它就不能被写入,只能由它的所有者springboot读取或执行。

您可以使用change attribute (chattr)命令将jar文件设置为不可变的。

sudo chattr +i your-app.jar

也应该为相应的.conf文件设置适当的权限,.conf文件只需要读取权限(Octal 400),而不是读取+执行权限(Octal 500)

chmod 400 your-app.conf

创建Systemd服务

/etc/systemd/system/your-app.service

[Unit]
Description=Your app description
After=syslog.target

[Service]
User=springboot
ExecStart=/var/myapp/your-app.jar
SuccessExitStatus=143

[Install]
WantedBy=multi-user.target

如果进程被操作系统杀死,将自动重启进程

添加以下两个属性(Restart和RestartSec)以在失败时自动重新启动进程。

/etc/systemd/system/your-app.service

[Service]
User=springboot
ExecStart=/var/myapp/your-app.jar
SuccessExitStatus=143
Restart=always
RestartSec=30

该更改将使Spring Boot应用程序在失败时重新启动,延迟30秒。如果使用systemctl命令停止服务,则不会重新启动。

在系统启动时安排服务

要标记应用程序在系统引导时自动启动,使用以下命令:

在系统启动时启用Spring Boot应用程序

sudo systemctl enable your-app.service

启动或停止服务

systemctl可以在Ubuntu 16.04 LTS和18.04 LTS中用于启动和停止进程。

开始这个过程

sudo systemctl start your-app

停止进程

sudo systemctl stop your-app

参考文献

https://docs.spring.io/spring-boot/docs/current/reference/html/deployment-install.html

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).

这可以在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