For the last part of this short series, let’s take a glance at some high-level differences between Azure Service Bus and MSMQ from developer’s point of view. We can’t cover much in a single blog post and, so let’s just mention few things to get you started.
Story of two APIs
Actually, Azure Service Bus has a lot of APIs, if we count different libraries for multiple languages and runtimes, REST or AMQP protocols… However what we’re interested in here are .Net APIs, since that’s the platform of choice for most MSMQ developers.
At the moment of writing (December 2017) there’s a slight confusion because there are 3 separate NuGet packages you can use in your .Net project.
- Older API
WindowsAzure.ServiceBus, requires .Net 4.5.2. It’s comprehensive, contains stuff for using queues, topics, and subscriptions, but also for managing them (create, delete, etc).
- New API
It consists of two NuGet packages, which require .Net Standard 2.0:
Microsoft recommendation is to go with new packages. However, if you need to manage queues, topics or subscriptions from your code, new management API still can’t replace old WindowsAzure.ServiceBus library.
You’ll need some access keys to work with Azure Service Bus from your app. You can create and take these keys, or connection strings, from Azure Portal.
These keys can be issued for the entire namespace, or just for queues or topics you want your app to access.
Message processing modes
Azure Service bus has two different modes of processing messages, “Receive and Delete” and “Peek and Lock”. First one, ReceiveAndDelete is similar to MSMQ’s Receive operation – message is immediately removed from a queue.
PeekAndLock is a bit different. As soon as you receive message using that mode, it will disappear from a queue and won’t be visible to other receivers. But it won’t be actually deleted yet. That part makes it different from MSMQ Peek operation. In Service Bus terminology message will be locked.
If your processing succeeds, you’ll perform “Complete” operation and only then message will be deleted from a queue. If on the other hand there’s some problem, you’ll execute “Abandon” operation and message will be unlocked and other receivers will see it again. Also, if you neither Complete or Abandon, after certain timeout your lock will be released, same as if you performed Abandon.
The important thing to remember is that if lock timeout expires or you manually Abandon operation – message’s Delivery Count will be increased by 1, and if it reaches 10 (default) message will be deadlettered. There are more details about DeliveryCount in previous post.
You also have an option to renew lock, i.e. increase time allocated for processing, or to immediately move message to deadletter queue, defer or schedule it for later.
“Receive and Delete” and “Peek and Lock” are two modes of Receive operation. There’s also a Peek operation, which shouldn’t be confused with “Peek and Lock” mode for Receive. Peek works just as it did in MSMQ, returns messages without modifying queue whatsoever.
MSMQ applications always work with local Message Queueing service, located on that same machine. These operations are fast and latency is negligible. Even if you send a message to another machine you actually only talk to local MSMQ, which then puts messages in an outgoing queue and continues sending on its own pace. MSMQ will have significant latency only if you receive messages from a remote machine, and that’s not generally recommended approach.
Performance issues are quite different with Azure Service Bus with its distributed, online nature. If you need to process or send many messages, latency will be a big factor. If for instance there’s a 100ms latency between your application and Service Bus, it could happen that you won’t be able to send or receive more than 10 messages per second! Yes, it can be quicker if you’re using async methods and do stuff in parallel, but generally speaking, latency can kill your performance.
Fortunately, Service Bus send and receive operations can work in batch mode – e.g. you can send or receive tens or hundred messages without roundtrips to a server for each message. However, batch sending is not as straightforward as it could be – batch can’t be larger than max message size, so you’ll have to estimate the size of each message to make sure you don’t go over that limit.
Azure Service Bus supports transactions, except in Basic tier. These transactions are equivalent to internal transactions in MSMQ, i.e. they can only include operations from one message broker. There are no distributed transactions like in MSMQ, i.e. no way to integrate database calls with queue operations in single atomic “do all or do nothing” operation. Here’s what Clemens Vasters, a Team Lead of Azure Service Bus team at Microsoft:
Where to go next
There’s a lot more that can be discussed about Azure Service Bus but it would go out of the scope of this short series. I hope this helped you get a quick overview of what Azure Service Bus is and what can be done with it. At the end, here are some resources:
Service Bus Messaging Documentation – on Microsoft site.
Sean Feldman’s blog – Sean has a lot of interesting and useful stuff about Azure Service Bus on his blog.
QueueExplorer (yep, our own product) – the best way to work with Azure Service Bus during development, testing, or production usage.
Links to all 5 parts of this series.