Voor gegarandeerde berichtvolgorde, taakverdeling en failover
Een berichtensysteem met gegarandeerde bezorging garandeert dat het bericht van de zender naar de ontvanger wordt afgeleverd, zelfs wanneer de ontvanger offline is. WSO2 Micro Integrator kan worden gebruikt om samen met een ‘message broker’ (berichtenmakelaar) een berichtensysteem met gegarandeerde bezorging te bouwen.
Deze functionaliteit is natuurlijk ook beschikbaar op de WSO2 Enterprise Integrator, maar we vermelden Micro Integrator (ook wel MI genoemd), aangezien het een recentere versie is.
WSO2 MI biedt kant-en-klare ondersteuning voor integratie met verschillende leveranciers van berichtenmakelaars. Een van de meest populaire en open-source berichtenmakelaars is ActiveMQ. Naast de normale berichtbemiddelingsfunctionaliteit biedt ActiveMQ geavanceerdere functies om verschillende gebruiksscenario’s te implementeren bij asynchrone berichtbezorging.
In een van onze vorige blogposts bespraken we de “Exclusieve consument” – functie van ActiveMQ om de berichtvolgorde in gegarandeerde bezorging te behouden. In deze blogpost bespreken we de functie “Berichtgroepen” van ActiveMQ.
Berichtgroepen
De functie Berichtgroepen is een verbetering van de functie “Exclusieve consument”. De JMSXGroupID-header wordt gebruikt om de berichten te groeperen. Dankzij deze groepering van berichten kunnen we gebruiksscenario’s implementeren, zoals gegarandeerde bestelbezorging, taakverdeling tussen meerdere consumenten en hoge beschikbaarheid/failover van consumenten.
ActiveMQ gebruikt de JMSXGroupID-headerwaarde om te bepalen naar welke consument het bericht moet worden verzonden. ActiveMQ koppelt de consumers (consumenten) aan berichtgroepen op basis van deze headerwaarde. Als er geen consumer aan een berichtgroep is gekoppeld, wordt een consumer gekozen uit beschikbare consumers. Totdat de gekozen consumer offline gaat, worden berichten met dezelfde berichtgroep (JMSXGroupID) afgeleverd bij de gekozen consumer.
Als een gekozen consumer offline gaat, kiest AcitveMQ een andere consumer die niet is gekoppeld aan berichtgroepen. Als een dergelijke consumer niet voorhanden is, wordt elke beschikbare consumer gekozen die mogelijk al aan een berichtgroep is gekoppeld.
In deze blogpost zullen we deze functie evalueren met behulp van WSO2 MI als berichtproducer en -consumer. Hier zullen we een REST API gebruiken die fungeert als een JMS-producer en twee JMS-proxy’s als JMS-consumers. U kunt natuurlijk ook een proxy gebruiken om als JMS-producer op te treden. Proxy’s kunnen luisteren in een JMS-wachtrij (naast andere transporten natuurlijk).
Deze REST API zou een XML-payload accepteren en zou, op basis van een payload-attribuut, de JMSXGroupID-header vullen en de payload naar de wachtrij publiceren. Beide JMS-consumers zouden de berichten uit dezelfde wachtrij gebruiken. We evalueren hoe ActiveMQ de berichten tussen de consumers verzendt op basis van de JMSXGroupID-headerwaarde.
We gebruikten
– WSO2 MI 4.1.0
– ActiveMQ 5.15.12
Denk eraan dat dit ook werkt op de Enterprise Integrator!
Configureer WSO2 EI met ActiveMQ om berichten te publiceren en te consumeren
We beschrijven de installatie van WSO2 en ActiveMQ niet volledig . Zie andere blogs van Yenlo over dit onderwerp of volg de instructies in de WSO2-documentatie om de setup te configureren.
Maak JMS-producent REST API in EI
Deze API accepteert een xml-bericht en publiceert het bericht naar de wachtrij “queue1” samen met de JMS-header JMSXGroupID. De waarde van deze header wordt geëxtraheerd uit de payload van inkomende API-verzoeken.
<property expression="//groupID/text()" name="JMSXGroupID" scope="transport" type="STRING"/>
In de bronweergave ziet de code er zo uit. Houd er rekening mee dat we een Property Group-mediator gebruiken om het ontwerp passend te krijgen op de pagina van deze blog.
<?xml version="1.0" encoding="UTF-8"?>
<api context="/publish" name="jms-publisher" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST" uri-template="/message">
<inSequence>
<log level="custom">
<property name="LOG" value="Message received. Publish to queue."/>
</log>
<propertyGroup>
<property expression="//groupID/text()" name="JMSXGroupID" scope="transport" type="STRING"/>
<property name="FORCE_SC_ACCEPTED" scope="axis2" type="STRING" value="true"/>
<property name="OUT_ONLY" scope="default" type="STRING" value="true"/>
<property name="messageType" scope="axis2" type="STRING" value="application/xml"/>
<property name="QueueName" scope="default" type="STRING" value="queue1"/>
</propertyGroup>
<header expression="concat('jms:/',get-property('QueueName'),'?transport.jms.ConnectionFactory=myQueueSender'')" name="To" scope="default"/>
<property action="remove" name="REST_URL_POSTFIX" scope="axis2"/>
<call>
<endpoint>
<default>
<timeout>
<duration>10000</duration>
<responseAction>fault</responseAction>
</timeout>
<suspendOnFailure>
<errorCodes>-1</errorCodes>
<initialDuration>0</initialDuration>
<progressionFactor>1.0</progressionFactor>
<maximumDuration>0</maximumDuration>
</suspendOnFailure>
<markForSuspension>
<errorCodes>-1</errorCodes>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</default>
</endpoint>
</call>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
Maak JMS Consumer 1 in EI
Deze proxy fungeert als JMS-consumer en is geabonneerd op de wachtrij “queue1”. Zodra een bericht is gelezen, worden de payload en de JMXGroupID-headerwaarde geregistreerd
<?xml version="1.0" encoding="UTF-8"?>
<proxy name="Alleenvooropmaak-jmsconsumer1" startOnLoad="true" transports="jms" xmlns="http://ws.apache.org/ns/synapse">
<target>
<inSequence>
<log level="full">
<property name="LOG" value="Consumer1 : Message consumed from queue."/>
<property expression="$trp: JMSXGroupID " name="groupID"/>
</log>
<log level="custom">
<property name="LOG" value="Consumer1 : Message processed. Send ACK to queue."/>
</log>
</inSequence>
<outSequence/>
<faultSequence>
<log level="full">
<property name="LOG" value="Consumer1 : Message processed. Send NACK to queue."/>
</log>
</faultSequence>
</target>
<parameter name="transport.jms.SessionAcknowledgement">CLIENT_ACKNOWLEDGE</parameter>
<parameter name="transport.jms.DestinationType">queue</parameter>
<parameter name="transport.jms.Destination">queue1</parameter>
<parameter name="transport.jms.ContentType">
<rules xmlns="">
<jmsProperty>contentType</jmsProperty>
<default>application/xml</default>
</rules>
</parameter>
<parameter name="transport.jms.SessionTransacted">true</parameter>
<parameter name="transport.jms.ConnectionFactory">myQueueListener</parameter>
<parameter name="transport.jms.CacheLevel">consumer</parameter>
</proxy>
Maak JMS Consumer 2 in EI
Deze proxy fungeert als JMS-consumer en is geabonneerd op de wachtrij “queue1”. Zodra een bericht is gelezen, worden de payload en de JMXGroupID-headerwaarde geregistreerd.
<?xml version="1.0" encoding="UTF-8"?>
<proxy name="jmsconsumer2" startOnLoad="true" transports="jms" xmlns="http://ws.apache.org/ns/synapse">
<target>
<inSequence>
<log level="full">
<property name="LOG" value="Consumer2 : Message consumed from queue."/>
<property expression="$trp: JMSXGroupID " name="groupID"/>
</log>
<log level="custom">
<property name="LOG" value="Consumer2 : Message processed. Send ACK to queue."/>
</log>
</inSequence>
<outSequence/>
<faultSequence>
<drop/>
</faultSequence>
</target>
<parameter name="transport.jms.SessionAcknowledgement">CLIENT_ACKNOWLEDGE</parameter>
<parameter name="transport.jms.DestinationType">queue</parameter>
<parameter name="transport.jms.Destination">queue1</parameter>
<parameter name="transport.jms.ContentType">
<rules xmlns="">
<jmsProperty>contentType</jmsProperty>
<default>application/xml</default>
</rules>
</parameter>
<parameter name="transport.jms.SessionTransacted">true</parameter>
<parameter name="transport.jms.ConnectionFactory">myQueueListener</parameter>
<parameter name="transport.jms.CacheLevel">consumer</parameter>
</proxy>
De setup testen
We sturen twee berichten met groupID-waarde gelijk aan group1 en nog twee berichten met groupID-waarde gelijk aan group 2.
Of, als je curl wilt gebruiken:
curl -k --location --request POST 'https://localhost:8253/publish/message' --header 'Content-Type: application/xml' --data '<groupID>group1</groupID>'
curl -k --location --request POST 'https://localhost:8253/publish/message' --header 'Content-Type: application/xml' --data '<groupID>group2</groupID>'
Voor een betere leesbaarheid van de logs heb ik een deel van de tekstkleur aangepast.
[2022-11-25 09:49:40,947] INFO {LogMediator} – {api:jms-publisher} LOG = Message received. Publish to queue.[2022-11-25 09:49:41,041] INFO {LogMediator} – {proxy:jmsconsumer1} To: , WSAction: urn:mediate, SOAPAction: urn:mediate, MessageID: ID:ip-172-31-39-100.eu-central-1.compute.internal-32983-1669364529898-9:3:1:1:1, Direction: request, LOG = Consumer1 : Message consumed from queue., groupID = group1, Envelope: <?xml version=’1.0′ encoding=’utf-8′?><soapenv:Envelope xmlns:soapenv=”http://schemas.xmlsoap.org/soap/envelope/”><soapenv:Body><groupID>group1</groupID></soapenv:Body></soapenv:Envelope>
[2022-11-25 09:49:41,041] INFO {LogMediator} – {proxy:jmsconsumer1} LOG = Consumer1 : Message processed. Send ACK to queue.
[2022-11-25 09:50:49,094] INFO {LogMediator} – {api:jms-publisher} LOG = Message received. Publish to queue.
[2022-11-25 09:50:49,238] INFO {LogMediator} – {proxy:jmsconsumer2} To: , WSAction: urn:mediate, SOAPAction: urn:mediate, MessageID: ID:ip-172-31-39-100.eu-central-1.compute.internal-32983-1669364529898-9:4:1:1:1, Direction: request, LOG = Consumer2 : Message consumed from queue., groupID = group2, Envelope: <?xml version=’1.0′ encoding=’utf-8′?><soapenv:Envelope xmlns:soapenv=”http://schemas.xmlsoap.org/soap/envelope/”><soapenv:Body><groupID>group2</groupID></soapenv:Body></soapenv:Envelope>
[2022-11-25 09:50:49,238] INFO {LogMediator} – {proxy:jmsconsumer2} LOG = Consumer2 : Message processed. Send ACK to queue.
Zoals we kunnen zien in de onderstaande consumentenlogboeken, heeft ActiveMQ consumer 1 gekozen om berichten te bezorgen met groupID =group1 en consumer 2 om berichten te bezorgen met groupID = group2. Vervolgens worden opeenvolgende berichten met dezelfde groeps-ID’s verzonden naar aangesloten consumers.
Deactiveer Consumer 2
Laten we nu eens kijken wat het gedrag zou zijn als we berichten verzenden wanneer één consumer offline is. Laten we in ons geval consumer 2 deactiveren terwijl consumer 1 actief is. U kunt een JMS-proxy deactiveren via Micro Integrator Dashboard of Management API (of de implementatie van de proxy ongedaan maken).
[2022-11-25 10:12:25,406] INFO {ServiceTaskManager} – JMS Polling server task stopped for service jmsconsumer2 MessageListenerTask{workerState=3, idleExecutionCount=51, idle=true, connected=true, listenerPaused=false, connectionReceivedError=false}[2022-11-25 10:12:26,083] INFO {ServiceTaskManager} – Task manager for service : jmsconsumer2 shutdown
[2022-11-25 10:12:26,084] INFO {JMSListener} – Stopped listening for JMS messages to service : jmsconsumer2
[2022-11-25 10:12:26,084] INFO {ProxyService} – {proxy:jmsconsumer2} Stopped the proxy service : jmsconsumer2
Stuur na het deactiveren van consumer 2 een bericht met ‘groupID=group2’. Dit bericht wordt nu verzonden naar consumer 1. Aangezien er geen consumer meer is gekoppeld aan deze groupID, kiest ActiveMQ een andere beschikbare consumer. In ons geval is dat consumer 1.
[2022-11-25 10:15:09,254] INFO {LogMediator} – {api:jms-publisher} LOG = Message received. Publish to queue.[2022-11-25 10:15:09,478] INFO {LogMediator} – {proxy:jmsconsumer1} To: , WSAction: urn:mediate, SOAPAction: urn:mediate, MessageID: ID:ip-172-31-39-100.eu-central-1.compute.internal-36290-1669366889587-9:5:1:1:1, Direction: request, LOG = Consumer1 : Message consumed from queue., groupID = group2, Envelope: group2
[2022-11-25 10:15:09,478] INFO {LogMediator} – {proxy:jmsconsumer1} LOG = Consumer1 : Message processed. Send ACK to queue.
Laten we nu eens kijken wat er gebeurt of consumer 2 weer online is. Activeer consumer 2 via de beheerconsole en stuur een bericht met groupID=groep 1 en met groupID=groep 2
[2022-11-25 10:16:51,513] INFO {JMSListener} – Connection attempt: 1 for JMS Provider for service: jmsconsumer2 was successful![2022-11-25 10:16:51,517] INFO {ServiceTaskManager} – Task manager for service : jmsconsumer2 [re-]initialized
[2022-11-25 10:16:51,527] INFO {ServiceTaskManager} – JMS Polling task activated with state: 1 for service jmsconsumer2
[2022-11-25 10:16:52,519] INFO {JMSListener} – Started to listen on destination : queue1 of type queue for service jmsconsumer2
[2022-11-25 10:16:52,520] INFO {ProxyService} – {proxy:jmsconsumer2} Started the proxy service : jmsconsumer2
[2022-11-25 10:17:02,386] INFO {LogMediator} – {api:jms-publisher} LOG = Message received. Publish to queue.
[2022-11-25 10:17:02,742] INFO {LogMediator} – {proxy:jmsconsumer1} To: , WSAction: urn:mediate, SOAPAction: urn:mediate, MessageID: ID:ip-172-31-39-100.eu-central-1.compute.internal-36290-1669366889587-9:6:1:1:1, Direction: request, LOG = Consumer1 : Message consumed from queue., groupID = group2, Envelope: group2
[2022-11-25 10:17:02,743] INFO {LogMediator} – {proxy:jmsconsumer1} LOG = Consumer1 : Message processed. Send ACK to queue.
Zoals we in het logboek zien, worden beide berichten verzonden naar consumer 1. Omdat beide berichtgroepen in de vorige stap door ActiveMQ aan consumer 1 zijn gekoppeld.
Een wijziging doorvoeren
Laten we nu eens kijken hoe we ActiveMQ kunnen vertellen dat deze een andere consumer moet kiezen voor een berichtgroep wanneer de berichtgroep al is toegewezen aan een consumer (in ons geval zijn beide berichtgroepberichten nu toegewezen aan consumer 1 en willen we het groep 2-bericht weer naar consumer 2 routeren). Dit kan worden gedaan door een bericht te sturen via de JMSXGroupSeq-header met een negatieve waarde.
Laten we nu onze JMS-uitgever bijwerken om JMSXGroupSeq in te stellen op -1, als inkomende verzoeken een closeGroup-transportparameter hebben.
Als broncode:
<?xml version="1.0" encoding="UTF-8"?>
<api context="/publish" name="jms-publisher" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST" uri-template="/message">
<inSequence>
<log level="custom">
<property name="LOG" value="Message received. Publish to queue."/>
</log>
<property expression="//groupID/text()" name="JMSXGroupID" scope="transport" type="STRING"/>
<filter regex="^true$" source="$trp:closeGroup">
<then>
<property name="JMSXGroupSeq" scope="transport" type="STRING" value="-1"/>
</then>
<else/>
</filter>
<property name="FORCE_SC_ACCEPTED" scope="axis2" type="STRING" value="true"/>
<property name="OUT_ONLY" scope="default" type="STRING" value="true"/>
<property name="messageType" scope="axis2" type="STRING" value="application/xml"/>
<property name="QueueName" scope="default" type="STRING" value="queue1"/>
<header expression="concat('jms:/',get-property('QueueName'),'?transport.jms.ConnectionFactory =myQueueSender')" name="To" scope="default"/>
<property action="remove" name="REST_URL_POSTFIX" scope="axis2"/>
<call>
<endpoint>
<default>
<timeout>
<duration>10000</duration>
<responseAction>fault</responseAction>
</timeout>
<suspendOnFailure>
<errorCodes>-1</errorCodes>
<initialDuration>0</initialDuration>
<progressionFactor>1.0</progressionFactor>
<maximumDuration>0</maximumDuration>
</suspendOnFailure>
<markForSuspension>
<errorCodes>-1</errorCodes>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</default>
</endpoint>
</call>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
Stuur een bericht met groupID=group2 en closeGroup:true header. Gebruik curl of SoapUI.
curl -k –location –request POST ‘https://localhost:8253/publish/message’ –header ‘Content-Type: application/xml’ –header ‘closeGroup: true’ –data ‘<groupID>group2</groupID>’
Stuur dan wat groep 2-berichten. Zoals we in de logboeken zien, bereikt het eerste groep 2-bericht met closeGroup:true(dwz JMSXGroupSeq = -1) consumer 1. Maar hierdoor werd de berichtgroep gesloten en als gevolg hiervan worden berichten van groep 2 verzonden naar een andere consumer (consumer 2).
[2022-11-29 13:13:58,784] INFO {org.apache.axis2.transport.jms.JMSListener} – Connection attempt: 1 for JMS Provider for service: jmsconsumer2 was successful![2022-11-29 13:13:58,787] INFO {org.apache.axis2.transport.jms.ServiceTaskManager} – Task manager for service : jmsconsumer2 [re-]initialized
[2022-11-29 13:13:58,787] INFO {org.apache.axis2.transport.jms.ServiceTaskManager} – JMS Polling task activated with state: 1 for service jmsconsumer2
[2022-11-29 13:13:59,796] INFO {org.apache.axis2.transport.jms.JMSListener} – Started to listen on destination : queue1 of type queue for service jmsconsumer2
[2022-11-29 13:13:59,796] INFO {org.apache.synapse.core.axis2.ProxyService} – {proxy:jmsconsumer2} Started the proxy service : jmsconsumer2
[2022-11-29 13:14:21,202] INFO {org.apache.synapse.mediators.builtin.LogMediator} – {api:jms-publisher} LOG = Message received. Publish to queue.
[2022-11-29 13:14:21,202] INFO {org.apache.synapse.mediators.builtin.LogMediator} – {api:jms-publisher} Value = Hier
[2022-11-29 13:14:21,203] INFO {org.apache.synapse.mediators.builtin.LogMediator} – {api:jms-publisher} To = jms:/queue1?transport.jms.ConnectionFactory=myQueueSender
[2022-11-29 13:14:21,203] INFO {org.apache.synapse.mediators.builtin.LogMediator} – {api:jms-publisher} To: jms:/queue1?transport.jms.ConnectionFactory=myQueueSender, MessageID: urn:uuid:5404bea4-fea1-4d97-868f-1b6af1c155f5, correlation_id: 5404bea4-fea1-4d97-868f-1b6af1c155f5, Direction: request, Envelope: group2
[2022-11-29 13:14:21,273] INFO {org.apache.synapse.mediators.builtin.LogMediator} – {proxy:jmsconsumer1} To: , WSAction: urn:mediate, SOAPAction: urn:mediate, MessageID: ID:ip-172-31-39-100.eu-central-1.compute.internal-39942-1669718798195-9:9:1:1:4, Direction: request, LOG = Consumer1 : Message consumed from queue., groupID = group2, Envelope: group2
[2022-11-29 13:14:21,273] INFO {org.apache.synapse.mediators.builtin.LogMediator} – {proxy:jmsconsumer1} LOG = Consumer1 : Message processed. Send ACK to queue.
[2022-11-29 13:14:25,397] INFO {org.apache.synapse.mediators.builtin.LogMediator} – {api:jms-publisher} LOG = Message received. Publish to queue.
[2022-11-29 13:14:25,398] INFO {org.apache.synapse.mediators.builtin.LogMediator} – {api:jms-publisher} To = jms:/queue1?transport.jms.ConnectionFactory=myQueueSender
[2022-11-29 13:14:25,399] INFO {org.apache.synapse.mediators.builtin.LogMediator} – {api:jms-publisher} To: jms:/queue1?transport.jms.ConnectionFactory=myQueueSender, MessageID: urn:uuid:6d92c98d-da75-4ea7-9a0a-7a64854b2752, correlation_id: 6d92c98d-da75-4ea7-9a0a-7a64854b2752, Direction: request, Envelope: group2
[2022-11-29 13:14:25,424] INFO {org.apache.synapse.mediators.builtin.LogMediator} – {proxy:jmsconsumer2} To: , WSAction: urn:mediate, SOAPAction: urn:mediate, MessageID: ID:ip-172-31-39-100.eu-central-1.compute.internal-39942-1669718798195-9:10:1:1:4, Direction: request, LOG = Consumer2 : Message consumed from queue., groupID = group2, Envelope: group2
[2022-11-29 13:14:30,823] INFO {org.apache.synapse.mediators.builtin.LogMediator} – {proxy:jmsconsumer2} LOG = Consumer2 : Message processed. Send ACK to queue.
[2022-11-29 13:14:36,282] INFO {org.apache.synapse.mediators.builtin.LogMediator} – {api:jms-publisher} LOG = Message received. Publish to queue.
[2022-11-29 13:14:36,283] INFO {org.apache.synapse.mediators.builtin.LogMediator} – {api:jms-publisher} To = jms:/queue1?transport.jms.ConnectionFactory=myQueueSender
[2022-11-29 13:14:36,283] INFO {org.apache.synapse.mediators.builtin.LogMediator} – {api:jms-publisher} To: jms:/queue1?transport.jms.ConnectionFactory=myQueueSender, MessageID: urn:uuid:e21cb03f-0a52-4252-a3ce-218176e33363, correlation_id: e21cb03f-0a52-4252-a3ce-218176e33363, Direction: request, Envelope: group1
[2022-11-29 13:14:36,290] INFO {org.apache.synapse.mediators.builtin.LogMediator} – {proxy:jmsconsumer1} To: , WSAction: urn:mediate, SOAPAction: urn:mediate, MessageID: ID:ip-172-31-39-100.eu-central-1.compute.internal-39942-1669718798195-9:3:1:1:5, Direction: request, LOG = Consumer1 : Message consumed from queue., groupID = group1, Envelope: group1
[2022-11-29 13:14:36,290] INFO {org.apache.synapse.mediators.builtin.LogMediator} – {proxy:jmsconsumer1} LOG = Consumer1 : Message processed. Send ACK to queue.
[2022-11-29 13:14:40,485] INFO {org.apache.synapse.mediators.builtin.LogMediator} – {api:jms-publisher} LOG = Message received. Publish to queue.
[2022-11-29 13:14:40,486] INFO {org.apache.synapse.mediators.builtin.LogMediator} – {api:jms-publisher} To = jms:/queue1?transport.jms.ConnectionFactory=myQueueSender
[2022-11-29 13:14:40,486] INFO {org.apache.synapse.mediators.builtin.LogMediator} – {api:jms-publisher} To: jms:/queue1?transport.jms.ConnectionFactory=myQueueSender, MessageID: urn:uuid:e1975933-c482-4651-8873-16b728300e47, correlation_id: e1975933-c482-4651-8873-16b728300e47, Direction: request, Envelope: group2
[2022-11-29 13:14:40,532] INFO {org.apache.synapse.mediators.builtin.LogMediator} – {proxy:jmsconsumer2} To: , WSAction: urn:mediate, SOAPAction: urn:mediate, MessageID: ID:ip-172-31-39-100.eu-central-1.compute.internal-39942-1669718798195-9:4:1:1:5, Direction: request, LOG = Consumer2 : Message consumed from queue., groupID = group2, Envelope: group2
[2022-11-29 13:14:40,532] INFO {org.apache.synapse.mediators.builtin.LogMediator} – {proxy:jmsconsumer2} LOG = Consumer2 : Message processed. Send ACK to queue.