...
- SEDA for in-JVM load balancing across a thread pool]
- ActiveMQ or JMS for distributed load balancing and parallel processing
- JPA for using the database as a poor mans message broker
When procssing processing messages concurrently, you should consider ordering and concurrency issues. These are described below
...
Note that there is no concurrency or locking issue when using ActiveMQ, JMS or SEDA by design; they are designed for highly concurrent use. However there are possible concurrency issues in the Processor of the messages i.e. What what the processor does with the message?
...
As soon as you send multiple messages to different threads or processes you will end up with an unknown ordering across the entire message stream as each thread is going
to process messages concurrently.
...
- for distributed locking, use a database by default, they are very good at it
- to preserve ordering across a JMS queue consider using Exclusive Consumers in the ActiveMQ component
- even better are Message Groups which allows you to preserve ordering across messages while still offering parallelisation via the JMSXGrouopID JMSXGroupID header to determine what can be parallelized
- if you receive messages out of order you could use the Resequencer to put them back together again
A good rule of thumb to help reduce concurrency ordering problems is to make sure each single can be processed as an atomic unit in parallel (either without concurrency issues or using say, database locking); or if it can't, use a Message Group to relate the messages together which need to be processed in order by a single thread.
...
For example the following code shows how to create a message group using an XPath expression taking an invoice's product code as the Correlation Identifier
Code Block |
---|
from("activemq:a").setHeader("JMSXGroupID"JmsConstants.JMS_X_GROUP_ID, xpath("/invoice/productCode")).to("activemq:b"); |
...