ChatGPT解决这个技术问题 Extra ChatGPT

如何在生产环境中运行 Spring Boot 可执行 jar?

Spring boot 的首选部署方法是通过一个包含 tomcat 的可执行 jar 文件。

它以一个简单的 java -jar myapp.jar 开始。

现在,我想将该 jar 部署到我在 EC2 上的 linux 服务器上,是我遗漏了什么还是我真的需要创建一个 init 脚本才能将应用程序作为守护程序正确启动?

如果我只是调用 java -jar,则应用程序会在我注销时死掉。

我可以在 screen 或 nohup 中启动它,但这不是很优雅,并且在我的服务器中重新启动会迫使我登录并手动启动该过程。

那么,春季启动中的任务是否已经完成?

nohup/screen(脏方法),init/systemd/upstart(正确方法)
@RC 是的,就像我提到的那样,我知道的很多,在 /etc/init.d 中带有自定义脚本的 /sbin/init 可以完成这项工作,但是每个人都应该构建自己的脚本来管理守护进程(启动、停止、重启、状态)?感觉该解决方案缺少某些东西。
我觉得 spring-boot 中缺少某些东西(顺便说一句,这是一个非常“新鲜”的项目)只需联系负责团队并提出进化建议即可。
好吧,如果您生成一个战争档案,您可以在 Tomcat 上使用您的发行版版本,该版本将有一个可供使用的 init 脚本。另一方面,如果您使用可执行 jar 方法,则必须提供自己的自定义 init 脚本。不确定这是否在引导领域,但它显然丢失了,这有点奇怪,因此我问我是否忽略了某些东西。将ping他们。
请参阅 here for existing discussion 和想法。

m
mrts

请注意,从 Spring Boot 1.3.0.M1 开始,您可以使用 Maven 和 Gradle 构建完全可执行的 jar。

对于 Maven,只需在 pom.xml 中包含以下内容:

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

对于 Gradle,将以下代码段添加到您的 build.gradle

springBoot {
    executable = true
}

完全可执行的 jar 在文件的前面包含一个额外的脚本,它允许您将 Spring Boot jar 符号链接到 init.d 或使用 systemd 脚本。

init.d 示例:

$ln -s /var/yourapp/yourapp.jar /etc/init.d/yourapp

这允许您启动、停止和重新启动您的应用程序,例如:

$/etc/init.d/yourapp start|stop|restart

或使用 systemd 脚本:

[Unit]
Description=yourapp
After=syslog.target

[Service]
ExecStart=/var/yourapp/yourapp.jar
User=yourapp
WorkingDirectory=/var/yourapp
SuccessExitStatus=143

[Install]
WantedBy=multi-user.target

更多信息请访问以下链接:

作为 init.d 服务安装

作为 systemd 服务安装


您可能还需要执行 $ chmod +x /etc/init.d/yourapp 才能启动/停止/重新启动
您始终必须授予服务用户读取和执行 jar 文件的权限。您还必须为服务器和 Java 环境变量配置默认 Java 才能正常工作。
这不行!我已经尝试过了,我收到以下错误:无法启动 MyApp.service: Unit MyApp.service not found
springBoot { executable = true } 的 kotlin 语法是什么?
@nayandhabarde 我基于 Kotlin 的 gradle 配置有 tasks.withType { launchScript() } 我执行 ./gradlew bootJar
m
mrts

到目前为止,在生产环境中运行 Spring Boot 应用程序最简单、最可靠的方法是使用 Docker。如果您需要使用多个连接的服务,请使用 Docker Compose、Docker Swarm 或 Kubernetes。

以下是来自官方 Spring Boot Docker guide 的简单 Dockerfile,可帮助您入门:

FROM openjdk:8-jdk-alpine
RUN addgroup -S spring && adduser -S spring -G spring
USER spring:spring
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

构建 Docker 映像的更好方法是使用 Jib,这是一种由 Google 维护的开源 Java 工具,用于构建 Java 应用程序的 Docker 映像。 Jib 不需要 Dockerfile,您只需使用 Maven(官方快速入门 here)或 Gradle(官方快速入门 here)调用它。

这是一个将容器作为守护进程运行的示例命令行:

