ejecutar - Ejecuta una aplicación Java como un servicio en Linux
java jar as service linux (14)
Escribí una aplicación de servidor Java que se ejecuta en una solución Linux alojada virtual estándar. La aplicación se ejecuta todo el tiempo escuchando conexiones de socket y creando nuevos manejadores para ellas. Es una implementación del lado del servidor para una aplicación cliente-servidor.
La forma en que lo comienzo es incluyéndolo en el script de inicio rc.local del servidor. Sin embargo, una vez que comencé, no sé cómo acceder para detenerlo y si quiero instalar una actualización, entonces tengo que reiniciar el servidor para reiniciar la aplicación.
En una PC con Windows, para este tipo de aplicación podría crear un servicio de Windows y luego puedo detenerlo e iniciarlo como yo quiera. ¿Hay algo así en una caja de Linux para que si comienzo esta aplicación puedo detenerlo y reiniciarlo sin hacer un reinicio completo del servidor?
Mi aplicación se llama WebServer.exe. Se inicia en el inicio del servidor incluyéndolo en mi rc.local como tal:
java -jar /var/www/vhosts/myweb.com/phpserv/WebServer.jar &
Soy un poco novato en Linux, así que cualquier ejemplo sería apreciado con cualquier publicación. Sin embargo, tengo SSH y acceso FTP completo al cuadro para instalar las actualizaciones y acceder a un panel de Plesk.
Sin embargo, una vez que comencé, no sé cómo acceder para detenerlo
Puede escribir un simple script de detención que greps para su proceso java, extrae el PID y las llamadas lo matan. No es elegante, pero es sencillo. Algo así puede ser de ayuda como punto de partida:
#!/bin/bash
PID = ps ax | grep "name of your app" | cut -d '' '' -f 1
kill $PID
Aquí hay un script de shell de muestra (asegúrese de reemplazar el nombre de MATH con el nombre de su aplicación):
#!/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
Desde la aplicación Spring Boot como un servicio , puedo recomendar la aplicación de supervisord
basada en Python. Mira esa pregunta de desbordamiento de pila para más información. Es muy sencillo de configurar.
El script de inicio de servicio de Linux se almacena en /etc/init.d
. Puede copiar y personalizar el archivo /etc/init.d/skeleton
, y luego llamar
service [yourservice] start|stop|restart
ver http://www.ralfebert.de/blog/java/debian_daemon/ . Es para Debian (por lo tanto, Ubuntu también) pero se ajusta más a la distribución.
Escribí otro envoltorio simple aquí:
#!/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
Puede seguir un tutorial completo para init.d here y para systemd (ubuntu 16+) here
Si necesita el registro de salida, reemplace el 2
nohup java -jar $PATH_TO_JAR /tmp 2>> /dev/null >> /dev/null &
líneas para
nohup java -jar $PATH_TO_JAR >> myService.out 2>&1&
La forma más fácil es usar supervisord
. Por favor, consulte todos los detalles aquí: http://supervisord.org/
Más información:
Otra alternativa, que también es bastante popular es la envoltura de servicios de Java . Esto también es bastante popular en la comunidad de OSS.
Otras respuestas hacen un buen trabajo al proporcionar scripts personalizados y configuraciones según su plataforma. Además de esos, aquí están los programas maduros y de propósito especial que conozco:
- JSW de TanukiSoftware
- YAJSW es un clon de código abierto de los anteriores. Está escrito en Java, y es un proceso de niñera que administra el proceso secundario (su código) de acuerdo con las configuraciones. Funciona en Windows / Linux.
- JSVC es una aplicación nativa. También es un proceso de niñera, pero invoca a su aplicación hija a través del JNI, en lugar de hacerlo como un subproceso.
Para ejecutar el código Java como daemon (servicio), puede escribir el código base JNI.
http://jnicookbook.owsiak.org/recipe-no-022/
para un código de muestra que se basa en JNI. En este caso, demoniza el código que se inició como Java y el bucle principal se ejecuta en C. Pero también es posible poner main, daemon''s, service loop dentro de Java.
https://github.com/mkowsiak/jnicookbook/tree/master/recipeNo029
¡Diviértete con JNI!
Puede usar el servidor Thrift o JMX para comunicarse con su servicio Java.
Tal vez no sea la mejor solución de desarrollo de operaciones, pero es buena para el uso general de un servidor para una fiesta lan o similar.
Utilice la screen
para ejecutar su servidor y luego desconectarlo antes de cerrar la sesión, esto mantendrá el proceso en ejecución, luego podrá volver a conectarlo en cualquier momento.
Flujo de trabajo:
Comienza una pantalla: screen
Inicie su servidor: java -jar minecraft-server.jar
Separar presionando: Ctl-a
, d
Vuelva a conectar: screen -r
Más información aquí: https://www.gnu.org/software/screen/manual/screen.html
También me refiero a la aplicación Spring Boot como un servicio , me gustaría ir a la versión systemd
, ya que es la más fácil, menos detallada y mejor integrada en las distribuciones modernas (e incluso las no tan modernas como CentOS 7.x).
Una solución simple es crear un script start.sh que ejecute Java a través de nohup y luego almacene el PID en un archivo:
nohup java -jar myapplication.jar > log.txt 2> errors.txt < /dev/null &
PID=$!
echo $PID > pid.txt
Luego, su stop script stop.sh leerá el PID del archivo y matará la aplicación:
PID=$(cat pid.txt)
kill $PID
Por supuesto, he pid.txt
algunos detalles, como verificar si el proceso existe y eliminar pid.txt
si ya pid.txt
.
Desde Spring Boot Reference Guide
Instalación como un servicio init.d (Sistema V)
Simplemente enlace simbólicamente el
init.d
jar ainit.d
para admitir los comandos estándar destart
,stop
,restart
ystatus
. Suponiendo que tiene una aplicación Spring Boot instalada en / var / myapp, para instalar una aplicación Spring Boot como servicio init.d simplemente cree un enlace simbólico:
$ sudo ln -s /var/myapp/myapp.jar /etc/init.d/myapp
Una vez instalado, puede iniciar y detener el servicio de la manera habitual. Por ejemplo, en un sistema basado en Debian:
$ service myapp start
Si su aplicación no se inicia, verifique el archivo de registro escrito en
/var/log/<appname>.log
para ver si hay errores.
Continúe leyendo para saber cómo proteger un servicio desplegado.
Después de hacer lo que he escrito, descubrí que mi servicio no puede comenzar con este mensaje de error en los registros: start-stop-daemon: opción no reconocida --no-close . Y logré solucionarlo creando un archivo de configuración /var/myapp/myapp.conf
con el siguiente contenido
USE_START_STOP_DAEMON=false