In the Spring Boot Document, they said that 'Each SpringApplication will register a shutdown hook with the JVM to ensure that the ApplicationContext is closed gracefully on exit.'
When I click ctrl+c
on the shell command, the application can be shutdown gracefully. If I run the application in a production machine, I have to use the command
java -jar ProApplicaton.jar
. But I can't close the shell terminal, otherwise it will close the process.
If I run command like nohup java -jar ProApplicaton.jar &
, I can't use ctrl+c
to shutdown it gracefully.
What is the correct way to start and stop a Spring Boot Application in the production environment?
If you are in a linux environment all you have to do is to create a symlink to your .jar file from inside /etc/init.d/
Then you can start the application like any other service
To close the application
This way, application will not terminate when you exit the terminal. And application will shutdown gracefully with stop command.
If you are using the actuator module, you can shutdown the application via
JMX
orHTTP
if the endpoint is enabled (addendpoints.shutdown.enabled=true
to yourapplication.properties
file)./shutdown
- Allows the application to be gracefully shutdown (not enabled by default).Depending on how an endpoint is exposed, the sensitive parameter may be used as a security hint. For example, sensitive endpoints will require a username/password when they are accessed over
HTTP
(or simply disabled if web security is not enabled).From the Spring boot documentation
SpringApplication implicitly registers a shutdown hook with the JVM to ensure that ApplicationContext is closed gracefully on exit. That will also call all bean methods annotated with
@PreDestroy
. That means we don't have to explicitly use theregisterShutdownHook()
method of aConfigurableApplicationContext
in a boot application, like we have to do in spring core application.Here is another option that does not require you to change the code or exposing a shut-down endpoint. Create the following scripts and use them to start and stop your app.
start.sh
Starts your app and saves the process id in a file
stop.sh
Stops your app using the saved process id
start_silent.sh
If you need to start the app using ssh from a remote machine or a CI pipeline then use this script instead to start your app. Using start.sh directly can leave the shell to hang.
After eg. re/deploying your app you can restart it using:
They are many ways to shutdown a spring application. One is to call close() on the
ApplicationContext
:Your question suggest you want to close your application by doing
Ctrl+C
, that is frequently used to terminate a command. In this case...Use
endpoints.shutdown.enabled=true
is not the best recipe. It means you expose an end-point to terminate your application. So, depending on your use case and your environment, you will have to secure it...Ctrl+C
should work very well in your case. I assume your issue is caused by the ampersand (&) More explanation:A Spring Application Context may have register a shutdown hook with the JVM runtime. See ApplicationContext documentation.
I don't know if Spring Boot configure this hook automatically as you said. I assume it is.
On
Ctrl+C
, your shell sends anINT
signal to the foreground application. It means "please interrupt your execution". The application can trap this signal and do cleanup before its termination (the hook registered by Spring), or simply ignore it (bad).nohup
is command that execute the following program with a trap to ignore the HUP signal. HUP is used to terminate program when you hang up (close your ssh connexion for example). Moreover it redirects outputs to avoid that your program blocks on a vanished TTY.nohup
does NOT ignore INT signal. So it does NOT preventCtrl+C
to work.I assume your issue is caused by the ampersand (&), not by nohup.
Ctrl+C
sends a signal to the foreground processes. The ampersand causes your application to be run in background. One solution: doUse
kill -9
orkill -KILL
is bad because the application (here the JVM) cannot trap it to terminate gracefully.Another solution is to bring back your application in foreground. Then
Ctrl+C
will work. Have a look on Bash Job control, more precisely onfg
.All of the answers seem to be missing the fact that you may need to complete some portion of work in coordinated fashion during graceful shutdown (for example, in an enterprise application).
@PreDestroy
allows you to execute shutdown code in the individual beans. Something more sophisticated would look like this: