web-dev-qa-db-fra.com

Comment exécuter un fichier jar exécutable de démarrage printanier dans un environnement de production?

La méthode de déploiement préférée de Spring Boot consiste à utiliser un fichier jar exécutable contenant Tomcat.

Il commence par un simple Java -jar myapp.jar.

Maintenant, je veux déployer ce fichier jar sur mon serveur Linux sur EC2, est-ce qu'il me manque quelque chose ou dois-je vraiment créer un script init pour démarrer correctement l'application en tant que démon?

Si j'appelle simplement Java -jar, l'application meurt lorsque je me déconnecte.

Je pourrais le démarrer à l'écran ou à Nohup, mais ce n'est pas très élégant et un redémarrage sur mon serveur m'obligerait à me connecter et à démarrer le processus manuellement.

Alors, y a-t-il déjà quelque chose à faire pour cette tâche au printemps?

90
Cleber Goncalves

Veuillez noter que depuis Spring Boot 1.3.0.M1, vous pouvez créer des fichiers jar entièrement exécutables à l'aide de Maven et Gradle.

Pour Maven, incluez simplement ce qui suit dans votre pom.xml:

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

Pour Gradle, ajoutez l’extrait suivant à votre build.gradle:

springBoot {
    executable = true
}

Le fichier jar entièrement exécutable contient un script supplémentaire à l'avant du fichier, ce qui vous permet simplement de faire un lien symbolique entre votre fichier jar Spring Boot et init.d ou d'utiliser un script systemd.

init.d exemple:

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

Cela vous permet de démarrer, d’arrêter et de redémarrer votre application de la manière suivante:

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

Ou utilisez un script 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

Plus d'informations sur les liens suivants:

83
corleone

Docker est de loin le moyen le plus simple et le plus fiable d’exécuter des applications Spring Boot en production. Utilisez Docker Compose, Docker Swarm ou Kubernetes si vous devez utiliser plusieurs services connectés.

Voici un simple Dockerfile de l’officiel guide Spring Boot Docker pour vous aider à démarrer:

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" ]

Voici un exemple de ligne de commande pour exécuter le conteneur en tant que démon:

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

Mon application de démarrage Spring a deux initialiseurs. Un pour le développement et un autre pour la production. Pour le développement, j'utilise la méthode principale comme ceci:

@SpringBootApplication
public class MyAppInitializer {

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

}

Mon initialiseur pour environnement de production étend le SpringBootServletInitializer et se présente comme suit:

@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);
    }

}

J'utilise gradle et mon fichier build.gradle applique le plugin 'WAR'. Lorsque je l'exécute dans l'environnement de développement, j'utilise la tâche bootrun. Où et quand je veux le déployer en production, j'utilise assembler tâche pour générer le WAR et le déployer.

Je peux utiliser comme une application de printemps normale en production sans négliger les avantages fournis par le Tomcat intégré lors du développement. J'espère que cela t'aides.

3
O-OF-N

Vous pouvez utiliser l'application appelée Supervisor . Dans supervisor config, vous pouvez définir plusieurs services et différentes manières de les exécuter.

Pour Java et les applications de démarrage Spring, la commande serait Java -jar springbootapp.jar.

Des options peuvent être fournies pour que l'application soit toujours exécutée. Si le EC2 redémarre, Supervisor redémarrera votre application.

J'ai trouvé Supervisor facile à utiliser par rapport à l'insertion de scripts de démarrage dans /etc/init.d/. Les scripts de démarrage se bloquaient ou se mettaient en attente en cas d'erreur.

2
unnik

Dans un environnement de production, vous souhaitez que votre application soit redémarrée lors du redémarrage d'une machine, etc., la création d'un script /etc/init.d/ et la liaison au niveau d'exécution approprié pour le démarrer et l'arrêter constituent la bonne approche. Spring Boot ne couvrira pas cela car il s’agit d’une configuration spécifique au système d’exploitation et de nombreuses autres options, voulez-vous qu’elle s’exécute dans une prison chroot, devez-vous l’arrêter avant un autre logiciel, etc.

2
spstorey

Sous Windows sans service.

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
2
sgrillon

Si vous utilisez gradle, vous pouvez simplement ajouter ceci à votre build.gradle

springBoot {
    executable = true
}

Vous pouvez ensuite exécuter votre application en tapant ./your-app.jar

Vous pouvez également trouver ici un guide complet pour configurer votre application en tant que service.

56.1.1 Installation en tant que service init.d (System V)

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

à votre santé

2
isijara

Je démarre les applications que je souhaite exécuter de manière persistante ou au moins semi-permanente via screen -dmS NAME/chemin/vers/script. Pour autant que je sache, c'est la solution la plus élégante.

1
Scrayos

C’est simple, vous pouvez utiliser Spring Boot Maven Plugin pour terminer le déploiement de votre code.

la configuration du plugin comme:

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

Et, la jvmArtuments est ajoutée pour vous jvm. profiles choisira un profil pour démarrer votre application. executable peut faire fonctionner votre application de manière directe.

et si vous ajoutez mvnw à votre projet, ou si vous avez une envergure. Vous pouvez simplement appeler ./mvnw spring-boot:run pour mvnw ou mvn spring-boot:run pour maven.

0
BeeNoisy