如何在生产环境中运行spring boot可执行jar?


105

Spring Boot的首选部署方法是通过其中包含tomcat的可执行jar文件。

它从简单开始java -jar myapp.jar

现在,我想将该jar部署到EC2上的linux服务器上,是否丢失了某些东西,还是真的需要创建一个初始化脚本来正确地将应用程序作为守护程序启动?

如果我只是简单地调用,java -jar则应用程序在注销时死亡。

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

那么,在Spring Boot中已经有一些任务要做吗?


1
nohup / screen(脏方法),init / systemd / upstart(适当方法)

@RC是的,正如我所提到的,我知道很多,/ sbin / init在/etc/init.d中带有自定义脚本,可以完成这项工作,但实际上每个人都应该构建自己的脚本来管理守护程序(启动,停止,重新启动,状态)?该解决方案似乎缺少某些东西。
Cleber Goncalves 2014年

我觉得在Spring-boot中缺少一些东西(顺便说一句,这是一个非常“新鲜”的项目),只需与负责团队联系并提出发展建议即可。

好吧,如果生成战争存档,则可以在Tomcat上使用发行版的版本,该版本将具有可以使用的初始化脚本。另一方面,如果使用可执行jar方法,则必须提出自己的自定义init脚本。不知道这是否在引导程序的境界上,但是它显然丢失了,这有点奇怪,因此我问我是否忽略了某些内容。会ping它们。
Cleber Goncalves 2014年

1
有关现有讨论和想法,请参见此处
Dave Syer 2014年

Answers:


96

请注意,从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

以下链接提供了更多信息:


4
您可能还需要做$ chmod +x /etc/init.d/yourapp一些才能启动/停止/重新启动
Rohith Nandakumar

您始终必须授予服务用户读取和执行jar文件的权限。您还必须为服务器和Java环境变量配置默认Java,以使其正常运行。
micaro '19

这行不通!我已经尝试过,但收到以下错误:无法启动MyApp.service:找不到单位MyApp.service
Martijn Hiemstra

9

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

以下是Dockerfile官方Spring Boot Docker指南中的简单入门,可以帮助您入门:

FROM frolvlad/alpine-oraclejdk8:slim
VOLUME /tmp
ADD YOUR-APP-NAME.jar app.jar
RUN sh -c 'touch /app.jar'
ENV JAVA_OPTS=""
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]

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

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

3

我的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任务。就像我要将其部署到生产环境一样,我使用组装任务生成WAR并进行部署。

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


2

在生产环境中,您希望在计算机重启等情况下再次启动应用程序,创建/etc/init.d/脚本并链接到适当的运行级别以启动和停止它是正确的方法。Spring Boot不会扩展到此范围,因为它是特定于操作系统的设置,还有许多其他选项,您是否希望它在chroot监狱中运行,是否需要先停止/启动某些其他软件等?


2

您可以使用名为Supervisor的应用程序。在超级用户配置中,您可以定义多种服务及其执行方式。

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

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

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


2

如果您正在使用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/...
菲利普·

2

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

start.bat

@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

1

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


0

这很简单,您可以使用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 spring-boot:runmvnw或mvn spring-boot:runmaven。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.