En el Spring Boot Document, dijeron que 'Cada SpringApplication registrará un gancho de apagado con la JVM para garantizar que ApplicationContext se cierre correctamente al salir'.
Cuando hago clic ctrl+c
en el comando de shell, la aplicación se puede cerrar sin problemas. Si ejecuto la aplicación en una máquina de producción, tengo que usar el comando
java -jar ProApplicaton.jar
. Pero no puedo cerrar la terminal de shell, de lo contrario cerrará el proceso.
Si ejecuto un comando como nohup java -jar ProApplicaton.jar &
, no puedo usarlo ctrl+c
para apagarlo con gracia.
¿Cuál es la forma correcta de iniciar y detener una aplicación Spring Boot en el entorno de producción?
linux
spring
spring-boot
Chris
fuente
fuente
kill -SIGTERM <PID>
debería funcionar.Respuestas:
Si está utilizando el módulo actuador, puede apagar la aplicación a través de
JMX
oHTTP
si el punto final está habilitado.agregar a
application.properties
:La siguiente URL estará disponible:
/actuator/shutdown
- Permite que la aplicación se cierre correctamente (no habilitado de forma predeterminada).Dependiendo de cómo se exponga un punto final, el parámetro sensible puede usarse como una sugerencia de seguridad.
Por ejemplo, los puntos finales sensibles requerirán un nombre de usuario / contraseña cuando se acceda a ellos
HTTP
(o simplemente deshabilitados si la seguridad web no está habilitada).De la documentación de Spring Boot
fuente
Aquí hay otra opción que no requiere que cambie el código o exponga un punto final apagado. Cree los siguientes scripts y utilícelos para iniciar y detener su aplicación.
start.sh
Inicia su aplicación y guarda la identificación del proceso en un archivo
stop.sh
Detiene su aplicación usando el ID de proceso guardado
start_silent.sh
Si necesita iniciar la aplicación usando ssh desde una máquina remota o una canalización de CI, utilice este script en su lugar para iniciar su aplicación. Usar start.sh directamente puede dejar el shell colgando.
Después, por ejemplo. re / implementando su aplicación puede reiniciarla usando:
fuente
nohup
, puede combinar los comandosEn cuanto a la respuesta de @ Jean-Philippe Bond,
aquí hay un ejemplo rápido de maven para que el usuario de maven configure el punto final HTTP para apagar una aplicación web de arranque de primavera usando spring-boot-starter-actuator para que pueda copiar y pegar:
1.Maven pom.xml:
2.aplicaciones.propiedades:
Todos los puntos finales se enumeran aquí :
3.Envíe un método de publicación para cerrar la aplicación:
Nota de seguridad:
si necesita el método de apagado protegido por autenticación, también puede necesitar
configurar detalles :
fuente
server.contextPath=/appName
en mi application.properties Entonces, el comando de apagado se convertiría en:curl -X POST localhost:8080/appName/shutdown
Espero que pueda ayudar a alguien. Tuve que luchar mucho por este error.endpoints.shutdown.enabled=true management.security.enabled=false
.Puede hacer que la aplicación springboot escriba el PID en un archivo y puede usar el archivo pid para detener o reiniciar u obtener el estado usando un script bash. Para escribir el PID en un archivo, registre un oyente en SpringApplication usando ApplicationPidFileWriter como se muestra a continuación:
Luego, escriba un script bash para ejecutar la aplicación Spring Boot. Referencia .
Ahora puede utilizar el script para iniciar, detener o reiniciar.
fuente
Todas las respuestas parecen no tener en cuenta el hecho de que es posible que deba completar una parte del trabajo de manera coordinada durante el cierre ordenado (por ejemplo, en una aplicación empresarial).
@PreDestroy
le permite ejecutar código de apagado en los beans individuales. Algo más sofisticado se vería así:fuente
No expongo ningún punto final y comienzo ( con nohup en segundo plano y sin los archivos creados a través de nohup ) y me detengo con el script de shell (con KILL PID con gracia y fuerzo la eliminación si la aplicación aún se está ejecutando después de 3 minutos ). Acabo de crear jar ejecutable y uso el escritor de archivos PID para escribir el archivo PID y almacenar Jar y Pid en la carpeta con el mismo nombre que el nombre de la aplicación y los scripts de shell también tienen el mismo nombre con inicio y parada al final. También llamo a estos script de parada y script de inicio a través de la tubería de jenkins. Hasta ahora no hay problemas. Funciona perfectamente para 8 aplicaciones (scripts muy genéricos y fáciles de aplicar para cualquier aplicación).
Clase principal
ARCHIVO YML
Aquí está el script de inicio (start-appname.sh):
Aquí está el script de detención (stop-appname.sh):
fuente
Spring Boot proporcionó varios oyentes de aplicaciones mientras intentaba crear el contexto de la aplicación, uno de ellos es ApplicationFailedEvent. Podemos utilizar para saber si el contexto de la aplicación se ha inicializado o no.
Agregue a la clase de escucha anterior a SpringApplication.
fuente
A partir de Spring Boot 2.3 y versiones posteriores, hay un elegante mecanismo de apagado integrado .
Antes de Spring Boot 2.3 , no hay un mecanismo de apagado elegante listo para usar. Algunos arrancadores de arranque de primavera proporcionan esta funcionalidad:
Soy el autor del nr. 1. El motor de arranque se llama "Hiatus for Spring Boot". Funciona en el nivel del equilibrador de carga, es decir, simplemente marca el servicio como OUT_OF_SERVICE, sin interferir con el contexto de la aplicación de ninguna manera. Esto permite hacer un cierre ordenado y significa que, si es necesario, el servicio se puede poner fuera de servicio durante algún tiempo y luego volver a la vida. La desventaja es que no detiene la JVM, tendrás que hacerlo con el
kill
comando. Como ejecuto todo en contenedores, esto no fue un gran problema para mí, porque tendré que detenerme y retirar el contenedor de todos modos.Los números 2 y 3 se basan más o menos en esta publicación de Andy Wilkinson. Funcionan en un solo sentido: una vez que se activan, finalmente cierran el contexto.
fuente
SpringApplication registra implícitamente un gancho de cierre con la JVM para garantizar que ApplicationContext se cierre correctamente al salir. Eso también llamará a todos los métodos bean anotados con
@PreDestroy
. Eso significa que no tenemos que usar explícitamente elregisterShutdownHook()
método de aConfigurableApplicationContext
en una aplicación de arranque, como tenemos que hacer en la aplicación Spring Core.fuente
@PostConstruct
y@PreDestroy
utilicé los atributosinitMethod
ydestroyMethod
dentro de la@Bean
anotación. Así que para este ejemplo:@Bean(initMethod="init", destroyMethod="destroy")
.@PreDestroy
algunos desarrolladores pueden no saber es que estos métodos solo se llaman para beans con alcance Singleton. Los desarrolladores deben administrar la parte de limpieza del ciclo de vida del bean para otros ámbitosHay muchas formas de cerrar una aplicación de primavera. Uno es llamar a close () en
ApplicationContext
:Su pregunta sugiere que desea cerrar su aplicación haciendo esto
Ctrl+C
, que se usa frecuentemente para terminar un comando. En este caso...El uso
endpoints.shutdown.enabled=true
no es la mejor receta. Significa que expone un punto final para finalizar su aplicación. Entonces, dependiendo de su caso de uso y su entorno, tendrá que protegerlo ...Ctrl+C
debería funcionar muy bien en tu caso. Supongo que su problema es causado por el signo comercial (&) Más explicación:Un contexto de aplicación Spring puede haber registrado un gancho de cierre con el tiempo de ejecución de JVM. Consulte la documentación de ApplicationContext .
No sé si Spring Boot configura este gancho automáticamente como dijiste. Asumo que lo es.
Encendido
Ctrl+C
, su shell envía unaINT
señal a la aplicación de primer plano. Significa "interrumpa su ejecución". La aplicación puede atrapar esta señal y hacer una limpieza antes de su terminación (el gancho registrado por Spring), o simplemente ignorarla (mal).nohup
Es un comando que ejecuta el siguiente programa con una trampa para ignorar la señal HUP. HUP se usa para terminar el programa cuando cuelga (cierre su conexión ssh, por ejemplo). Además, redirige las salidas para evitar que su programa se bloquee en un TTY desaparecido.nohup
NO ignora la señal INT. Entonces NO impideCtrl+C
que funcione.Supongo que su problema es causado por el ampersand (&), no por nohup.
Ctrl+C
envía una señal a los procesos en primer plano. El ampersand hace que su aplicación se ejecute en segundo plano. Una solución: hacerUse
kill -9
okill -KILL
es malo porque la aplicación (aquí la JVM) no puede atraparlo para terminar con gracia.Otra solución es volver a poner su aplicación en primer plano. Entonces
Ctrl+C
funcionará. Eche un vistazo a Bash Job control, más precisamente enfg
.fuente
Use el
exit()
método estático en la clase SpringApplication para cerrar su aplicación de arranque de primavera con gracia.fuente
Spring Boot ahora admite un apagado ordenado (actualmente en versiones preliminares, 2.3.0.BUILD-SNAPSHOT)
Puede habilitarlo con:
https://docs.spring.io/spring-boot/docs/2.3.0.BUILD-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-graceful-shutdown
fuente
Si está utilizando maven, puede utilizar el complemento del ensamblador de la aplicación Maven .
El demonio mojo (que incrusta JSW ) generará un script de shell con un argumento de inicio / detención. El
stop
apagará / matará elegantemente su aplicación Spring.El mismo script se puede usar para usar su aplicación maven como un servicio de Linux.
fuente
Si está en un entorno Linux, todo lo que tiene que hacer es crear un enlace simbólico a su archivo .jar desde dentro /etc/init.d/
Entonces puedes iniciar la aplicación como cualquier otro servicio
Para cerrar la aplicación
De esta forma, la aplicación no terminará cuando salga de la terminal. Y la aplicación se cerrará con gracia con el comando de parada.
fuente