Как запустить исполняемый файл jar с загрузкой Spring в производственной среде?

106

Предпочтительный метод развертывания Spring boot - через исполняемый файл jar, который содержит внутри tomcat.

Все начинается с простого java -jar myapp.jar.

Теперь я хочу развернуть эту банку на моем сервере Linux на EC2, мне что-то не хватает или мне действительно нужно создать сценарий инициализации для правильного запуска приложения в качестве демона?

Если я просто вызываю, java -jarприложение умирает, когда я выхожу из системы.

Я мог бы запустить его на экране или в nohup, но это не очень элегантно, и перезапуск моего сервера вынудил бы меня войти в систему и запустить процесс вручную.

Итак, есть ли что-то для этой задачи в весенней загрузке?

Клебер Гонсалвес
источник
2
nohup / screen (грязный метод), init / systemd / upstart (правильный метод)
@RC Да, насколько я знаю, как я уже упоминал, / sbin / init с настраиваемым сценарием в /etc/init.d справится с этой задачей, но действительно ли идея состоит в том, что каждый должен создать свой собственный сценарий для управления демон (запуск, остановка, перезапуск, статус)? Похоже, что в этом решении чего-то не хватает.
Cleber Goncalves
Мне кажется, что в spring -boot чего-то не хватает (кстати, это действительно «свежий» проект), просто свяжитесь с командой и сделайте предложение по развитию.
Что ж, если вы создаете военный архив, вы можете использовать версию вашего дистрибутива на Tomcat, у которой будет готовый сценарий инициализации. С другой стороны, если вы используете подход с исполняемым jar-файлом, вам придется создать свой собственный сценарий инициализации. Не уверен, что это находится в области загрузки, но явно отсутствует, что довольно странно, поэтому я спрашиваю, если я что-то пропустил. Будет пинговать их.
Cleber Goncalves
1
Смотрите здесь существующие обсуждения и идеи.
Дэйв Сайер

Ответы:

97

Обратите внимание, что начиная с Spring Boot 1.3.0.M1 вы можете создавать полностью исполняемые jar-файлы с помощью Maven и Gradle.

Для 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

Дополнительная информация по следующим ссылкам:

Corleone
источник
4
Возможно, вам также понадобится сделать, $ chmod +x /etc/init.d/yourappчтобы иметь возможность запускать / останавливать / перезапускать
Рохит Нандакумар
Вы всегда должны предоставлять пользователю службы права на чтение и выполнение файла jar. Вы также должны настроить Java по умолчанию для переменных сервера и среды Java, чтобы все работало.
micaro
Это не работает! Я попробовал и получаю следующую ошибку: Не удалось запустить MyApp.service: Unit 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
mrts
источник
3

У моего загрузочного приложения Spring есть два инициализатора. Один для разработки, а другой для производства. Для разработки я использую такой основной метод:

@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 и развертывания.

Я могу работать в продакшене как обычное весеннее приложение, не сбрасывая со счетов преимущества встроенного tomcat при разработке. Надеюсь это поможет.

O-OF-N
источник
2

В производственной среде вы хотите, чтобы ваше приложение снова запускалось при перезапуске компьютера и т. Д., Создание сценария /etc/init.d/ и привязка к соответствующему уровню запуска для запуска и остановки - это правильный подход. Spring Boot не распространяется на это, поскольку это настройка, специфичная для операционной системы, и есть множество других опций, хотите ли вы, чтобы она работала в chroot jail, нужно ли ее останавливать / запускать перед другим программным обеспечением и т.

spstorey
источник
2

Вы можете использовать приложение под названием Supervisor . В конфигурации супервизора вы можете определить несколько служб и способов их выполнения.

Для загрузочных приложений Java и Spring команда будет java -jar springbootapp.jar.

Могут быть предоставлены параметры, чтобы приложение всегда работало, поэтому при перезапуске EC2 Supervisor перезапустит ваше приложение.

Я нашел Supervisor простым в использовании по сравнению с помещением сценариев запуска в /etc/init.d/. Сценарии запуска зависали или переходили в состояние ожидания в случае ошибок.

унник
источник
2

Если вы используете 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

ура

Исиджара
источник
На самом деле это должно быть bootRepackage { executable = true }См. Docs.spring.io/spring-boot/docs/current/reference/html/…
Philippe
2

В ОС Windows без службы.

start.bat

@ECHO OFF
call run.bat start

stop.bat:

@ECHO OFF
call run.bat stop

run.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
Стефан ГРИЛЬОН
источник
1

Я запускаю приложения, которые хочу запускать постоянно или хотя бы полупостоянно, через screen -dmS NAME / path / to / script. Насколько мне известно, это наиболее элегантное решение.

Scrayos
источник
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 enveriment. Вы можете просто вызвать ./mvnw spring-boot:runmvnw или mvn spring-boot:runmaven.

BeeNoisy
источник