No Spring Boot Document, eles disseram que 'Cada SpringApplication registrará um gancho de desligamento com a JVM para garantir que o ApplicationContext seja fechado normalmente na saída.'
Quando clico ctrl+c
no comando shell, o aplicativo pode ser encerrado normalmente. Se eu executar o aplicativo em uma máquina de produção, tenho que usar o comando
java -jar ProApplicaton.jar
. Mas não consigo fechar o terminal shell, caso contrário, o processo será fechado.
Se eu executar o comando como nohup java -jar ProApplicaton.jar &
, não posso usar ctrl+c
para desligá-lo normalmente.
Qual é a maneira correta de iniciar e interromper um aplicativo Spring Boot no ambiente de produção?
linux
spring
spring-boot
Chris
fonte
fonte
kill -SIGTERM <PID>
deve resolver.Respostas:
Se estiver usando o módulo atuador, você pode desligar o aplicativo via
JMX
ouHTTP
se o terminal estiver habilitado.adicionar a
application.properties
:O seguinte URL estará disponível:
/actuator/shutdown
- Permite que o aplicativo seja encerrado normalmente (não habilitado por padrão).Dependendo de como um endpoint é exposto, o parâmetro confidencial pode ser usado como uma dica de segurança.
Por exemplo, endpoints sensíveis exigirão um nome de usuário / senha quando forem acessados
HTTP
(ou simplesmente desativados se a segurança da web não estiver ativada).Da documentação de inicialização do Spring
fonte
Aqui está outra opção que não exige que você altere o código ou exponha um endpoint de desligamento. Crie os scripts a seguir e use-os para iniciar e interromper seu aplicativo.
start.sh
Inicia seu aplicativo e salva a id do processo em um arquivo
stop.sh
Para seu aplicativo usando o ID de processo salvo
start_silent.sh
Se você precisar iniciar o aplicativo usando ssh de uma máquina remota ou um pipeline de CI, use este script para iniciar seu aplicativo. Usar start.sh diretamente pode deixar o shell travar.
Depois, por exemplo. re / implantando seu aplicativo, você pode reiniciá-lo usando:
fonte
nohup
, pode apenas mesclar os comandosQuanto à resposta de @Jean-Philippe Bond,
aqui está um exemplo rápido do maven para o usuário do maven configurar o endpoint HTTP para desligar um aplicativo da web de inicialização do spring usando spring-boot-starter-atuator para que você possa copiar e colar:
1.Maven pom.xml:
2.application.properties:
Todos os endpoints estão listados aqui :
3. Envie um método de postagem para desligar o aplicativo:
Nota de segurança:
se você precisa do método de desligamento protegido por autenticação, você também pode precisar
configurar detalhes :
fonte
server.contextPath=/appName
em meu application.properties, agora o comando para desligar seria:curl -X POST localhost:8080/appName/shutdown
Espero que possa ajudar alguém. Tive que lutar muito por causa desse erro.endpoints.shutdown.enabled=true management.security.enabled=false
.Você pode fazer o aplicativo springboot gravar o PID em um arquivo e pode usar o arquivo pid para parar ou reiniciar ou obter o status usando um script bash. Para gravar o PID em um arquivo, registre um ouvinte para SpringApplication usando ApplicationPidFileWriter conforme mostrado abaixo:
Em seguida, escreva um script bash para executar o aplicativo Spring Boot. Referência .
Agora você pode usar o script para iniciar, parar ou reiniciar.
fonte
Todas as respostas parecem não perceber o fato de que você pode precisar concluir alguma parte do trabalho de maneira coordenada durante o desligamento normal (por exemplo, em um aplicativo corporativo).
@PreDestroy
permite que você execute o código de desligamento nos beans individuais. Algo mais sofisticado ficaria assim:fonte
Não exponho nenhum endpoint e inicio ( com nohup em segundo plano e sem arquivos de saída criados por meio de nohup ) e paro com script de shell (com KILL PID graciosamente e force o kill se o aplicativo ainda estiver em execução após 3 minutos ). Acabei de criar o jar executável e usar o gravador de arquivo PID para escrever o arquivo PID e armazenar Jar e Pid na pasta com o mesmo nome do nome do aplicativo e os scripts de shell também têm o mesmo nome com start e stop no final. Eu também chamo isso de script de parada e script de início via jenkins pipeline. Sem problemas até agora. Funcionando perfeitamente para 8 aplicativos (scripts muito genéricos e fáceis de aplicar para qualquer aplicativo).
Classe Principal
YML FILE
Aqui está o script de início (start-appname.sh):
Aqui está o script de parada (stop-appname.sh):
fonte
Spring Boot forneceu vários ouvintes de aplicativo enquanto tentava criar o contexto do aplicativo, um deles é ApplicationFailedEvent. Podemos usar para saber se o contexto do aplicativo foi inicializado ou não.
Adicione a classe de ouvinte acima a SpringApplication.
fonte
A partir do Spring Boot 2.3 e posterior, há um mecanismo de desligamento normal integrado .
Antes do Spring Boot 2.3 , não há nenhum mecanismo de desligamento normal pronto para uso. Alguns iniciadores de boot com mola fornecem esta funcionalidade:
Eu sou o autor do nr. 1. O starter é denominado "Hiato para a Spring Boot". Ele funciona no nível do balanceador de carga, ou seja, simplesmente marca o serviço como OUT_OF_SERVICE, não interferindo no contexto do aplicativo de forma alguma. Isso permite fazer um desligamento normal e significa que, se necessário, o serviço pode ser retirado de serviço por algum tempo e, em seguida, restaurado. A desvantagem é que isso não para a JVM, você terá que fazer isso com o
kill
comando. Como eu executo tudo em contêineres, isso não é grande coisa para mim, porque terei que parar e remover o contêiner de qualquer maneira.Os números 2 e 3 são mais ou menos baseados neste post de Andy Wilkinson. Eles funcionam unilateralmente - uma vez acionados, eles eventualmente fecham o contexto.
fonte
SpringApplication registra implicitamente um gancho de encerramento com a JVM para garantir que ApplicationContext seja fechado normalmente na saída. Isso também chamará todos os métodos de bean anotados com
@PreDestroy
. Isso significa que não temos que usar explicitamente oregisterShutdownHook()
método de aConfigurableApplicationContext
em um aplicativo de inicialização, como temos que fazer no aplicativo spring core.fonte
@PostConstruct
e@PreDestroy
usei os atributosinitMethod
edestroyMethod
na@Bean
anotação. Portanto, para este exemplo:@Bean(initMethod="init", destroyMethod="destroy")
.@PreDestroy
poucos desenvolvedores podem não saber é que esses métodos são chamados apenas para beans com escopo Singleton. Os desenvolvedores precisam gerenciar a parte de limpeza do ciclo de vida do feijão para outros escoposExistem várias maneiras de encerrar um aplicativo Spring. Uma é chamar close () no
ApplicationContext
:Sua pergunta sugere que você deseja fechar seu aplicativo fazendo
Ctrl+C
, que é freqüentemente usado para encerrar um comando. Nesse caso...O uso
endpoints.shutdown.enabled=true
não é a melhor receita. Isso significa que você expõe um ponto de extremidade para encerrar seu aplicativo. Portanto, dependendo do seu caso de uso e do seu ambiente, você terá que protegê-lo ...Ctrl+C
deve funcionar muito bem no seu caso. Presumo que o seu problema seja causado pelo E comercial (&) Mais explicação:Um contexto de aplicativo Spring pode ter registrado um gancho de encerramento com o tempo de execução da JVM. Consulte a documentação do ApplicationContext .
Não sei se o Spring Boot configura este gancho automaticamente como você disse. Eu suponho que sim.
Ativado
Ctrl+C
, seu shell envia umINT
sinal para o aplicativo em primeiro plano. Significa "interrompa sua execução". O aplicativo pode capturar este sinal e fazer a limpeza antes de seu término (o gancho registrado pelo Spring) ou simplesmente ignorá-lo (ruim).nohup
é o comando que executa o seguinte programa com uma armadilha para ignorar o sinal HUP. O HUP é usado para encerrar o programa quando você desliga (feche sua conexão ssh, por exemplo). Além disso, ele redireciona as saídas para evitar que o seu programa bloqueie em um TTY desaparecido.nohup
NÃO ignora o sinal INT. Portanto, NÃO impedeCtrl+C
trabalho.Presumo que o seu problema seja causado pelo "e" comercial (&), não pelo nohup.
Ctrl+C
envia um sinal para os processos de primeiro plano. O E comercial faz com que seu aplicativo seja executado em segundo plano. Uma solução: façaUse
kill -9
oukill -KILL
está incorreto porque o aplicativo (aqui a JVM) não pode interceptá-lo para encerrar normalmente.Outra solução é trazer de volta seu aplicativo em primeiro plano. Então
Ctrl+C
vai funcionar. Dê uma olhada no controle Bash Job, mais precisamente ativadofg
.fonte
Use o
exit()
método estático na classe SpringApplication para fechar seu aplicativo de inicialização de primavera normalmente.fonte
Spring Boot agora suporta desligamento normal (atualmente em versões de pré-lançamento, 2.3.0.BUILD-SNAPSHOT)
Você pode habilitá-lo com:
https://docs.spring.io/spring-boot/docs/2.3.0.BUILD-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-graceful-shutdown
fonte
Se você estiver usando o maven, poderá usar o plugin Maven App assembler .
O daemon mojo (que incorpora JSW ) produzirá um script de shell com o argumento start / stop. O
stop
desligamento vontade / matar graciosamente sua aplicação Primavera.O mesmo script pode ser usado para usar seu aplicativo maven como um serviço Linux.
fonte
Se você estiver em um ambiente Linux, tudo o que você precisa fazer é criar um link simbólico para o seu arquivo .jar de dentro de /etc/init.d/
Então você pode iniciar o aplicativo como qualquer outro serviço
Para fechar o aplicativo
Dessa forma, o aplicativo não será encerrado quando você sair do terminal. E o aplicativo será encerrado normalmente com o comando de parada.
fonte