J'ai écrit une application serveur Java qui s'exécute sur une solution Linux hébergée virtuelle standard. L'application s'exécute tout le temps en écoutant les connexions de sockets et en créant de nouveaux gestionnaires pour celles-ci. C'est une implémentation côté serveur pour une application client-serveur.
Je commence par l'inclure dans le script de démarragerc.local du serveur. Cependant, une fois démarré, je ne sais pas comment y accéder pour l'arrêter et si je souhaite installer une mise à jour, je dois donc redémarrer le serveur pour pouvoir redémarrer l'application.
Sur un PC Windows, pour ce type d'application, je pourrais créer un service Windows, puis l'arrêter et le démarrer comme je le souhaite. Y at-il quelque chose comme ça sur une machine Linux afin que si je lance cette application je puisse l’arrêter et la redémarrer sans faire un redémarrage complet du serveur.
Mon application s'appelle WebServer.exe. Il est démarré au démarrage du serveur en l'incluant dans mon rc.local en tant que tel:
Java -jar /var/www/vhosts/myweb.com/phpserv/WebServer.jar &
Je suis un peu un noob à Linux donc tout exemple serait apprécié avec n'importe quel message. Cependant, j'ai SSH et un accès FTP complet à la boîte pour installer les mises à jour, ainsi que l'accès à un panneau Plesk.
J'ai écrit un autre simple wrapper ici:
#!/bin/sh
SERVICE_NAME=MyService
PATH_TO_JAR=/usr/local/MyProject/MyJar.jar
PID_PATH_NAME=/tmp/MyService-pid
case $1 in
start)
echo "Starting $SERVICE_NAME ..."
if [ ! -f $PID_PATH_NAME ]; then
Nohup Java -jar $PATH_TO_JAR /tmp 2>> /dev/null >> /dev/null &
echo $! > $PID_PATH_NAME
echo "$SERVICE_NAME started ..."
else
echo "$SERVICE_NAME is already running ..."
fi
;;
stop)
if [ -f $PID_PATH_NAME ]; then
PID=$(cat $PID_PATH_NAME);
echo "$SERVICE_NAME stoping ..."
kill $PID;
echo "$SERVICE_NAME stopped ..."
rm $PID_PATH_NAME
else
echo "$SERVICE_NAME is not running ..."
fi
;;
restart)
if [ -f $PID_PATH_NAME ]; then
PID=$(cat $PID_PATH_NAME);
echo "$SERVICE_NAME stopping ...";
kill $PID;
echo "$SERVICE_NAME stopped ...";
rm $PID_PATH_NAME
echo "$SERVICE_NAME starting ..."
Nohup Java -jar $PATH_TO_JAR /tmp 2>> /dev/null >> /dev/null &
echo $! > $PID_PATH_NAME
echo "$SERVICE_NAME started ..."
else
echo "$SERVICE_NAME is not running ..."
fi
;;
esac
Vous pouvez suivre un tutoriel complet pour init.d here et pour systemd (ubuntu 16 +) here
Si vous avez besoin du journal de sortie, remplacez le 2
Nohup Java -jar $PATH_TO_JAR /tmp 2>> /dev/null >> /dev/null &
lignes pour
Nohup Java -jar $PATH_TO_JAR >> myService.out 2>&1&
Une solution simple consiste à créer un script start.sh qui exécute Java via Nohup, puis stocke le PID dans un fichier:
Nohup Java -jar myapplication.jar > log.txt 2> errors.txt < /dev/null &
PID=$!
echo $PID > pid.txt
Ensuite, votre script d'arrêt stop.sh lirait le PID du fichier et tuerait l'application:
PID=$(cat pid.txt)
kill $PID
Bien sûr, j'ai omis certains détails, tels que la vérification de l'existence du processus et la suppression de pid.txt
si vous avez terminé.
Les scripts d'initialisation du service Linux sont stockés dans /etc/init.d
. Vous pouvez copier et personnaliser le fichier /etc/init.d/skeleton
, puis appeler
service [yourservice] start|stop|restart
voir http://www.ralfebert.de/blog/Java/debian_daemon/ . C'est pour Debian (donc, Ubuntu aussi) mais pour plus de distribution.
Peut-être pas la meilleure solution de dev-ops, mais bon pour l’utilisation générale d’un serveur pour un groupe local ou similaire.
Utilisez screen
pour exécuter votre serveur, puis détachez-le avant de vous déconnecter. Le processus continuera de fonctionner, vous pourrez alors vous reconnecter à tout moment.
Flux de travail:
Lancer un écran: screen
Démarrez votre serveur: Java -jar minecraft-server.jar
Détachez en appuyant sur: Ctl-a
, d
Re-attacher: screen -r
Plus d'infos ici: https://www.gnu.org/software/screen/manual/screen.html
Une autre alternative, qui est également très populaire, est le Java Service Wrapper . Ceci est également très populaire dans la communauté des logiciels libres.
En se référant à l'application Spring Boot en tant que service , j'opterais également pour la version systemd
, puisqu'elle est la plus facile, la moins détaillée et la mieux intégrée dans les distributions modernes (et même les moins modernes, comme CentOS 7 .X).
Voici un exemple de script Shell (assurez-vous de remplacer le nom MATH par le nom de votre application):
#!/bin/bash
### BEGIN INIT INFO
# Provides: MATH
# Required-Start: $Java
# Required-Stop: $Java
# Short-Description: Start and stop MATH service.
# Description: -
# Date-Creation: -
# Date-Last-Modification: -
# Author: -
### END INIT INFO
# Variables
PGREP=/usr/bin/pgrep
Java=/usr/bin/Java
ZERO=0
# Start the MATH
start() {
echo "Starting MATH..."
#Verify if the service is running
$PGREP -f MATH > /dev/null
VERIFIER=$?
if [ $ZERO = $VERIFIER ]
then
echo "The service is already running"
else
#Run the jar file MATH service
$Java -jar /opt/MATH/MATH.jar > /dev/null 2>&1 &
#sleep time before the service verification
sleep 10
#Verify if the service is running
$PGREP -f MATH > /dev/null
VERIFIER=$?
if [ $ZERO = $VERIFIER ]
then
echo "Service was successfully started"
else
echo "Failed to start service"
fi
fi
echo
}
# Stop the MATH
stop() {
echo "Stopping MATH..."
#Verify if the service is running
$PGREP -f MATH > /dev/null
VERIFIER=$?
if [ $ZERO = $VERIFIER ]
then
#Kill the pid of Java with the service name
kill -9 $($PGREP -f MATH)
#Sleep time before the service verification
sleep 10
#Verify if the service is running
$PGREP -f MATH > /dev/null
VERIFIER=$?
if [ $ZERO = $VERIFIER ]
then
echo "Failed to stop service"
else
echo "Service was successfully stopped"
fi
else
echo "The service is already stopped"
fi
echo
}
# Verify the status of MATH
status() {
echo "Checking status of MATH..."
#Verify if the service is running
$PGREP -f MATH > /dev/null
VERIFIER=$?
if [ $ZERO = $VERIFIER ]
then
echo "Service is running"
else
echo "Service is stopped"
fi
echo
}
# Main logic
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status
;;
restart|reload)
stop
start
;;
*)
echo $"Usage: $0 {start|stop|status|restart|reload}"
exit 1
esac
exit 0
Le moyen le plus simple consiste à utiliser supervisord
. S'il vous plaît voir les détails complets ici: http://supervisord.org/
Plus d'informations:
À partir de Application Spring Boot en tant que service , je peux recommander l'application supervisord
basée sur Python. Voir cette question de débordement de pile pour plus d'informations. C'est vraiment simple à mettre en place.
Vous pouvez utiliser Thrift server ou JMX pour communiquer avec votre service Java.
Pour exécuter le code Java en tant que démon (service), vous pouvez écrire un stub basé sur JNI.
http://jnicookbook.owsiak.org/recipe-no-022/
pour un exemple de code basé sur JNI. Dans ce cas, vous démonalisez le code qui a été lancé en tant que Java et la boucle principale est exécutée en C. Mais il est également possible de placer la boucle de service principale du démon dans Java.
https://github.com/mkowsiak/jnicookbook/tree/master/recipeNo029
Amusez-vous avec JNI!
D'autres réponses font du bon travail en donnant des scripts personnalisés et des configurations en fonction de votre plate-forme. En plus de ceux-ci, voici les programmes matures et spéciaux que je connais:
Cependant, une fois commencé, je ne sais pas comment y accéder pour l'arrêter
Vous pouvez écrire un script d'arrêt simple qui écrit pour votre processus Java, extrait le PID et appelle kill sur celui-ci. Ce n'est pas compliqué, mais c'est simple ... Un début comme ça peut être utile au début:
#!/bin/bash
PID = ps ax | grep "name of your app" | cut -d ' ' -f 1
kill $PID
From Guide de référence du démarrage du printemps
Installation en tant que service init.d (System V)
Reliez simplement jar le fichier jar à
init.d
pour prendre en charge les commandes standardstart
,stop
,restart
etstatus
. En supposant qu'une application Spring Boot soit installée dans/var/myapp, pour installer une application Spring Boot en tant que service init.d, créez simplement un lien symbolique:$ Sudo ln -s /var/myapp/myapp.jar /etc/init.d/myapp
Une fois installé, vous pouvez démarrer et arrêter le service de la manière habituelle. Par exemple, sur un système basé sur Debian:
$ service myapp start
Si votre application ne parvient pas à démarrer, vérifiez si le fichier journal écrit dans
/var/log/<appname>.log
contient des erreurs.
Poursuivez votre lecture pour savoir comment sécuriser un service déployé.
Après avoir procédé comme prévu, j'ai découvert que mon service ne pouvait pas démarrer avec ce message d'erreur dans les journaux: start-stop-daemon: option non reconnue --no-close . Et j'ai réussi à le réparer en créant un fichier de configuration /var/myapp/myapp.conf
avec le contenu suivant
USE_START_STOP_DAEMON=false
Il est possible d’exécuter la guerre en tant que service Linux et vous pouvez forcer le fichier pom.xml à être forcé avant l’emballage, car certaines distributions risquent de ne pas être reconnues en mode automatique. Pour ce faire, ajoutez la propriété suivante à l’intérieur du plug-in spring-boot-maven-plugin.
<embeddedLaunchScriptProperties>
<mode>service</mode>
</embeddedLaunchScriptProperties>
Ensuite, configurez votre init.d avec:
ln -s myapp.war /etc/init.d/myapp
et vous pourrez courir
service myapp start|stop|restart
Il existe de nombreuses autres options que vous pouvez trouver dans Documentation Spring Boot , y compris le service Windows.