What i need: 1. Send messages through jms. 2. Have messages persisted so that if not handled from client and server restarts client gets the message on server restart. 3. Messages should be received from client in the same order as these messages have been sent. 4. Have multiple consumers in the queue so as to scale and handle different messages in parallel.
What i did: I use active mq and have the following spring configuration
<bean id="destination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg index="0" value="destination"/>
</bean>
<bean id="template" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="pooledConnectionFactory"/>
<property name="deliveryMode" value="2"/>
<property name="defaultDestination" ref="destination"/>
</bean>
<bean id="messageListener" class="InternalNotificationJMSConsumer"/>
<jms:listener-container connection-factory="pooledConnectionFactory" acknowledge="client" destination-type="queue" concurrency="5-10" container-type="simple" cache="none" client-id="client1" prefetch="1">
<jms:listener destination="destination" ref="messageListener" method="onMessage"/>
</jms:listener-container>
So i have my destination and my connection pool. Then i create a spring jmstemplate and start sending messages
template.send(new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
return session.createObjectMessage(message);
}
});
Then i have the receiver as follows:
@Component
public class JMSConsumer implements MessageListener {
@Override
public void onMessage(Message message) {
if (message instanceof ObjectMessage) {
....
}
}
My problems:
a. Messages using this configuration are not received in order. This makes sence given the xsd comment in listener-container.concurency: "keep concurrency limited to 1 in case of a topic listener or if message ordering is important;". So question is how/if i can keep order but have multiple consumers.
b. message acknowledgement. What i need is that after message has been processed, onMessage returns, only then message is considered as acknowledged and not re-transmited. I have no transactionmanager in terms that i am not inside any application server and wish to avoid this if possible. i only need to acknowledge messages my self. Is this possible?