info@yenlo.com
eng
Menu
WSO2 Enterprise Integrator 4 min

Guaranteed message deliveries #2: delivery not possible

Luuk_Abels.jpg
Luuk Abels
Integration Consultant
DHL Weve missed you 905379 edited 1

In my previous blog I explained how to configure the WSO2ESB and ActiveMQ for guaranteed delivery using JMS transactions. The reason of course being that you do not want messages lost in cyberspace. In this blog about guaranteed message deliveries I want to focus on how to deal with messages that cannot be delivered.

In the previous part (1) blog I showed an example configuration that would retry indefinitely. But this can be a waste of resources when, for example, the client will not be available for some time.

A solution for this problem is to send the messages that cannot be delivered to another queue, a so called deadletterqueue. To do this you will need to configure a deadLetterStrategy.
This is a so called Enterprise Integration Pattern. These patterns are common for all organizations and the WSO2ESB supports all these patterns. To be more precise, there is a special piece of documentation about it on the WSO2 site.

In this blog I will explain how to configure such a deadLetterStrategy using the WSO2ESB and ActiveMQ.
To set up this configuration we are going to continue with the configuration from my previous blog.

The first step is to add a number of parameters to the following section in the Axis2.xml <ESB_HOME/repository/conf/axis2> configuration file:

 <!--Uncomment this and configure as appropriate for JMS transport support, after setting up your JMS environment (e.g. ActiveMQ) --> <transportReceiver class="org.apache.axis2.transport.jms.JMSListener" name="jms"> <parameter name="myQueueConnectionFactory">    <parameter name="java.naming.factory.initial">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>    <parameter name="java.naming.provider.url">tcp://localhost:61616</parameter>    <parameter name="transport.jms.ConnectionFactoryJNDIName>QueueConnectionFactory</parameter>    <parameter name="transport.jms.ConnectionFactoryType">queue</parameter>    <parameter name="transport.jms.SessionTransacted">true</parameter>    <parameter name="transport.jms.SessionAcknowledgement">CLIENT_ACKNOWLEDGE</parameter>    <parameter name="redeliveryPolicy.redeliveryDelay">1000</parameter>    <parameter name="redeliveryPolicy.maximumRedeliveries">-1</parameter>    <parameter name="transport.jms.CacheLevel">consumer</parameter> </parameter> 

Add the following parameters to this section:

<parameter name="redeliveryPolicy.initialRedeliveryDelay">1000</parameter> <parameter name="redeliveryPolicy.backOffMultiplier">3</parameter> <parameter name="redeliveryPolicy.useExponentialBackOff">true</parameter> 

Explanation

  • redeliveryPolicy.initialRedeliveryDelay: the time (in milliseconds) between the first delivery and the first redelivery attempt.
  • redeliveryPolicy.backOffMultiplier: multiplies the redelivery delay between each redeliver attempt.
  • redeliveryPolicy.useExponentialBackOff: enables or disables the exponential back off using the value set in the redeliveryPolicy.backOffMultiplier parameter.

Change the value of the following parameter:

<parameter name="redeliveryPolicy.maximumRedeliveries">3</parameter> 

Note: do not forget to restart the ESB since these are only loaded at startup.

We now have configured a redelivery policy that will work the following way:

  • After the first delivery attempt there will be a delay of 1 second before the second attempt.
  • Between the second and the third attempt there will be a delay of 3 seconds.
  • Between the third and the fourth attempt there will be delay of 9 seconds.
  • After 4 delivery attempts the message will be send to the deadletterqueue.

By default ActiveMQ uses one deadletterqueue that is called ActiveMQ.DLQ. All the messages that cannot be delivered will be send to this queue.
But as you can imagine this can difficult to manage if different messages all end up in the same queue.

Individual Dead Letter Strategy

This can be solved by configuring a individualDeadLetterStrategy. This is done in the activemq.xml configuration.
Find the following section of parameters in the activemq.xml configuration file:

<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>       </policyEntries>     </policyMap> </destinationPolicy> 

Replace it with the following configuration:

  <destinationPolicy>     <policyMap>       <policyEntries>         <policyEntry queue=">">           <deadLetterStrategy>             <individualDeadLetterStrategy queuePrefix="DLQ." useQueueForQueueMessages="true"/>           </deadLetterStrategy>         </policyEntry>       </policyEntries>     </policyMap>   </destinationPolicy> 

Explanation

This configuration will create a deadletterqueue with the prefix “DLQ.” for every queue that has a message that cannot be delivered.
This will allow you to keep tabs on the messages while making it easier to get messages of the DLQ since we still need to deliver them. In my next blog I will tell you about monitoring the redelivery policy.

View also our WSO2 Tutorials, webinars or white papers for more technical information. Need support? We do deliver WSO2 Product Support, WSO2 Development Support, WSO2 Operational Support and WSO2 Training Programs.

eng
Close