Bij het ontwikkelen van services in WSO2 Micro Integrator is het vaak noodzakelijk om retry-mechanismen toe te voegen voor betrouwbare communicatie met back-endsystemen die tijdelijk niet beschikbaar kunnen zijn. Exponentiële backoff is een van de benaderingen om retries te beheren, waarbij de wachttijd tussen opeenvolgende retry-pogingen geleidelijk toeneemt.
In deze blogpost wordt uitgelegd hoe exponentiële retries kunnen worden geconfigureerd in WSO2 MI. Aan de hand van een voorbeeld met ActiveMQ laten we zien hoe message redelivery bij fouten kan worden afgehandeld.
Deze configuratie is lokaal getest op WSO2 MI 4.2 (U2 level – 102) met ActiveMQ 6.0.1 als message

Overzicht van exponentiële backoff in WSO2 Micro Integrator
Exponentiële backoff is een retrystrategie waarbij de wachttijd tussen opeenvolgende retry-pogingen exponentieel toeneemt. Deze strategie is met name geschikt voor situaties waarin het back-endsysteem tijdelijk problemen ondervindt of overbelast is.
Bij exponentiële backoff wordt gestart met een basisinterval voor retries. De wachttijd voor elke volgende poging neemt vervolgens toe op basis van een backoff-multiplier, totdat een vooraf ingestelde maximale vertraging is bereikt. Deze aanpak minimaliseert onnodige belasting en optimaliseert de hersteltijd voor zowel de client als de server.
Laten we beginnen met het configureren van het retry-mechanisme in het proxyservice-codevoorbeeld.
JMS-proxy configureren met exponentiële backoff
In dit voorbeeld zetten we een consumer-proxyservice op die luistert naar een JMS-queue en een HTTP-aanroep doet naar een back-end-endpoint. Wanneer de back-end-aanroep faalt, moet het JMS-bericht opnieuw worden afgeleverd met exponentiële backoff-intervallen.
Belangrijke parameters voor exponentiële backoff
In WSO2 MI kunnen exponentiële backoff-retries worden geconfigureerd door specifieke parameters in de JMS-proxyservice in te stellen:
redeliveryPolicy.useExponentialBackOff : Activeert exponentiële backoff voor retries.
redeliveryPolicy.backOffMultiplier : Bepaalt de factor waarmee de wachttijd na elke retry wordt vermenigvuldigd.
redeliveryPolicy.initialRedeliveryDelay : Stelt de wachttijd in vóór de eerste retry.
Voorbeeld van een JMS consumer-proxyconfiguratie
<?xml version="1.0" encoding="UTF-8"?>
<proxy name="ExponentialRetryProxySample" startOnLoad="true" transports="jms" xmlns="http://ws.apache.org/ns/synapse">
<target>
<inSequence>
<log level="custom">
<property name="MSG" value="Receiving messages from Queue"/>
<property expression="json-eval($)" name="Payload"/>
</log>
<call blocking="true">
<endpoint>
<http method="GET" uri-template="http://backend.example.com/api/resource">
<suspendOnFailure>
<errorCodes>-1</errorCodes>
<initialDuration>-1</initialDuration>
<progressionFactor>1</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
<drop/>
</inSequence>
<outSequence/>
<faultSequence>
<log level="custom">
<property name="MSG" value="Fault Sequence Triggered"/>
</log>
<property name="SET_ROLLBACK_ONLY" scope="axis2" value="true"/>
</faultSequence>
</target>
<parameter name="transport.jms.DestinationType">queue</parameter>
<parameter name="transport.jms.Destination">testqueue</parameter>
<parameter name="transport.jms.ContentType">
<rules>
<jmsProperty>contentType</jmsProperty>
<default>application/json</default>
</rules>
</parameter>
<parameter name="transport.jms.ConnectionFactory">myQueueListener</parameter>
<parameter name="transport.jms.SessionAcknowledgement">CLIENT_ACKNOWLEDGE</parameter>
<parameter name="transport.jms.SessionTransacted">true</parameter>
<parameter name="transport.jms.CacheLevel">consumer</parameter>
<parameter name="redeliveryPolicy.backOffMultiplier">3</parameter>
<parameter name="redeliveryPolicy.maximumRedeliveries">5</parameter>
<parameter name="redeliveryPolicy.initialRedeliveryDelay">2000</parameter>
<parameter name="redeliveryPolicy.useExponentialBackOff">true</parameter>
</proxy> Uitleg van de belangrijkste elementen
- endpoint configuratie:
– suspendOnFailure: Configureert het endpoint zo dat het niet wordt geschorst bij een fout, waardoor retries blijven plaatsvinden op basis van het JMS-redeliverybeleid.
– markForSuspension: Voorkomt dat het endpoint na een fout in een geschorste status terechtkomt. - faultSequence: Wordt uitgevoerd wanneer het endpoint niet reageert. De eigenschap SET_ROLLBACK_ONLY, ingesteld op “true”, markeert de transactie voor rollback, waardoor message redelivery met exponentiële backoff wordt geactiveerd.
- JMS Parameters:
– redeliveryPolicy.useExponentialBackOff: Activeert exponentiële backoff.
– redeliveryPolicy.backOffMultiplier: Stelt de backoff-multiplier in op 3, waardoor de wachttijd na elke retry wordt verdrievoudigd.
– redeliveryPolicy.initialRedeliveryDelay: Stelt de initiële wachttijd vóór de eerste retry in op 2000 ms (2 seconden).
– redeliveryPolicy.maximumRedeliveries: Beperkt het aantal retries tot vijf pogingen.
Hoe exponentiële retries werken
Met de bovenstaande instellingen vinden retries plaats met exponentieel toenemende intervallen:
- Eerste retry: 2 seconden
- Tweede retry: 6 seconden (2 s × 3)
- Derde retry: 18 seconden (6 s × 3)
- Vierde retry: 54 seconden (18 s × 3)
- Enzovoort, tot een maximum van vijf retries.
Wanneer een bericht na alle retry-pogingen nog steeds faalt, wordt het naar een Dead Letter Queue (DLQ) gestuurd voor handmatige inspectie.
Aanvullende configuratietips
- Blocking Mode: Door blocking Setting blocking=”true” in de call mediator in te stellen, wacht het systeem op de HTTP-respons. Deze aanpak is essentieel voor betrouwbare message redelivery binnen JMS-proxyservices.
- Voorkomen van endpoint-suspensie: Standaard wordt een endpoint bij een fout gedurende 30.000 milliseconden geschorst. Wanneer een endpoint zich in deze geschorste status bevindt, kan het gedurende die periode geen nieuwe berichten verwerken. In dit scenario zorgen de configuraties suspendOnFailure en markForSuspension ervoor dat het endpoint actief blijft, zodat vervolg-retries kunnen worden uitgevoerd.
- Fijn afstellen van het redeliverybeleid:
Het redeliverygedrag kan verder worden geoptimaliseerd met aanvullende parameters
a. redeliveryPolicy.maximumRedeliveryDelay: Definieert een bovengrens (in seconden) om te voorkomen dat retry-intervallen te lang worden.
b. redeliveryPolicy.maximumRedeliveries: Stelt een limiet in op het aantal retries. - Transactiebeheer voor berichten: Door transport.jms.SessionTransacted op “true” te zetten, wordt het bericht pas uit de queue verwijderd nadat het succesvol is verwerkt.
Configuratie in deployment.toml
[[transport.jms.sender]]
name = "myQueueSender"
parameter.initial_naming_factory = "org.apache.activemq.jndi.ActiveMQInitialContextFactory"
parameter.provider_url = "tcp://${activemqEndpoint}" //input your activemq URL
parameter.connection_factory_name = "QueueConnectionFactory"
parameter.connection_factory_type = "queue"
parameter.cache_level = "producer"
[[transport.jms.listener]]
name = "myQueueListener"
parameter.initial_naming_factory = "org.apache.activemq.jndi.ActiveMQInitialContextFactory"
parameter.provider_url = "failover:(tcp://${activemqEndpoint})" //input your activemq URL
parameter.connection_factory_name = "QueueConnectionFactory"
parameter.connection_factory_type = "queue"
parameter.cache_level = "consumer"
[[transport.jms.listener]]
name = "default"
parameter.initial_naming_factory = "org.apache.activemq.jndi.ActiveMQInitialContextFactory"
parameter.provider_url = "failover:(tcp://${activemqEndpoint})"
parameter.connection_factory_name = "QueueConnectionFactory"
parameter.connection_factory_type = "queue" Na het toevoegen van deze configuraties moet WSO2 MI opnieuw worden gestart.
Testen en observeren van exponentiële backoff
Om de test te starten, hebben we een voorbeeldbericht gepubliceerd naar de testqueue via de ActiveMQ Web Console (http://localhost:8161/admin). De queue en de connection factory waren vooraf geconfigureerd in ActiveMQ, en de WSO2 MI JMS-listener was via de proxy ExponentialRetryProxySample op deze queue geabonneerd.


Wanneer de proxy een bericht uit de queue ontving, probeerde deze het geconfigureerde endpoint aan te roepen. Om een endpoint-fout te simuleren, hebben we een ongeldig endpoint-URL gebruikt.
Dit zorgde ervoor dat de faultSequence werd geactiveerd, waarbij de transactie met behulp van de betreffende property werd gemarkeerd voor rollback.
<property name="SET_ROLLBACK_ONLY" scope="axis2" type="STRING" value="true"/> Als gevolg hiervan probeerde ActiveMQ het bericht opnieuw af te leveren volgens het geconfigureerde exponentiële backoff-beleid. We hebben waargenomen dat de retry-intervallen geleidelijk toenamen van 2 seconden → 6 seconden → 18 seconden, enzovoort, op basis van de backOffMultiplier-waarde van 3.
Zodra de maximale retry-limiet (gedefinieerd door redeliveryPolicy.maximumRedeliveries) werd bereikt, werd het bericht automatisch verplaatst naar de Dead Letter Queue (DLQ) voor verdere analyse.
Voorbeeld van logoutput
Hieronder zie je een voorbeeld van de logoutput tijdens het testen, waarin retry-intervallen van 2 seconden, 6 seconden en 18 seconden (enzovoort) zichtbaar zijn:
[2024-11-05 14:07:33,734] INFO {LogMediator} - {proxy: ExponentialRetryProxySample} MSG = Receiving messages from Queue, Payload = {
"test": "message"
}
[2024-11-05 14:08:33,768] INFO {LogMediator} - {proxy: ExponentialRetryProxySample} MSG = Fault Sequence Triggered
[2024-11-05 14:08:33,769] ERROR {ServiceTaskManager} - Error recovering the JMS session javax.jms.IllegalStateException: This session is transacted
[2024-11-05 14:08:35,807] INFO {LogMediator} - {proxy: ExponentialRetryProxySample} MSG = Receiving messages from Queue, Payload = {
"test": "message"
}
[2024-11-05 14:08:35,808] INFO {LogMediator} - {proxy: ExponentialRetryProxySample} MSG = Fault Sequence Triggered
[2024-11-05 14:08:35,809] ERROR {ServiceTaskManager} - Error recovering the JMS session javax.jms.IllegalStateException: This session is transacted
[2024-11-05 14:08:41,824] INFO {LogMediator} - {proxy: ExponentialRetryProxySample} MSG = Receiving messages from Queue, Payload = {
"test": "message"
}
[2024-11-05 14:08:41,825] INFO {LogMediator} - {proxy: ExponentialRetryProxySample} MSG = Fault Sequence Triggered
[2024-11-05 14:08:41,826] ERROR {ServiceTaskManager} - Error recovering the JMS session javax.jms.IllegalStateException: This session is transacted
[2024-11-05 14:08:59,843] INFO {LogMediator} - {proxy: ExponentialRetryProxySample} MSG = Receiving messages from Queue, Payload = {
"test": "message"
}
[2024-11-05 14:08:59,844] INFO {LogMediator} - {proxy: ExponentialRetryProxySample} MSG = Fault Sequence Triggered
[2024-11-05 14:08:59,844] ERROR {ServiceTaskManager} - Error recovering the JMS session javax.jms.IllegalStateException: This session is transacted
[2024-11-05 14:09:53,864] INFO {LogMediator} - {proxy: ExponentialRetryProxySample} MSG = Receiving messages from Queue, Payload = {
"test": "message"
}
[2024-11-05 14:10:53,875] INFO {LogMediator} - {proxy: ExponentialRetryProxySample} MSG = Fault Sequence Triggered
[2024-11-05 14:10:53,875] ERROR {ServiceTaskManager} - Error recovering the JMS session javax.jms.IllegalStateException: This session is transacted
[2024-11-05 14:13:35,900] INFO {LogMediator} - {proxy: ExponentialRetryProxySample} MSG = Receiving messages from Queue, Payload = {
"test": "message"
}
[2024-11-05 14:14:35,921] INFO {LogMediator} - {proxy: ExponentialRetryProxySample} MSG = Fault Sequence Triggered
[2024-11-05 14:14:35,921] ERROR {ServiceTaskManager} - Error recovering the JMS session javax.jms.IllegalStateException: This session is transacted Deze logoutput bevestigt dat retries plaatsvinden volgens exponentieel toenemende intervallen, zoals geconfigureerd.
Conclusie
Het exponentiële retry-mechanisme in WSO2 Micro Integrator maakt het mogelijk om tijdelijke back-endfouten op een gecontroleerde en robuuste manier af te handelen. Door retries met exponentiële backoff te configureren, voorkomen we dat verzoeken te frequent worden verzonden wanneer een back-endservice niet beschikbaar is. Dit vermindert de belasting van het systeem en geeft de service de benodigde tijd om te herstellen.
Probeer deze configuratie in uw eigen WSO2 MI-omgeving en experimenteer met de parameters voor herlevering om de optimale balans voor uw gebruikssituatie te vinden. Als u inzichten of alternatieve benaderingen hebt, kunt u deze delen door contact op te nemen met een van onze accountmanagers.
