In mijn vorige blog heb ik uitgelegd hoe je de WSO2 ESB en ActiveMQin zo in kunt stellen dat je met JMS transacties berichtaflevering kunt garanderen. De reden hiervoor is dat je natuurlijk niet wil dat berichten verloren raken in de cyberspace. In deze blog over gegarandeerde berichtaflevring ga ik het hebben over hoe je om kunt gaan met berichten die niet afgeleverd kunnen worden.
Ik liet in deel 1 een voorbeeld van een configuratie zien die oneindig lang blijft proberen, maar als de client voor langere tijd onbeschikbaar blijft, zou dat een verspilling van je middelen zijn. Dit probleem is op te lossen door de berichten die niet afgeleverd kunnen worden naar een andere wachtrij te sturen, we noemen dat een ‘Dead Letter Queue’. Om dit te kunnen doen, zul je een ‘Dead Letter Strategy’ moeten configureren.
De Dead Letter Strategy is een ‘Enterprise Integration Pattern’. Deze patronen zijn gebruikelijk binnen alle organisaties en ze worden door de WSO2 ESB ondersteund. Er is zelfs een speciaal stuk aan gewijd in de documentatie op de WSO2 website.
In deze blog bespreek ik hoe je zo’n dead letter strategie kunt configureren door de WSO2 ESB en ActiveMQ te gebruiken. Om dit allemaal voor elkaar te krijgen, maak ik opnieuw gebruik van de configuratie die ik mijn vorige blog heb gemaakt.
De eerste stap is het toevoegen van een aantal parameters aan het volgende onderdeel in het Axis2.xml <ESB_HOME/repository/conf/axis2> configuratiebestand:
<!--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>
Voeg de volgende parameters aan dit deel toe:
<parameter name="redeliveryPolicy.initialRedeliveryDelay">1000</parameter> <parameter name="redeliveryPolicy.backOffMultiplier">3</parameter> <parameter name="redeliveryPolicy.useExponentialBackOff">true</parameter>
Uitleg
- redeliveryPolicy.initialRedeliveryDelay: de tijd (in milliseconden) tussen de eerste aflevering en de eerste afleveringspoging.
- redeliveryPolicy.backOffMultiplier: vermenigvuldigt tussen iedere afleveringspoging de vertraging voor het opnieuw afleveren.
- redeliveryPolicy.useExponentialBackOff: schakelt de exponentiële vertraging, met de waarde die is ingesteld als redeliveryPolicy.backOffMultiplier parameter, aan of uit.
Verander de waarde van de volgende parameter:
<parameter name="redeliveryPolicy.maximumRedeliveries">3</parameter>
Let op: vergeet niet de ESB opnieuw op te starten, omdat deze alleen bij het opstarten geladen worden.
We hebben nu een beleid voor het herhaaldelijk afleveren ingesteld. Dit beleid werkt op de volgende wijze:
- Na de eerste afleveringspoging is er een vertraging van 1 seconde tot de tweede poging plaatsvindt.
- Tussen de tweede en derde poging is er een vertraging van 3 seconden.
- Tussen de derde en vierde poging is er een vertraging van 9 seconden.
- Na 4 afleveringspogingen wordt het bericht doorgestuurd naar de dead letter queue.
ActiveMQ gebruikt standaard een dead letter queue die ActiveMQ.DLQ heet. Alle berichten die niet afgeleverd kunnen worden, worden naar deze wachtrij gestuurd. Maar zoals je je kunt voorstellen is het moeilijk managen als alle verschillende soorten berichten in dezelfde wachtrij terechtkomen.
Individuele Dead Letter Strategie
Dit kun je oplossen door een individuele deal letter strategie te configureren. Je hebt hiervoor de activemq.xml configuratie nodig. Zoek naar het volgende deel met parameters in het activemq.xml configuratiebestand:
<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>
Vervang het met de volgende configuratie:
<destinationPolicy> <policyMap> <policyEntries> <policyEntry queue=">"> <deadLetterStrategy> <individualDeadLetterStrategy queuePrefix="DLQ." useQueueForQueueMessages="true"/> </deadLetterStrategy> </policyEntry> </policyEntries> </policyMap> </destinationPolicy>
Uitleg
Deze configuratie zal voor iedere wachtrij, waarvan een bericht niet afgeleverd kan worden, een dead letter queue maken met de prefix “DLQ.” Hierdoor kun je de verschillende berichten beter sorteren en in de gaten houden, waardoor het makkelijker is om berichten uit de DLQ te halen en ze alsnog af te leveren, want dat is uiteindelijk het doel. In mijn volgende blog ga ik het hebben over het monitoren van het beleid voor het opnieuw afleveren.
Bekijk ook onze WSO2 Tutorials, webinars en whitepapers voor uitgebreidere technische informatie. Heb je ondersteuning nodig? We bieden WSO2 Productondersteuning, Ondersteuning voor WSO2 Development, Operationele WSO ondersteuning en WSO2 Trainingsprogramma’s.