This article explains a real-world business requirement and how Azure Service Bus Queue helps to fulfill the requirement.

Business Requirement

One of the utility bill payments company wants to build an application, which will do the mobile recharge for end users. The application should support all the operators which are available in the market. The flow is, the user sends SMS in predefined format and application should parse the message and do the recharge accordingly.

Now, the biggest challenge is the application gets a huge number of recharge requests during the peak hours and is not able to process each request, so the company is looking for something like where all the requests are parked when they come and process one by one.

Azure Service Bus

The company came to know about the Azure Service Bus provided by Azure, so he started exploring Azure Service Bus.

Azure Service Bus supports cloud-based message-oriented middleware technologies like Queue, Topic, and Relay.

Azure Service Bus

Here in order to meet the business requirement, we will use the queue mechanism where all the requests will be added in the queue and another side queue listener will process the message by reading from the queue.

Queue

Azure Service Bus

The sender sends the message, adds it into the queue and the receiver processes the message in a FIFO (First In First Out) manner. The benefit of using queue is, it creates decoupling between sender and receiver, means sender and receiver should not be available at the same time while sending the message as messages are stored in a queue. Another benefit is load leveling, which means sender sends messages at a different rate and the receiver can process messages at a different rate, as both are independent in sending and processing.

Now let's see the step by step implementation of the below to design a solution:

  1. Create Service Bus Namespace
  2. Create Queue
  3. Add a message in the queue
  4. Read Message from the queue
  5. Scheduled Message
  6. Receive Mode
  7. Abandoned Async
  8. Dead-letter Queue
Create Service Bus Namespace

Service bus namespace is a container for all messaging components. One namespace contains multiple queues and topics.

Once you create a namespace, you can explore the same from the dashboard where you can find all the details which you have provided while creating a namespace.

Azure Service Bus

Credentials

Click on 'Shared access policies' from the left panel, click on 'RootManageSharedAccessKey' to explore keys and connection strings which will be used further to connect.

Azure Service Bus
Create Queue
Add Message in the QUEUE
Read Message from QUEUE
Scheduled Message

Now let's tweak the requirement, where we want to do recharge after a specific time, not now. So for this, we have scheduled message facility where you can schedule a message for a specific time. In the demo, we will set it after 5 minutes.

In order to implement this, we need to comment SendSync method and call ScheduleMessageAsync which expects a message and schedule time.

Modify your code as below,

  1. DateTimeOffset scheduleTime = DateTime.UtcNow.AddMinutes(5);
  2. queueClient.ScheduleMessageAsync(message,scheduleTime);

We can observe in the portal that the message is not added in the queue as 'Active message count' is zero (0) only.

Azure Service Bus

Now wait for 5 minutes and verify once again in a portal. We can see that it's added as 5 minutes have passed.

Azure Service Bus

Run the read application and you can get the scheduled message.

Azure Service Bus
Receive Mode

In the next step after receiving the message, you need to process that message; i.e. need to do a recharge. Now assume that while processing the message some exception occurs, then we may lose the request completely. For this situation, we have a Receive Mode facility.

You can specify two different modes as Receive Mode:

PeekLock

In this mode, the message won't be deleted until you call CompleteAsync method, so while processing if any exception occurs, we don't lose the message.

Let's check the message in the portal, ideally, it was read by read application, so it should not be there in the portal but as Receive Mode is Peeklock, the message will be there.

Azure Service Bus

Execute CompleAsync method after processing the message.

Azure Service Bus

We can see in the portal that the message is not available as we have already called CompleteAsync.

Azure Service Bus

ReceiveAndDelete

In Receive and Delete mode, as soon as the message is read, it will be deleted from the queue.

AbandonAsync

Now in your application, whenever an exception occurs during processing you want to reprocess the message again. For this, we have the facility of AbandonAsync.

AbandonAsync abandons a Message using a lock token, this will make the message available again for processing.

To verify this we need to throw an exception explicitly from ReceiveMessageAsync and from the catch block call AbandonAsync method.

  1. static async Task ReceiveMessagesAsync(Message message, CancellationToken token)
  2. {
  3. try
  4. {
  5. Console.WriteLine($"Received message: {Encoding.UTF8.GetString(message.Body)}");
  6. int i = 0;
  7. i=i / Convert.ToInt32(message);
  8. await queueClient.CompleteAsync(message.SystemProperties.LockToken);
  9. }
  10. catch(Exception ex)
  11. {
  12. await queueClient.AbandonAsync(message.SystemProperties.LockToken);
  13. }
  14. }

Run the application once again and from the read application we can observe that the same message was read 10 times, this means whenever an exception occurs it was available once again to process.

Azure Service Bus

You can configure the reprocess count from properties by setting Maximum Delivery Count. Previously it was read 10 times because, by default, Maximum Delivery Count is set to 10.

Azure Service Bus

Once the 10-time process is over, it is no longer available in the queue, and it will be added in the Dead-letter queue. We can verify the same thing in the portal.

Azure Service Bus

Dead-letter Queue

Now, in order to read the messages from the Dead-letter queue for analyzing purposes, the same application is used, you just need to change the queue name as below:

  1. string sbQueueName = "Recharge/$DeadLetterQueue";
Run the application and it will read all messages available in Dead-letter queue.
Azure Service Bus

We don't find any messages in Dead-letter queue now.

Azure Service Bus

In the next article, we will discuss Azure Service Bus - Topic.

Note
You can download the complete sample code from here.