ActiveMQ redelivery does not work

我怕爱的太早我们不能终老 提交于 2019-12-01 12:50:28

because you are using this.session = connection.createSession(false,Session.CLIENT_ACKNOWLEDGE);
calling message.acknowledge(); is the same than calling session.acknowledge(); .

to have ActiveMQ redelivery working successfully with your config, there is some possibilities with minimal changes:

  1. calling QueueReceiver.this.session.recover();
    in place of calling QueueReceiver.this.session.rollback();

void org.apache.activemq.ActiveMQSession.recover() throws JMSException

Stops message delivery in this session, and restarts message delivery with the oldest unacknowledged message.

All consumers deliver messages in a serial order. Acknowledging a received message automatically acknowledges all messages that have been delivered to the client.

Restarting a session causes it to take the following actions: •Stop message delivery •Mark all messages that might have been delivered but not acknowledged as "redelivered" •Restart the delivery sequence including all unacknowledged messages that had been previously delivered. Redelivered messages do not have to be delivered in exactly their original delivery order.

  1. use this.session = connection.createSession(false, org.apache.activemq.ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE); and call ((org.apache.activemq.command.ActiveMQMessage) message ).acknowledge(); , note that not calling this method is like a rollback, means the message is not acknowledged and throwing an exception in onMessage method will call QueueReceiver.this.consumer.rollback(); of org.apache.activemq.ActiveMQMessageConsumer.rollback().

  2. simply calling QueueReceiver.this.consumer.rollback(); org.apache.activemq.ActiveMQMessageConsumer.rollback() in place of calling QueueReceiver.this.session.rollback();

So it proved to be a combination of issues:

  • The session acknowledge mode needed to be set to ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE
  • I'm using session.recover() rather than rollback()
  • The ActiveMQ broker wasn't properly configured. I needed to add this bit to the activemq.xml configuration file (place it under the <broker> tag).

        <destinationPolicy>
        <policyMap>
          <policyEntries>
            <policyEntry topic=">" >
                <!-- The constantPendingMessageLimitStrategy is used to prevent
                     slow topic consumers to block producers and affect other consumers
                     by limiting the number of messages that are retained
                     For more information, see:
    
                     http://activemq.apache.org/slow-consumer-handling.html
    
                -->
              <pendingMessageLimitStrategy> 
                <constantPendingMessageLimitStrategy limit="1000"/>
              </pendingMessageLimitStrategy>
            </policyEntry>
            <!-- Set the following policy on all queues using the '>' wildcard -->
            <policyEntry queue=">">
                <deadLetterStrategy>
                    <!--
                      Use the prefix 'DLQ.' for the destination name, and make
                      the DLQ a queue rather than a topic
                    -->
                    <individualDeadLetterStrategy queuePrefix="DLQ." useQueueForQueueMessages="true"/>
                </deadLetterStrategy>
            </policyEntry>
          </policyEntries>
        </policyMap>
    </destinationPolicy>
    
  • Make sure you didn't active any redeliveryPlugin that can mess with your ActiveMQConnectionFactory configuration.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!