The level of message delivery assurance is handled by the quality of service (qos), which is the term used to describe the amount of processing that takes place to ensure that a message is transferred between the client and server.


The MQ Light API supports two qualities of service:

  • At most once [message delivery] – a message will usually be transferred once, however situations may arise when a message will never reach a recipient. Messages are never transferred more than once (e.g. duplicated).
  • At least once [message delivery] – a message will usually be transferred once, however situations may arise when a message is transferred or duplicated more than once. At least one copy of a message will be transferred to a recipient.

 

Every time a message is sent from the client to the MQ Light server, or received by the client from the MQ Light server it is transported using one of these two qualities of service. You can specify the quality of service to use on the client.send(...) method call, or the client.subscribe(...) method call. If you do not specify a quality of service – then you will get the default quality of service, which is ‘at most once’.


Choosing a quality of service

The criteria for choosing between qualities of service is: “how reliably does your application needs to transport data?”

 



For some use-cases losing a piece of data could be (very) undesirable. For example, if your application is recording customer orders to a database, it will likely want to do this reliably so as no orders are ever lost. In these situations it is recommended that you use the ‘at least once‘ quality of service for sending and receiving message – more on this below.

 



Where some data loss is tolerable – perhaps you are scraping logs, where transferring most of the entries is good enough – or where a piece of data represents an absolute value with a short lifetime – for example, when publishing a system’s load average – then consider using the ‘at most once‘ quality of service.

 



Finally, its worth noting that when deployed to reliable infrastructure, both qualities of service will deliver a message exactly once for the vast majority of the time. Message loss or duplication will typically only occur when something interrupts the status quo, such as a network glitch, or an MQ Light client process being ended.


Getting started

How do qualities of service work? If you’re not concerned about the details, it’s still worth taking a quick look at the description of ‘at least once‘ as this explains what can be seen as the mysterious act of confirming a message delivery.

 



The mechanics of the ‘at most once‘ quality of service are quite straight forward. If A wants to transfer a message to B, as illustrated below, it sends it over the network. If a problem occurs at any point after A has started to send the message – it gives up. B may or may not receive the message, but it certainly won’t get duplicates!

 



at-most-once

 



At least once‘ quality of service starts off in the same way as ‘at most once‘ quality of service, but when B receives a message, it must send data over the network to confirm that it has indeed received the message. A only considers the message successfully transferred when it receives the confirm transmission – and can opt to send the message again if it never receives a confirmation that the message arrived at B. This is illustrated below:

 



at-least-once

 



When a client receives a message using the ‘at least once‘ quality of service, by default the client will automatically send the confirmation. This happens as soon as any event listeners registered for the message event return.

 



Your application can opt to control when the message is confirmed, using the autoConfirm property passed in to the subscribe(...) method. When autoConfirm is set to false, your application must call a confirmDelivery(...) method to send the confirm transmission for each message it receives.

 



Why would you want to write an application that explicitly confirms each message it receives? The next section explains a possible use-case.


Explicitly confirming message delivery

By way of an example – imagine you have been tasked to write an application that accepts customer orders, encoded as messages, and make a record of the order in a database. Receiving messages using ‘at most once‘ quality of service would be a poor design choice, as some orders might go missing.

 



Implementing the application using ‘at least once‘ quality of service is a better choice – but only with careful consideration of when the receipt of a message is confirmed. If messages are confirmed before their payloads are written into the database, this exposes a timing window, where a failure of the application could result in orders being lost. The trick is to ensure that receipt of a message is only confirmed once the database has been updated.

It may be necessary to explicitly confirm the delivery of a message when some other operation completes – and invokes its associated callback. The following code snippet illustrates this:



Because ‘at least once‘ quality of service is used to receive the messages, it is possible that messages could be received more than once. This means that updates to the database must be idempotent (for example, trying to add an order that is already present in the database must have no effect).

 



Finally, a note of caution: if your application elects to explicitly confirm the delivery of messages, you should take care to ensure that the delivery of each message is confirmed. If an application has received too many messages that it has not confirmed, then the MQ Light server will stop delivering messages to the application until it confirms some of these messages.

Join The Discussion

Your email address will not be published.