Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent Spring Boot application closing until all current requests are finished

We have a Spring Boot (2.0.4) application exposing a number of endpoints, one of which enables clients to retrieve sometimes very large files (~200 GB). The application is exposed in a Pod via a Kubernetes deployment configured with the rolling-update strategy.

When we update our deployment by setting the image to the latest version the pods get destroyed and new ones spun up. Our service provision is seamless for new requests. However current requests can and do get severed and this can be annoying for clients in the middle of downloading very large files.

We can configure Container Lifecycle Pre-Stop hooks in our deployment spec to inject a pause before sending shutdown signals to the app via it's PID. This helps prevent any new traffic going to pods which have been set to Terminate. Is there a way to then pause the application shutdown process until all current requests have been completed (this may take tens of minutes)?

Here's what we have tried from within the Spring Boot application:

  • Implementing a shutdown listener which intercepts ContextCloseEvents; unfortunately we can't reliably retrieve a list of active requests. Any Actuator metrics which may have been useful are unavailable at this stage of the shutdown process.

  • Count active sessions by implementing a HttpSessionListener and overriding sessionCreated/Destroy methods to update a counter. This fails because the methods are not invoked on a separate thread so always report the same value in the shutdown listener.

Any other strategy we should try? From within the app itself, or the container, or directly through Kubernetes resource descriptors? Advice/Help/Pointers would be much appreciated.

Edit: We manage the cluster so we're only trying to mitigate service outages to currently connected clients during a managed update of our deployment via a modified pod spec

like image 361
slowko Avatar asked May 17 '19 15:05

slowko


People also ask

How do you stop Spring Boot gracefully?

Close ApplicationContext Another option to shutdown Spring Boot application is to close Spring ApplicationContext using SpringApplication . SpringApplication#run(String…) method returns ApplicationContext as a < ConfigurableApplicationContext. We can use close() method to close ApplicationContext programmatically.

What is the preferred way to close an application context does Spring Boot do this for you?

For Spring Boot applications, context will be closed automatically. And this is done by registering the shutdown hook for the CLI applications.

What is terminationGracePeriodSeconds?

concept terminationgraceperiodsecond in category kubernetesThe application is given a certain amount of time to terminate. This time can be configured using the terminationGracePeriodSeconds field in the pod's spec and defaults to 30 seconds.


1 Answers

You could increase the terminationGracePeriodSeconds, the default is 30 seconds. But unfortunately, there's nothing to prevent a cluster admin from force deleting your pod, and there's all sorts of reasons the whole node could go away.

like image 78
Joshua Oliphant Avatar answered Oct 06 '22 00:10

Joshua Oliphant