Whats the best way to process an asynchronous queue continuously in Java?

10,115

Solution 1

"On one hand I can probably create a simple java program that I kick off from the command line that picks each item in the queue and processes it. Is that safe?"

What's unsafe about it? It works great.

"Does it make more sense to have that program running as another thread inside the Tomcat container?"

Only if Tomcat has a lot of free time to handle background processing. Often, this is the case -- you have free time to do this kind of processing.

However, threads aren't optimal. Threads share common I/O resources, and your background thread may slow down the front-end.

Better is to have a JMS queue between the "port 80" front-end, and a separate backend process. The back-end process starts, connects to the queue, fetches and executes the requests. The backend process can (if necessary) be multi-threaded.

Solution 2

If you are using JMS, why are you placing the tasks into a DB?

You can use a durable Queue in JMS. This would keep tasks, even if the JMS broker dies, until they have been acknowledged. You can have redundant brokers so that if one broker dies, the second automatically takes over. This could be more reliable than using a single DB.

Solution 3

If you are already using Spring, check out DefaultMessageListenerContainer. It allows you to create a POJO message driven bean. This can be used from within an existing application container (your WAR file) or as a separate process.

Share:
10,115
Ish
Author by

Ish

Updated on June 14, 2022

Comments

  • Ish
    Ish almost 2 years

    I'm having a hard time figuring out how to architect the final piece of my system. Currently I'm running a Tomcat server that has a servlet that responds to client requests. Each request in turn adds a processing message to an asynchronous queue (I'll probably be using JMS via Spring or more likely Amazon SQS).

    The sequence of events is this:

    Sending side:
    1. Take a client request
    2. Add some data into a DB related to this request with a unique ID
    3. Add a message object representing this request to the message queue

    Receiving side:
    1. Pull a new message object from the queue
    2. Unwrap the object and grab some information from a web site based on information contained in the msg object.
    3. Send an email alert
    4. update my DB row (same unique ID) with the information that operation was completed for this request.

    I'm having a hard figuring out how to properly deal with the receiving side. On one hand I can probably create a simple java program that I kick off from the command line that picks each item in the queue and processes it. Is that safe? Does it make more sense to have that program running as another thread inside the Tomcat container? I will not want to do this serially, meaning the receiving end should be able to process several objects at a time -- using multiple threads. I want this to be always running, 24 hours a day.

    What are some options for building the receiving side?

  • Ish
    Ish about 15 years
    In this case is the consumer polling the queue continously or does it get notified somehow?
  • John Meagher
    John Meagher about 15 years
    I'm pretty sure the DefaultMessageListenerContainer polls. The nice thing about it is that it hides the poll/notification issue from you. You just implement a jms MessageListener and do whatever work you need to do.
  • TheMonkWhoSoldHisCode
    TheMonkWhoSoldHisCode over 9 years
    Can you explain how to implement a event-based model?
  • Don Branson
    Don Branson over 9 years
    Have a look at docs.oracle.com/cd/E13222_01/wls/docs90/jms/…, the section titled "Receiving Messages Asynchronously."