Graceful Shutdown of vert.x application

1,922 views
Skip to first unread message

Subhasis Dash

unread,
Feb 4, 2021, 3:29:08 AM2/4/21
to vert.x
How to shutdown vert.x application gracefully from kubernetes, 
1. Is there a command we can add in the prestop hook?
2. Is there some logs to tell us a graceful shutdown is initiated ?
3. can we override some methods and add some logs to check is shutdown is happening properly? 
we tried to override beforeStoppingVertx and afterStoppingVertx  of Launcher class and added some logs but none are getting printed during shutdown

Please answer above questions and suggest other ways to initiate a graceful shut down for vertx app from kubernetes

Christian Damsgaard

unread,
Feb 4, 2021, 4:28:39 AM2/4/21
to ve...@googlegroups.com
Hi Subhasis,

Depending on your type of application (JEE / Spring / SpringBoot / plain) you can consider adding a JVM shutdown hook: Runtime.getRuntime().addShutdownHook(...)

The shutdown hook handle code is executed on a separate thread once invoked and the shutdown of the JVM will not complete before your code has returned.

In the handle code you can get a reference to your vertx instance and invoke the close(Handler<AsyncResult<Void>> completionHandler) on it with a call back to a CompletableFuture to be completed once Vertx has been closed.

A sample from some code of mine:

public void destroyVertx() {
if (vertx == null) {
throw new IllegalStateException("Vertx has not been initialized!");
}

log.info("Closing vertx");

// Create a completable future for the purpose of being able to block the thread
final CompletableFuture<Void> completableFuture = new CompletableFuture<>();

// Create a close completion handler which completes the completable future above
final Handler<AsyncResult<Void>> closeCompletionHandler =
result -> {
if (!result.failed()) {
completableFuture.complete(null);
} else {
completableFuture.completeExceptionally(result.cause());
}
};

// Async close with reference to completion handler
this.vertx.close(closeCompletionHandler);

try {
// Wait for the vertx to complete and pickup the result (could be an exception)
completableFuture.get(shutdownTimeout, shutdownTimeoutUnit);

log.info("Vertx was closed successfully");
} catch (final InterruptedException e) {
throw new IllegalStateException("Thread was interrupted while waiting to vertx instance to close!", e);
} catch (final ExecutionException e) {
log.error("An execution exception was caught while waiting to vertx instance to close!", e);
} catch (final TimeoutException e) {
log.error("An timeout exception was caught while waiting to vertx instance to close!", e);
}
}

Best regards
Christian

--
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/vertx/eace20ef-e80c-436d-b8ed-27c63f7b6df8n%40googlegroups.com.


--

Subhasis Dash

unread,
Feb 4, 2021, 5:34:34 AM2/4/21
to vert.x
Hi Christian,
I have tried adding a shutdown hook in afterStartingVertx method but it is never getting invoked as we don't see the logs getting printed, neither in Kubernetes cluster when we bring down a pod, nor when we stop the project in IDE's (eclipse, intellij)
sample code:
```
@Override public void afterStartingVertx(Vertx vertx) {  
LOG.info("Vertx started"); 
AppComponent appComponent = AppComponent.create(vertx);
Runtime.getRuntime().addShutdownHook(new Thread() { 
public void run() { 
LOG.info("Vertx is Closing Gracefully via the Shutdown Hook"); 
vertx.close(); } }); 
}
```

Christian Damsgaard

unread,
Feb 4, 2021, 5:43:09 AM2/4/21
to ve...@googlegroups.com
Hi Subhasis,

You should use the close method with call back and wait for it.

Please read this guide with respect to the shutdown hook: https://www.baeldung.com/jvm-shutdown-hooks

We are running our application in Openshift and the hook is invoked when the application is asked to terminate.

Please note that other components (Spring Boot) might have registered shutdown hooks as well.

Best regards
Christian


Jesse Englert

unread,
Jun 2, 2021, 2:16:40 PM6/2/21
to vert.x
Subhasis,

The reason you may not be seeing your log message during shutdown may be due to your logger framework registering its own JVM shutdown hook that will prevent logging from occurring. Since shutdown hooks are all run concurrently, their order is non-deterministic. You can try using System.out.println("...") instead in your shutdown code. Java Util Logging (JUL) registers a shutdown hook for example:

private LogManager(Void checked) {
  // Add a shutdown hook to close the global handlers.
  try {
    Runtime.getRuntime().addShutdownHook(new Cleaner());
  } catch (IllegalStateException e) {
    // If the VM is already shutting down,
    // We do not need to register shutdownHook.
  }
}
    
// This private class is used as a shutdown hook.
// It does a "reset" to close all open handlers.
private class Cleaner extends Thread {
  private Cleaner() {
    super(null, null, "Logging-Cleaner", 0, false);
            /* Set context class loader to null in order to avoid
             * keeping a strong reference to an application classloader.
             */
    this.setContextClassLoader(null);
  }

  @Override
  public void run() {
    // This is to ensure the LogManager.<clinit> is completed
    // before synchronized block. Otherwise deadlocks are possible.
    LogManager mgr = manager;

    // set globalHandlersState to STATE_SHUTDOWN atomically so that
    // no attempts are made to (re)initialize the handlers or (re)read
    // the configuration again. This is terminal state.
    configurationLock.lock();
    globalHandlersState = STATE_SHUTDOWN;
    configurationLock.unlock();

    // Do a reset to close all active handlers.
    reset();
  }
}

Reply all
Reply to author
Forward
0 new messages