Dans le document Spring Boot, ils ont déclaré que «Chaque SpringApplication enregistrera un hook d'arrêt auprès de la JVM pour s'assurer que ApplicationContext est fermé correctement à la sortie.
Lorsque je clique ctrl+c
sur la commande shell, l'application peut être arrêtée en douceur. Si j'exécute l'application sur une machine de production, je dois utiliser la commande
java -jar ProApplicaton.jar
. Mais je ne peux pas fermer le terminal shell, sinon cela fermera le processus.
Si j'exécute une commande comme nohup java -jar ProApplicaton.jar &
, je ne peux pas l'utiliser ctrl+c
pour l'arrêter gracieusement.
Quelle est la bonne façon de démarrer et d'arrêter une application Spring Boot dans l'environnement de production?
linux
spring
spring-boot
Chris
la source
la source
kill -SIGTERM <PID>
ça devrait faire l'affaire.Réponses:
Si vous utilisez le module actionneur, vous pouvez arrêter l'application via
JMX
ouHTTP
si le point final est activé.ajouter à
application.properties
:L'URL suivante sera disponible:
/actuator/shutdown
- Permet à l'application de s'arrêter en douceur (non activé par défaut).Selon la manière dont un point de terminaison est exposé, le paramètre sensible peut être utilisé comme un indice de sécurité.
Par exemple, les points de terminaison sensibles auront besoin d'un nom d'utilisateur / mot de passe lorsqu'ils seront accédés via
HTTP
(ou simplement désactivés si la sécurité Web n'est pas activée).À partir de la documentation de Spring Boot
la source
Voici une autre option qui ne vous oblige pas à modifier le code ou à exposer un point de terminaison d'arrêt. Créez les scripts suivants et utilisez-les pour démarrer et arrêter votre application.
start.sh
Démarre votre application et enregistre l'ID de processus dans un fichier
stop.sh
Arrête votre application en utilisant l'ID de processus enregistré
start_silent.sh
Si vous devez démarrer l'application à l'aide de ssh à partir d'une machine distante ou d'un pipeline CI, utilisez ce script à la place pour démarrer votre application. L'utilisation directe de start.sh peut laisser le shell se bloquer.
Après par exemple. re / déployer votre application, vous pouvez la redémarrer en utilisant:
la source
nohup
vous pouvez simplement fusionner les commandesQuant à la réponse de @ Jean-Philippe Bond,
Voici un exemple rapide maven pour l'utilisateur maven pour configurer le point de terminaison HTTP pour arrêter une application Web Spring Boot à l'aide de spring-boot-starter-actuator afin que vous puissiez copier et coller:
1.Maven pom.xml:
2.application.properties:
Tous les points de terminaison sont répertoriés ici :
3.Envoyez une méthode de publication pour arrêter l'application:
Note de sécurité:
si vous avez besoin de la méthode d'arrêt auth protected, vous devrez peut-être également
configurer les détails :
la source
server.contextPath=/appName
dans mon application.properties Alors maintenant, la commande d'arrêt deviendrait:curl -X POST localhost:8080/appName/shutdown
J'espère que cela peut aider quelqu'un. J'ai dû beaucoup lutter à cause de cette erreur.endpoints.shutdown.enabled=true management.security.enabled=false
.Vous pouvez faire en sorte que l'application springboot écrive le PID dans un fichier et vous pouvez utiliser le fichier pid pour arrêter ou redémarrer ou obtenir l'état à l'aide d'un script bash. Pour écrire le PID dans un fichier, enregistrez un écouteur sur SpringApplication à l'aide de ApplicationPidFileWriter comme indiqué ci-dessous:
Ensuite, écrivez un script bash pour exécuter l'application Spring Boot. Référence .
Vous pouvez maintenant utiliser le script pour démarrer, arrêter ou redémarrer.
la source
Toutes les réponses semblent manquer le fait que vous devrez peut-être effectuer une partie du travail de manière coordonnée pendant un arrêt normal (par exemple, dans une application d'entreprise).
@PreDestroy
vous permet d'exécuter le code d'arrêt dans les beans individuels. Quelque chose de plus sophistiqué ressemblerait à ceci:la source
Je n'expose aucun point de terminaison et je démarre ( avec nohup en arrière-plan et sans les fichiers créés via nohup ) et je m'arrête avec le script shell (avec KILL PID gracieusement et force tuer si l'application est toujours en cours d'exécution après 3 minutes ). Je viens de créer un fichier jar exécutable et d'utiliser l'écrivain de fichier PID pour écrire un fichier PID et stocker Jar et Pid dans un dossier avec le même nom que le nom de l'application et les scripts shell ont également le même nom avec start et stop à la fin. J'appelle ces scripts d'arrêt et démarre le script via le pipeline jenkins également. Aucun problème pour l'instant. Fonctionne parfaitement pour 8 applications (scripts très génériques et faciles à appliquer pour n'importe quelle application).
Classe principale
FICHIER YML
Voici le script de démarrage (start-appname.sh):
Voici le script d'arrêt (stop-appname.sh):
la source
Spring Boot a fourni plusieurs écouteurs d'application tout en essayant de créer un contexte d'application, l'un d'eux est ApplicationFailedEvent. On peut utiliser pour connaître la météo du contexte d'application initialisé ou non.
Ajoutez à la classe d'écouteur ci-dessus à SpringApplication.
la source
À partir de Spring Boot 2.3 et versions ultérieures, il existe un arrêt progressif intégré mécanisme d' .
Pre-Spring Boot 2.3 , il n'y a pas de mécanisme d'arrêt normal prêt à l'emploi. Certains démarreurs à ressort offrent cette fonctionnalité:
Je suis l'auteur de nr. 1. Le démarreur s'appelle "Hiatus for Spring Boot". Il fonctionne au niveau de l'équilibreur de charge, c'est-à-dire qu'il marque simplement le service comme OUT_OF_SERVICE, sans interférer en aucune façon avec le contexte de l'application. Cela permet de procéder à un arrêt progressif et signifie que, si nécessaire, le service peut être mis hors service pendant un certain temps, puis ramené à la vie. L'inconvénient est que cela n'arrête pas la JVM, vous devrez le faire avec la
kill
commande. Comme j'exécute tout dans des conteneurs, ce n'était pas un gros problème pour moi, car je devrai de toute façon m'arrêter et retirer le conteneur.Les n ° 2 et 3 sont plus ou moins basés sur ce post d'Andy Wilkinson. Ils fonctionnent à sens unique - une fois déclenchés, ils finissent par fermer le contexte.
la source
SpringApplication enregistre implicitement un hook d'arrêt avec la JVM pour garantir que ApplicationContext est fermé correctement à la sortie. Cela appellera également toutes les méthodes bean annotées avec
@PreDestroy
. Cela signifie que nous n'avons pas à utiliser explicitement laregisterShutdownHook()
méthode aConfigurableApplicationContext
dans une application de démarrage, comme nous devons le faire dans l'application Spring Core.la source
@PostConstruct
,@PreDestroy
j'ai utilisé les attributsinitMethod
etdestroyMethod
dans l'@Bean
annotation. Donc , pour cet exemple:@Bean(initMethod="init", destroyMethod="destroy")
.@PreDestroy
peu de développeurs ignorent est que ces méthodes ne sont appelées que pour les beans avec une portée Singleton. Les développeurs doivent gérer la partie nettoyage du cycle de vie du bean pour les autres portéesIl existe de nombreuses façons d'arrêter une application à ressort. La première consiste à appeler close () sur le
ApplicationContext
:Votre question suggère que vous souhaitez fermer votre application en faisant
Ctrl+C
, qui est fréquemment utilisé pour terminer une commande. Dans ce cas...L'utilisation
endpoints.shutdown.enabled=true
n'est pas la meilleure recette. Cela signifie que vous exposez un point de terminaison pour mettre fin à votre application. Ainsi, en fonction de votre cas d'utilisation et de votre environnement, vous devrez le sécuriser ...Ctrl+C
devrait très bien fonctionner dans votre cas. Je suppose que votre problème est causé par l'esperluette (&) Plus d'explication:Un contexte d'application Spring peut avoir enregistré un hook d'arrêt avec le runtime JVM. Consultez la documentation ApplicationContext .
Je ne sais pas si Spring Boot configure ce hook automatiquement comme vous l'avez dit. Je suppose que oui.
Activé
Ctrl+C
, votre shell envoie unINT
signal à l'application au premier plan. Cela signifie "veuillez interrompre votre exécution". L'application peut intercepter ce signal et effectuer un nettoyage avant sa fin (le hook enregistré par Spring), ou simplement l'ignorer (mauvais).nohup
est une commande qui exécute le programme suivant avec un trap pour ignorer le signal HUP. HUP est utilisé pour terminer le programme lorsque vous raccrochez (fermez votre connexion ssh par exemple). De plus, il redirige les sorties pour éviter que votre programme ne se bloque sur un TTY disparu.nohup
n'ignore PAS le signal INT. Cela n'empêche donc PASCtrl+C
de travailler.Je suppose que votre problème est causé par l'esperluette (&), pas par nohup.
Ctrl+C
envoie un signal aux processus de premier plan. L'esperluette entraîne l'exécution de votre application en arrière-plan. Une solution: faireUtilisez
kill -9
oukill -KILL
est incorrect car l'application (ici la JVM) ne peut pas l'intercepter pour se terminer correctement.Une autre solution consiste à ramener votre application au premier plan. Puis
Ctrl+C
fonctionnera. Jetez un œil sur le contrôle Bash Job, plus précisément surfg
.la source
Utilisez la
exit()
méthode statique de la classe SpringApplication pour fermer correctement votre application de démarrage de printemps.la source
Spring Boot prend désormais en charge l'arrêt progressif (actuellement dans les versions préliminaires, 2.3.0.BUILD-SNAPSHOT)
Vous pouvez l'activer avec:
https://docs.spring.io/spring-boot/docs/2.3.0.BUILD-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-graceful-shutdown
la source
Si vous utilisez maven, vous pouvez utiliser le plugin assembleur Maven App .
Le démon mojo (qui intègre JSW ) produira un script shell avec l'argument start / stop. Le
stop
va arrêter / tuer gracieusement votre application Spring.Le même script peut être utilisé pour utiliser votre application maven en tant que service linux.
la source
Si vous êtes dans un environnement Linux, tout ce que vous avez à faire est de créer un lien symbolique vers votre fichier .jar depuis /etc/init.d/
Ensuite, vous pouvez démarrer l'application comme n'importe quel autre service
Pour fermer l'application
De cette façon, l'application ne se terminera pas lorsque vous quitterez le terminal. Et l'application s'arrêtera gracieusement avec la commande d'arrêt.
la source