Why is #PreDestroy being invoked - spring

I have a Spring boot app running in docker on ECS
I can see that my #PreDestory method is being invoked on my #Component classes (added to gracefully shutdown an ExecutorService) but even with Trace logging level set I cannot see why. Is there a way to add a shutdown hook that provides information as to what event caused the shutdown to occur.

Related

How to get notified in SpringBoot about an initiated shutdown

since its 2.3 release, SpringBoot has the feature called "graceful shutdown". When a certain signal is received by the JVM, SpringBoot executes some code (because it registers a callback within the JVM) so that the application is shut down gracefully.
In the course of the shutdown process, the application context is closed, traffic is not accepted anymore, beans get destroyed etc. This is described in this section of the SpringBoot docs and elsewhere.
My question is: is it possible to get notified about the fact that SpringBoot has initiated a shutdown? By "get notified" I mean (ideally) this: I want to have a bean which would be part of the application context. This bean should get a notification (one of its methods should be called or via events) when the shutdown is initiated but before any actions are taken in that direction. I.e. #PreDestroy and other lifecycle callbacks are too late IMO. My desired notification should come earlier (when the traffic is still accepted).
I could of course register my own callback within the JVM but it wouldn't look good and also I could not be sure whether my callback is executed before or after the SpringBoot's one.
Thank you for any hints.

Spring boot, Kotlin, Kafka and shutdown

I have a Spring boot / Kotlin application that has a Kafka listener embedded. I am programmatically shutting it down at some point by calling:
configurableApplicationContext.close()
However, Kafka listener does not shut down at that time and instead I get this:
Failed to shut down 1 bean with phase value 2147483547 within timeout of 30000: [org.springframework.kafka.config.internalKafkaListenerEndpointRegistry]
After that, the app shuts down as expected.
What do I need to do differently so it shuts down cleanly when requested?

spring-boot graceful shutdown

Is there a way in spring boot to control the graceful shutdown of the app.
I know that you can have #PreDestroy methods in beans but how can you control the ordering in which those #PreDestroy methods are called.
You can have multiple beans depending on each other will the shutdown of the context look for this dependency already and call the #PreDestroy methods in the right order or not?
For example what I would like to accomplish is:
1.) stop listening for new requests on rest endpoints
2.) prevent rabbit message listeners to accept new messages
3.) wait for all processing that has started before the shutdown but is not finished yet.
Spring-boot-2-3-0 has added support for graceful shutdown.
you can enable graceful shutdown by setting up server.shutdown=graceful property
To configure the timeout period you can use
spring.lifecycle.timeout-per-shutdown-phase=20s
spring boot documentation
If you can not upgrade to spring boot 2.3 then you can check below project
https://github.com/gesellix/graceful-shutdown-spring-boot

How to manually shutdown embedded Tomcat?

I'm trying to implement a graceful shutdown sequence for my Spring Boot application. For that I registered a custom shutdown hook with Runtime and disabled the one provided by Spring (SpringApplication.setRegisterShutdownHook(false)). From this custom shutdown hook I first would like to pause embedded Tomcat or the connectors and some other schedulers after which I manually invoke applicationContext.close() to shutdown the rest of the Spring application.
What is the best way to get access to the embedded Tomcat instance? I was fiddling around with TomcatEmbeddedServletContainerFactory but this does not seem to give me access to default connectors or EmbeddedServletContainer which has a stop method.
You can access the EmbeddedServletContainer from the EmbeddedWebApplicationContext (just inject that) and downcast it.

how can we use addShutdownHook in project?

i saw some code use ShutdownHook like this
Runtime.getRuntime().addShutdownHook(new Thread(){
ConfigurableApplicationContext.stop();
//close spring context;
threadpool.shutdownnow();
//close theadpool
});
is there anything useful to do like this?
i thought
when jvm exit ,maybe thread will be shutdown immediately
and spring context will close tooï¼›
what shall we do next when we need to call System.exit() ?
It really depends on your application and the lifecycle of your objects and those threads you appear to have outside of your context. If you are running the spring container inside a standalone java process, then trapping the shutdown hook like this is one way to do that. Another way is to have it listen on a tcp port and send a command to begin the shutdown process. If you are running in a web container like tomcat, then you should follow the standards on normal webapp shutdown, which Spring supports with Context Listeners.
I would also consider redesigning your app so that the threads are all managed with a bean that lives inside your spring container. For instance using a bean that is configured with directives (attributes) for start/stop methods and then that bean would use an Executor for thread pooling. This way, your shutdown is ONLY shutting down the Spring container, and Spring provides very good support for orderly shutdown of beans. One of those beans is your object holding the threads within the Executor. Its a much cleaner way than trying to integrate Spring beans with external threads.
Hope this helps.

Resources