Asynchronous send to a queue using Spring Jms issue

10,486

The JmsTemplate send is never synchronous in terms of waiting for a consumer to take a Message of the Queue in the normal case. The send can however be synchronous in that it waits for a response from the Broker indicating that it has received and stored the Message. This is so that you have an indication of success as Queues must ensure that they are reliable. You can configure many things in the ActiveMQConnectionFactory to control this. Setting the options useAsyncSend will enforce that your send don't wait for a Broker ACK if that is what you want. These options are all documented.

You configure these on the connection URI like so: tcp://localhost:61616?jms.useAsyncSend=true

A send can however block if the ActiveMQ Broker's producer flow control kicks in to prevent a Producer from flooding the Broker with messages. This is configurable as well both in terms of disabling it altogether and also in that you can increase the memory limits on the Broker for when this might kick in.

Finally a Producer send could block if the Connection to the broker is lost and you are using the Failover Transport to have your client automatically reconnect.

Share:
10,486
user1717230
Author by

user1717230

Updated on June 04, 2022

Comments

  • user1717230
    user1717230 almost 2 years

    I have a requirement when I need to write asynchronously to a queue in activemq. I am using Spring Jms to do it. This is the wiring in my spring context file

    <bean id="amqProducerConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
            <property name="brokerURL" value="${activemq.broker}"/>        
        </bean>
    
        <bean id="pooledProducerConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop" lazy-init="true">
            <property name="connectionFactory" ref="amqProducerConnectionFactory" />
        </bean>
    
        <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
            <property name="connectionFactory" ref="pooledProducerConnectionFactory" />
        </bean>
    

    And in my code...i do..

    void sendMessage(JmsTemplate jmsTemplate, String message, String requestQueue) {
            def messageCreator = { session ->
                session.createTextMessage(message)
            } as MessageCreator
    
            jmsTemplate.send(requestQueue, messageCreator)
        }
    

    But the above seems to be working synchronously, not asynchrously. Is there anything that I need to add here that makes the process asynchronous(I mean, App 'A' writes to a queue. It should write to the queue and forget, not wait until App 'B' picks it up from the queue and processes it.)

  • jeromerg
    jeromerg over 7 years
    JmsTemplate gets the connection from the connection factory synchronously. Can it happen that the sending gets delayed if the connection has not been established yet or if the connection cannot be established at all? If yes what would be the best workaround to ensure, that the full JmsTemplate processing remains asynchronous in any case?