Brahim Bousnguar

Learn · MuleSoft · Lesson 3 of 8

Queues: VM and Anypoint MQ

By · · 6 min read · 4 live labs

A queue lets one flow drop off work and move on, while another flow picks it up when it can. In Mule you have two: the VM connector, whose queues live inside the app, and Anypoint MQ, a cloud broker that any app can reach. Both get the work done; they differ in what survives a crash and in who decides when a message is really finished.

This lesson keeps the orders app. post-order takes the order, and booking it at the warehouse becomes somebody else's job. Each diagram plays by itself while it's on screen. The buttons change the story; the arrows step through it.

Hand off the work, or wait for it

The VM connector gives an app its own queues. VM Publish puts the message in a queue and returns straight away. A VM Listener in another flow takes it, with 4 consumers working in parallel by default. The publishing flow gets no notice of how the work went.

When you do need the answer, VM Publish Consume puts the message in the queue and waits for a reply on a temporary reply-To queue, 5 seconds by default. If the receiving flow fails, the caller gets VM:PUBLISH_CONSUMER_FLOW_ERROR. If nobody answers in time, VM:QUEUE_TIMEOUT.

Lab 1 · Handing work to a VM queue

Order in

post-order hands an order to process-order through the VM queue orders. With VM Publish, post-order answers the client at once and never hears whether process-order succeeded or failed. With VM Publish Consume, post-order waits for the reply on a temporary reply-To queue: it gets process-order's result as its payload, or VM:PUBLISH_CONSUMER_FLOW_ERROR when process-order fails.

post-order uses
process-order

flow post-order

  1. HTTP ListenerPOST /orders
  2. VM Publishqueue: orders

flow process-order

  1. VM Listenerqueue: orders
  2. HTTP Requestwarehouse API
  3. Loggerbooked

VM queue and caller

orders
empty
caller
waiting

Run Publish with process-order failing and watch the caller row: "answered, unaware". That's the deal with fire-and-forget. If someone has to hear about a failure, process-order must report it itself.

Transient or persistent

A VM queue is transient unless you say otherwise. Transient queues are held in memory: fast, and not reliable if the system crashes. A persistent queue is written to disk on a single runtime, or kept in the memory grid when the runtime is part of a cluster. It's slower, and the data you publish has to be serializable.

Lab 2 · A crash with orders in the queue

Three orders waiting

Three orders wait in the VM queue orders when the Mule runtime crashes. With a transient queue, held in memory, the queue is empty after the restart and the three orders are lost. With a persistent queue, stored on disk or in the cluster's memory grid, the orders are still there after the restart and the VM Listener processes them.

Queue type

one Mule app

  1. VM Publishpost-order
  2. VM queueorders
  3. VM Listenerprocess-order

VM queue

orders
3 messages
storage
memory (transient, the default)

Two limits to know before you count on this. Persistent VM queues aren't available on CloudHub 2.0 or Runtime Fabric. And VM queues are visible only to the components that use the same VM configuration, so two different apps can share one only through a shared domain, which means running on premises.

Anypoint MQ: the queue lives outside the app

Anypoint MQ queues live in the cloud, outside every app. One app publishes, another subscribes, and they can be deployed, scaled and restarted on their own schedules. Apps that aren't Mule can use it too, over REST.

The key idea is the acknowledgement. When the Subscriber takes a message, the message goes in flight: other consumers can't see it, but it isn't deleted. An ACK deletes it. A NACK puts it back in the queue to be delivered again. The acknowledgement mode decides who sends which.

  • AUTO, the Subscriber's default: ACK when the flow ends without an error, NACK when it fails.
  • IMMEDIATE, the Consume operation's default: ACK as soon as the message is received, before your flow has done anything.
  • MANUAL: your flow calls ACK or NACK itself, with the message's ack token.

Lab 3 · Acknowledgement decides what a failure costs

Published

The order-api app publishes an order to the Anypoint MQ queue orders, and the fulfilment app's Subscriber takes it. In AUTO mode a successful flow acknowledges and deletes the message; a failing flow nacks it back into the queue, it is delivered again, and after the tenth failed delivery Anypoint MQ moves it to the dead-letter queue orders-dlq. In IMMEDIATE mode the message is acknowledged and deleted on arrival, so when the flow fails the order is gone and never redelivered.

Acknowledgement mode
on-order

