Process several thousand messages with a single Service Bus sender

81 Views Asked by At

I am utilizing Azure Service Bus with a .NET Core 3.1 application. My application receives thousands of requests and places them in the topic. The question I want to ask is whether I should create a new sender for each message or if a single sender should process all messages. My current implementation is:

private async Task EnqueueAsync(ServiceBusMessage message, string queueOrTopicName)
{
    var sender = _serviceBusClient.CreateSender(queueOrTopicName);
    try
    {
        await sender.SendMessageAsync(message);
        _logger.Info($"Message has been published to {queueOrTopicName}");
    }
    catch (ServiceBusException ex)
    {
        _logger.Error($"Error while publishing data to the Service bus: {ex}");
        throw new QueueException("Unable to publish data.");
    }
    finally
    {
        await sender.DisposeAsync();
    }
}

ServiceBusClient is registered as a Singleton and the topic has 5 subscriptions so far.

2

There are 2 best solutions below

2
RithwikBojja On

Below is code with which i am able to send multiple messages by creating one sender instance:

using Azure.Messaging.ServiceBus;
public class RithwikTest
{
    private readonly ServiceBusClient rsc;
    private readonly ServiceBusSender rith_sender;
    private int rithcounter=0;
    public RithwikTest(ServiceBusClient serBusClient, string x)
    {
        rsc = serBusClient;
        rith_sender = rsc.CreateSender(x);
        rithcounter++;
    }
    public int GetSenderCount()
    {
        return rithcounter;
    }
    public async Task EnqueueAsync(ServiceBusMessage info)
    {
            await rith_sender.SendMessageAsync(info);
            Console.WriteLine($"Hello Rithwik Bojja, Message has sent to : {rith_sender.EntityPath}");  
    }
    public static async Task Main(string[] args)
    {
        string rithcon = "Endpoint=sb://pysdksb.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=1ienlgav4=";
        string queOrTop = "rithq";
        var sbc = new ServiceBusClient(rithcon);
        var test = new RithwikTest(sbc, queOrTop);
        for (int i = 0; i < 3; i++)
        {
            var info = new ServiceBusMessage($"Message is {i}");
            await test.EnqueueAsync(info);
        }
        Console.WriteLine($"Hello Rithwik, Total sender instances created and count: {test.GetSenderCount()}");
    }
}

Output:

enter image description here

enter image description here

You can integrate your code with your messages.

1
Ask On

Based on the following 2 docs, I can safely use a single sender to process all messages.

I've created a IServicebusSenderProvider and registered it as a singleton and in the constructor of the class, I've called this._serviceBusClient.CreateSender(topicName); and then used IServiceBusSenderProvider in MessageSender class.

https://github.com/Azure/azure-service-bus/issues/245 https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-performance-improvements?tabs=net-standard-sdk-2