docker run \
  -d --restart=always \
  -e "SPRING_PROFILES_ACTIVE=prod" \
  -p 8080:8080 \
  prefix/imagename

V
Vinod Mohanan

我的 Spring Boot 应用程序有两个初始化程序。一个用于开发,另一个用于生产。对于开发,我使用这样的主要方法:

@SpringBootApplication
public class MyAppInitializer {

    public static void main(String[] args) {
        SpringApplication.run(MyAppInitializer .class, args);
    }

}

我的生产环境初始化器扩展了 SpringBootServletInitializer,如下所示:

@SpringBootApplication
public class MyAppInitializerServlet extends SpringBootServletInitializer{
    private static final Logger log = Logger
            .getLogger(SpringBootServletInitializer.class);
    @Override
    protected SpringApplicationBuilder configure(
            SpringApplicationBuilder builder) {
        log.trace("Initializing the application");
        return builder.sources(MyAppInitializerServlet .class);
    }

}

我使用 gradle 并且我的 build.gradle 文件应用了“WAR”插件。当我在开发环境中运行它时,我使用 bootrun 任务。当我想将它部署到生产环境时,我使用 assemble 任务来生成 WAR 并进行部署。

我可以在生产中像普通的 Spring 应用程序一样运行,而不会忽视内置 tomcat 在开发时提供的优势。希望这可以帮助。


S
Stéphane GRILLON

在没有服务的 Windows 操作系统上。

开始.bat

@ECHO OFF
call run.bat start

停止.bat:

@ECHO OFF
call run.bat stop

运行.bat

@ECHO OFF
IF "%1"=="start" (
    ECHO start myapp
    start "myapp" java -jar -Dspring.profiles.active=staging myapp.jar
) ELSE IF "%1"=="stop" (
    ECHO stop myapp
    TASKKILL /FI "WINDOWTITLE eq myapp"
) ELSE (
    ECHO please, use "run.bat start" or "run.bat stop"
)
pause

s
spstorey

在生产环境中,您希望您的应用程序在机器重新启动等时再次启动,创建 /etc/init.d/ 脚本并链接到适当的运行级别以启动和停止它是正确的方法。 Spring Boot 不会扩展到涵盖这一点,因为它是特定于操作系统的设置,并且还有很多其他选项,您是否希望它在 chroot 监狱中运行,是否需要在其他一些软件之前停止/启动等。


u
unnik

您可以使用名为 Supervisor 的应用程序。在主管配置中,您可以定义多个服务和执行相同的方式。

对于 Java 和 Spring 引导应用程序,该命令将为 java -jar springbootapp.jar

可以提供选项以保持应用程序始终运行。因此,如果 EC2 重新启动,那么 Supervisor 将重新启动您的应用程序

与将启动脚本放在 /etc/init.d/ 中相比,我发现 Supervisor 易于使用。启动脚本会挂起或进入等待状态以防出错。


i
isijara

如果您使用的是 gradle,您可以将其添加到您的 build.gradle

springBoot {
    executable = true
}

然后,您可以通过键入 ./your-app.jar 来运行您的应用程序

此外,您可以在此处找到完整指南,将您的应用设置为服务

56.1.1 作为 init.d 服务安装(系统 V)

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

干杯


实际上结果应该是bootRepackage { executable = true }参见docs.spring.io/spring-boot/docs/current/reference/html/…
S
Scrayos

我通过 screen -dmS NAME /path/to/script 启动我想要永久或至少半永久运行的应用程序。据我所知,这是最优雅的解决方案。


B
BeeNoisy

这是一个简单的,你可以使用 spring boot maven 插件来完成你的代码部署。

插件配置如下:

<plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <jvmArguments>-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=${debug.port}
                    </jvmArguments>
                    <profiles>
                        <profile>test</profile>
                    </profiles>
                    <executable>true</executable>
                </configuration>
            </plugin>

而且,jvmArtuments 是为您添加的 jvm。 profiles 将选择一个配置文件来启动您的应用程序。 executable 可以让您的应用程序直接运行。

如果您将 mvnw 添加到您的项目中,或者您有一个 Maven 环境。您可以为 mvnw 调用 ./mvnw spring-boot:run 或为 maven 调用 mvn spring-boot:run