I have built a batch job which is called from enterprise scheduler to access a light-4j microservice to perform some daily tasks. The batch job is a standalone application uses the light-4j client module to invoke the microservice.
A strange thing happens after the job is done. The main class does not exit automatically after the job is done. It looks like there are still some threads running that prevents the main class to exit. When I switch the light-4j Http2Client to Apache HttpClient, the main class exits gracefully. Am I doing something wrong?
Unlike other Http Client which is single-threaded. The light-4j Http2Client is using an event loop to handle multiple requests/responses asynchronously like the Undertow Server. This ensures the highest throughput and lowest latency; however, the event loop allocated a thread pool that won't be closed after the main thread is completed. This requires to call system.exit() to stop the JVM application. After that, all running threads from the application will be stopped.
Here is an example of standalone applications that uses Http2Client.
https://github.com/networknt/light-example-4j/blob/release/client/standalone/src/main/java/com/networknt/client/Http2ClientExample.java#L56
Related
I'm learning about threads and how threads work when building a web application.
As per my understanding the flow is as follows:
User sends Http request
Tomcat creates a thread running the controller.
Spring boot runs an async annotated method, that runs code on a seperate thread pool created by the spring boot app.
The tomcat thread is released until the async method is completed to handle more requests.
Am I correct in my understanding?
Does spring boot create its own thread pool to run async operations on freeing the main tomcat thread?
When the asynchronous method is called, the tomcat thread isn't "released" or "freed". It proceeds with the next instruction after the async method call and keeps on going (unless it does something like call get on a future returned by the async method so that it blocks until the future completes). Both threads execute concurrently.
It is true that Spring has its own separate threadpool that it uses for async methods. The Executor used is configurable, #Async takes the name of the executor as an argument so different methods can use different pools if needed. And Tomcat has a pool for its threads, of course.
I have a question, I am just starting on reactive programing and I am using quarkus. I made a demo with Panache hibernate reactive and one with SQL clients.
I want each of my rest apis to run on a different non blocking thread. With panache hibernate whenever I did a a blocking action I got a message about it and in the logs it showed me that the api was running o vertex event loop thread so everything was fine.
In Reactive clients everything runs on executor thread 0 does that mean my apis aren’t asynchonus(reactive) from input to output and when I run a blocking action non erros is showing.
Quarkus tries in a lot of places to put the proper guard-rails when it comes to the threads that can be used - however it can't catch all mistakes.
If you are seeing your code executed on a thread that has executor in the name, then the request is being serviced by the wrong thread pool.
If you are using quarkus-resteasy for example, this is the only way that RESTEasy can handle requests - it doesn't matter what your code is, the request is always handled on an executor thread.
For this reason, Quarkus provides RESTEasy Reactive (which is the prefered REST API layer) which allows you to choose whether you want a request to be serviced on an executor thread or an event-loop thread.
See this for more details.
I need to consume messages from RabbitMQ in a microservice written using Quarkus. I tried to use the smallrye-reactive-messaging for Quarkus but faced two problems:
it only supports AMQP 1.0 and doesn't work with RabbitMQ (even if I use the experimental AMQP 1.0 plugin).
it works with ActiveMQ Artemis but there's another issue: The smallrye-reactive-messaging is... reactive which is nice but there's no time right now to rewrite my database code to be reactive. Processing the message means persisting tens of thousands of documents to the mongodb which can take several minutes and it seems to be blocking the whole server:
WARNING [io.ver.cor.imp.BlockedThreadChecker]
(vertx-blocked-thread-checker) Thread
Thread[vert.x-eventloop-thread-0,5,main]=Thread[vert.x-eventloop-thread-0,5,main]
has been blocked for 212088 ms, time limit is 2000 ms:
io.vertx.core.VertxException: Thread blocked
So my idea for a workaround is to start a thread for consuming and processing the messages somewhere in Quarkus when it boots up. There's a support for scheduling periodic tasks in Quarkus is there's an annotation for background processes or do I have to write my own extension?
In the end I've solved my problem by using ActiveMQ Artemis and rewriting my database code using the reactive pattern. Another approach might have been using the io.vertx.rabbitmq.RabbitMQClient in Vert.x.
In case someone came here looking for how and where a background process can be started in Quarkus I found the answer in the book Quarkus Cookbook (Chapter 5.9). There's also a section on Application Life Cycle Events in the official documentation.
So to execute some code when Quarkus boots you observe the StartupEvent in your bean:
import io.quarkus.runtime.StartupEvent;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Observes;
#ApplicationScoped
public class AppLifeEventListener {
void onStart(#Observes StartupEvent event) {
// start you background thread here
}
}
A process can be started in Quarkus Command Mode (https://quarkus.io/guides/command-mode-reference) using a external scheduler.
In MongoDB there is a bulk insert operation that improves performance by reducing the number of round trips.
Making a batch process using an external scheduler, Quarkus Command Mode and MongoDB Bulk Inserts can improve control over executions and yield better resource utilization.
Currently, we have four JMS listener containers that are started during the application start. They all connect through Apache ZooKeeper and are manually started. This becomes problematic when a connection to ZooKeeper cannot be established. The (Wicket) application cannot start, even though it is not necessary for the JMS listeners be active to use the application. They simply need to listen to messages in the background, save them and a cron job will process them in batches.
Goals:
Allow the application to start and not be prevented by the message containers not being able to connect.
After the application starts, start the message listeners.
If the connection to one or any of the message listeners goes down, it should attempt to automatically reconnect.
On application shutdown (such as the Tomcat being shutdown), the application should stop the message listeners and the cron job that processes the saved messages.
Make all of this testable (as in, be able to write integration tests for this setup).
Current Setup:
Spring Boot 1.5.6
Apache ZooKeeper 3.4.6
Apache ActiveMQ 5.7
Wicket 7.7.0
Work done so far:
Define a class that implements ApplicationListener<ApplicationReadyEvent>.
Setting the autoStart property of the DefaultMessageListenerContainer to false and start each container in the onApplicationEvent in a separate thread.
Questions:
Is it necessary to start each message container in its own thread? This seems to be overkill, but the way the "start" process works is that the DefaultMessageListenerContainer is built for that listener and then it is started. There is a UI component that a user can use to start/stop the message listeners if need be, and if these are started sequentially in one thread, then the latter three message containers could be null if the first one has yet to connect on startup.
How do I accomplish goals 4 and 5?
Of course, any commments on whether I am on the right track would be helpful.
If you do not start them in a custom thread then the whole application cannot be fully started. It is not just Wicket, but the Servlet container won't change the application state from STARTING to STARTED due to the blocking request to ZooKeeper.
Another option is to use a non-blocking request to ZooKeeper but this is done by the JMS client (ActiveMQ), so you need to check whether this is supported in their docs (both ActiveMQ and ZooKeeper). I haven't used those in several years, so I cannot help you more.
I am working on a on Spring web service which calls a thread for a long running task, as I don't want to keep the user busy because the task can be really long.
I want to notify the user through web socket when the task on the thread has completed. What is the best procedure to do so in spring??
Spring websocket can be used for this purpose.
I beleive this would help you initially at least. https://spring.io/guides/gs/messaging-stomp-websocket/