Isaac.

azure

Azure Service Bus Messaging

Implement asynchronous messaging with Azure Service Bus.

By Emem IsaacOctober 23, 20212 min read
#azure#service bus#messaging#async#queues#topics
Share:

A Simple Analogy

Azure Service Bus is like the postal system for cloud applications. Messages are reliably delivered even if the recipient is temporarily unavailable.


Why Service Bus?

  • Decoupling: Apps don't call each other directly
  • Asynchronous: Don't wait for responses
  • Reliable: Messages persist if app is down
  • Scalable: Handle message spikes
  • Ordering: Optional FIFO guarantees

Queue Operations

using Azure.Messaging.ServiceBus;

var connectionString = "Endpoint=sb://...";
var client = new ServiceBusClient(connectionString);

// Send message
var sender = client.CreateSender("order-queue");

var message = new ServiceBusMessage("Order #123 created")
{
    ContentType = "application/json",
    Subject = "OrderCreated",
    CorrelationId = "order-123"
};

await sender.SendMessageAsync(message);

// Receive messages
var receiver = client.CreateReceiver("order-queue");

var receivedMessage = await receiver.ReceiveMessageAsync();
if (receivedMessage != null)
{
    Console.WriteLine(receivedMessage.Body);
    await receiver.CompleteMessageAsync(receivedMessage);
}

Topics and Subscriptions

// Publish to topic
var topicClient = client.CreateSender("orders-topic");

var message = new ServiceBusMessage("Order #123 created")
{
    ApplicationProperties = { { "Type", "OrderCreated" } }
};

await topicClient.SendMessageAsync(message);

// Subscribe to topic
var receiver = client.CreateReceiver("orders-topic", "email-subscription");

var message = await receiver.ReceiveMessageAsync();
if (message != null)
{
    Console.WriteLine("Email notification triggered");
    await receiver.CompleteMessageAsync(message);
}

Message Processing

public class OrderProcessor
{
    private readonly ServiceBusClient _client;
    
    public async Task StartProcessingAsync()
    {
        var receiver = _client.CreateReceiver("orders-queue");
        
        var options = new ServiceBusProcessorOptions
        {
            MaxConcurrentCalls = 10,
            AutoCompleteMessages = false
        };
        
        var processor = _client.CreateProcessor("orders-queue", options);
        
        processor.ProcessMessageAsync += MessageHandler;
        processor.ProcessErrorAsync += ErrorHandler;
        
        await processor.StartProcessingAsync();
    }
    
    private async Task MessageHandler(ProcessMessageEventArgs args)
    {
        try
        {
            var message = args.Message;
            var body = message.Body.ToString();
            
            // Process message
            await ProcessOrderAsync(body);
            
            // Complete message
            await args.CompleteMessageAsync(message);
        }
        catch (Exception ex)
        {
            // Dead letter on error
            await args.DeadLetterMessageAsync(args.Message);
        }
    }
    
    private Task ErrorHandler(ProcessErrorEventArgs args)
    {
        Console.WriteLine($"Error: {args.Exception}");
        return Task.CompletedTask;
    }
}

Dead Letter Queue

// Messages automatically go to dead letter queue after max retries
var receiver = client.CreateReceiver("orders-queue");

// Access dead letter messages
var deadLetterReceiver = client.CreateReceiver(
    "orders-queue",
    new ServiceBusReceiverOptions { SubQueue = SubQueue.DeadLetter });

var deadLetterMessage = await deadLetterReceiver.ReceiveMessageAsync();

Console.WriteLine($"Reason: {deadLetterMessage.DeadLetterReason}");
Console.WriteLine($"Error: {deadLetterMessage.DeadLetterErrorDescription}");

Best Practices

  1. Use sessions: For correlated messages
  2. Set TTL: Messages expire
  3. Partition keys: Enable message ordering
  4. Dead letter: Handle poison messages
  5. Monitor: Track queue depth

Related Concepts

  • Event Grid
  • Event Hubs
  • Logic Apps
  • Message-driven architecture

Summary

Azure Service Bus provides reliable, scalable messaging for decoupled applications. Use queues for point-to-point and topics for pub/sub patterns.

Share:

Written by Emem Isaac

Expert Software Engineer with 15+ years of experience building scalable enterprise applications. Specialized in ASP.NET Core, Azure, Docker, and modern web development. Passionate about sharing knowledge and helping developers grow.

Ready to Build Something Amazing?

Let's discuss your project and explore how my expertise can help you achieve your goals. Free consultation available.

💼 Trusted by 50+ companies worldwide | ⚡ Average response time: 24 hours