Let’s talk a bit more about Azure Service Bus messages and what’s different compared to MSMQ. For start, there are mechanisms to hide messages and delay their processing. This is available both in queues and topics/subscriptions.
If a message shouldn’t be processed immediately but shouldn’t be deleted for good either, you can defer it. While message is deferred it won’t show up as you perform Receive on other, normal messages.
The only way to finally Receive and process deferred message is to know its sequence number, which is a bit problematic since your application has to store it somewhere. Another way is to Peek through all messages since it shows up for Peek, just not for Receive, but that’s not practical for a production app. Btw. that’s how QueueExplorer displays deferred messages, and that’s why it can be slow if there are too many messages in the main queue.
Scheduled messages are similar to deferred, but hidden only until specified date/time. After that time Service Bus will automatically make it available for processing.
QueueExplorer displays scheduled and deferred messages as subqueues since it’s easier for a user to see them separated. Behind the scene, there aren’t actual subqueues in Service Bus, these messages are still in main queue and visible for Peek, but hidden for Receive.
DeliveryCount is a field in every Service Bus message. If message processing fails for some reason, you can return that message back to the top of the queue. When this happens – message delivery count is increased by 1. After that counter reaches 10 (default, can be changed in queue properties), message is automatically moved to the deadletter queue.
This is great for preventing poison message scenarios, where top message has some permanent problem. Since it won’t ever be processed it stays on top of the queue preventing other messages getting their turn. On the other hand, this could be undesirable if issues are only temporary – e.g. your app couldn’t connect to web service for few minutes. In that case, message could end up deadletter queue even if there’s nothing wrong with it.
So when message ends up in a deadletter queue, in most cases someone should check what was the problem, and whether the message should be returned to the main queue or not. Or whether maybe message should be edited before it’s returned. The good thing is – these messages have a reason and description, in their custom properties, of why they were deadlettered.
One problem “Delivery count” creates for tools like QueueExplorer, is that if user wants to delete the fifth message in a queue, app has to receive first four messages, receive the fifth one, and then “Abandon” first four operations. That will increase delivery count of all 4 messages! Unfortunately, Service Bus API currently doesn’t offer a way to process a message from the middle of the queue. And we have to do this same thing for scheduling or deferring message.
You can’t specify priority of messages like you could in MSMQ. If you need that functionality you’ll have to roll out your own. One possibility is to create multiple queues. In that case receiver should check all these queues, and only move to next one if higher priority queue doesn’t have messages. Similar functionality could be achieved using topic with multiple subscriptions for multiple priority levels. However, you should be careful when setting up filters for these subscriptions, so that each subscription gets only messages for that exact priority level.
In last part of this series we’ll take a look at some development aspects.
Links to all 5 parts of this series.