如何在生产环境中运行弹簧启动可执行 jar?

Spring 启动的首选部署方法是通过一个可执行的 jar 文件,其中包含 tomcat。

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

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

如果我简单地调用 java -jar,当我注销时应用程序就会死亡。

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

So, is there something already for the task in spring boot?

158945 次浏览

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

在生产环境中,您希望您的应用程序在机器重新启动时重新启动等等,创建/etc/init.d/script 并链接到适当的运行级别以启动和停止它是正确的方法。Spring Boot 不会涉及到这个问题,因为它是一个特定于操作系统的设置,而且有成吨的其他选项,你想让它在 chroot 监狱中运行吗,它需要在其他软件之前停止/启动吗,等等。

我的 Spring 启动应用程序有两个初始化器。一个用于开发,另一个用于生产。对于开发,我使用的主要方法如下:

@SpringBootApplication
public class MyAppInitializer {


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


}

My Initializer for production environment extends the SpringBootServletInitializer and looks like this:

@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 文件应用了‘ 战争’插件。当我在开发环境中运行它时,我使用 Bootrun任务。当我想将它部署到生产环境时,我使用 集合任务来生成 WAR 并进行部署。

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

Please note that since Spring Boot 1.3.0.M1, you are able to build fully executable jars using Maven and Gradle.

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

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

在你的 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

更多资料请浏览以下连结:

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

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

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

与将启动脚本放入/etc/init.d/中相比,我发现督导程序很容易使用。如果出现错误,启动脚本将挂起或进入等待状态。

这是一个简单的,你可以使用 Spring 启动 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

如果使用 gradle,可以将其添加到 build.gradle 中

springBoot {
executable = true
}

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

此外,您可以在这里找到一个完整的指南,以设置您的应用程序作为一项服务

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

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

干杯

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

Here's a simple Dockerfile from the official 弹簧靴码头指南 to get you started:

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 (正式快速启动 给你)或 Gradle (正式快速启动 给你)调用它。

下面是将容器作为守护进程运行的示例命令行:

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

Windows 操作系统中的无服务。

开始,击球

@ECHO OFF
call run.bat start

stop.bat:

@ECHO OFF
call run.bat stop

快跑,蝙蝠

@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