Search code examples
multithreadingactivemq-classicquartz-schedulerdaemon

Multiple consumers on single ActiveMQ session


I have a java application and I want some help in validating what I did till now!. the application has Quartz Daemon that is configured to run every 200ms to poll a message from an ActiveMQ Queue, the processing time for the daemon is about 2-3 minutes for each message, when the Daemon trigger fires then another thread starts the Daemon task to poll another message and process it up to 50 threads in parallel , all the threads use the same connection and session to the ActiveMQ in which it is configured with the default Prefetch size.

Do you think there is anything wrong with this implementation? thanks!


Solution

  • Assuming you like the current design and you're only concerned about the implementation then the only reason for concern here I see is any possible concurrent access of the javax.jms.Session. The Session is not thread-safe so it should never be accessed by more than one thread at the same time. A javax.jms.Connection is thread-safe so that's not a concern. It may be safer/simpler to just create a session for each consumer. Sessions are pretty light-weight so I wouldn't expect any real performance degradation.

    To avoid session concurrency problems you might even consider using a connection pool (e.g. PooledJMS which is based on ActiveMQ's connection pool implementation).

    Your prefetch size might be an issue if you start running into consumer starvation issues, but you don't indicate what your message volume is going to be so it's hard to say if that's going to be an issue or not. Two things to keep in mind:

    • The higher the volume of messages the less likely it is that consumers will starve.
    • The longer a consumer takes to process a message the lower its prefetch size should be.

    Adjust your prefetch size accordingly.

    Regarding the design overall, I can't help but think a javax.jms.MessageListener implementation would be better here. A single MessageListener could get messages and hand them off to threads for processing. This would avoid the Quartz dependency as well as the polling.