app order-api

  1. Anypoint MQ Publishqueue: orders

Anypoint MQ, outside both apps

  1. Queueorders · DLQ after 10
  2. Queueorders-dlq

app fulfilment · flow on-order

  1. Anypoint MQ Subscriberqueue: orders
  2. HTTP Requestwarehouse API

Anypoint MQ

orders
1 in queue · 0 in flight
orders-dlq
empty

IMMEDIATE with a failing flow is the one to remember. The message was deleted before the flow ran, so nothing redelivers it and the dead-letter queue never sees it. AUTO is safer, but it brings a question of its own: what if the flow is slow?

A slow consumer gets the message twice

The lock on an in-flight message has a time limit: the acknowledgement timeout. The connector uses 2 minutes when you don't set one, and a queue allows up to 12 hours. If the flow is still running when the lock expires, the message goes back to the queue, and another consumer can take it.

Lab 4 · A consumer slower than its lock

Replica 1 takes it

The fulfilment app runs two replicas that subscribe to the orders queue, with a 2-minute acknowledgement timeout. When an order takes 30 seconds, replica 1 acknowledges it in time and it is deleted. When an order takes 3 minutes, the lock expires at 2 minutes, the message returns to the queue, replica 2 takes it with a delivery count of 2, and both replicas process the same order.

One order takes

fulfilment · replica 1 · flow on-order

  1. Anypoint MQ Subscriberqueue: orders
  2. HTTP Requestwarehouse API

fulfilment · replica 2 · flow on-order

  1. Anypoint MQ Subscriberqueue: orders
  2. HTTP Requestwarehouse API

Anypoint MQ

orders
0 in queue · 1 in flight
lock
2 min left
attributes
Delivery Count: 1

So with the 3-minute order, the same booking runs twice. That isn't a bug in Anypoint MQ: standard queues deliver at least once and the docs say a message is occasionally delivered more than once anyway. Set the timeout above your slowest run, and make the work safe to repeat, for example by checking the order id before booking.

VM or Anypoint MQ

The docs don't put the two side by side, but what they say about each points one way.

  • VM queues are for work inside one app: passing messages between flows instead of a Flow Reference, spreading work across a cluster, or apps in the same domain on premises.
  • Anypoint MQ is for work between apps, and for apps with different life cycles or maintenance windows. A standard queue holds unlimited messages of up to 10 MB each, for up to two weeks.
  • On CloudHub 2.0 and Runtime Fabric there's no persistent VM queue, so anything that must survive a restart goes through Anypoint MQ.

Check yourself

Three questions on what you just ran. Pick an answer to see why.

  1. post-order uses VM Publish, and process-order fails on the warehouse call. What does post-order see?

    • VM:PUBLISH_CONSUMER_FLOW_ERROR
    • Nothing: it has already moved on
    • VM:QUEUE_TIMEOUT after 5 seconds
    Answer

    Nothing. VM Publish returns as soon as the message is in the queue and gets no notice of the outcome. Only Publish Consume waits for the receiving flow.

  2. A Subscriber in IMMEDIATE mode takes an order, and the flow fails. Where is the order now?

    • Back in the queue, to be delivered again
    • In the dead-letter queue
    • Nowhere: it was deleted before the flow ran
    Answer

    Nowhere. IMMEDIATE acknowledges the message on arrival, so Anypoint MQ deleted it before the flow failed and doesn't redeliver it.

  3. An order takes 3 minutes to process, and the acknowledgement timeout is 2 minutes. What can happen?

    • Anypoint MQ waits until the flow finishes
    • The message is delivered again while the first run is still going
    • The Subscriber stops with a timeout error
    Answer

    It's delivered again. When the lock expires the message returns to the queue, another consumer can take it, and the same order is processed twice.

Where the facts come from

Every claim in this lesson was checked against the MuleSoft documentation:

Two things I left out on purpose. What a full VM queue does depends on maxOutstandingMessages, and the docs disagree on what its default of 0 means. And no Mule 4 page says what happens to a VM message when a listener without a transaction fails. Next up is Anypoint MQ exchanges: one publish, several queues. If a lab does something Mule wouldn't, tell me. The contact links are right below.

Plain text: queues.md · All tracks

Contact

Say hello.

b.bousnguar@gmail.com

SAP Commerce Cloud, MuleSoft and Salesforce integration · Nantes · EN / FR