user1754675
user1754675

Reputation: 897

Azure Storage Queue poor performance - only 200 RPS

I have created a dotnet core web api using Asp.Net Core Web Application (.Net Core) template which gives us api/values controller and on the post i am sending a message to azure storage queue using Windows Azure Storage library v8.0. https://www.nuget.org/packages/WindowsAzure.Storage/8.0.0

Currently when i do a single request, the queue takes about an avg. 140ms to complete the method AddMessageAsync() but when i do a load test for 200 request per second the same method takes an average 800ms to complete. According to azure storage queue it should be able to handle 2000 request per sec but i am not able to get 200 request per second.

I would appreciate if someone to provide an some information as why web application api not performing as expected.

Please see below my code example

Startup.cs - ConfigureServices()

// Add QueueAccessLayer.
services.AddSingleton<IQueueAccessLayer, QueueAccessLayer>();

Emailcontroller.cs

[Route("api/[controller]")]
public class EmailController : Controller
{
    private IQueueAccessLayer _queue;

    public EmailController(IQueueAccessLayer queue)
    {
        _queue = queue;
    }

    // POST api/values
    [HttpPost]
    public async Task<IActionResult> Post([FromBody]string value)
    {
        var emailMessage = "Message Id - " + Guid.NewGuid();
        await _queue.SendMessage(emailMessage);
        return new EmptyResult();
    }
}

QueueAccessLayer.cs

public class QueueAccessLayer : IQueueAccessLayer
{
    private CloudQueueClient _queueClient;         
    private CloudStorageAccount _storageAccount;

    private CloudQueue _emailQueue;
    private ILogger<QueueAccessLayer> _logger;


    public QueueAccessLayer(ILogger<QueueAccessLayer> logger)
    {
        _storageAccount = CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;AccountName=test1;AccountKey=#####;");
        _queueClient = _storageAccount.CreateCloudQueueClient();
        _emailQueue = _queueClient.GetQueueReference("emailqueue");
        _emailQueue.CreateIfNotExistsAsync().Wait();

        _logger = logger;
    }

    public async Task<bool> SendMessage(string msg)
    {
        Stopwatch watch = new Stopwatch();
        watch.Start();
        CloudQueueMessage message = new CloudQueueMessage(msg);
        await _emailQueue.AddMessageAsync(message);
        watch.Stop();

        _logger.LogInformation(msg + " - " + watch.ElapsedMilliseconds + "ms");
        return true;
    }
}

public interface IQueueAccessLayer
{
    Task<bool> SendMessage(string msg);
}

Upvotes: 3

Views: 916

Answers (1)

yonisha
yonisha

Reputation: 3096

Make sure to set the following on application startup:

  1. ServicePointManager.Expect100Continue = false;
  2. ServicePointManager.UseNagleAlgorithm = false;

Expect100Continue set to false - will reduce roundtrips to server side when sending requests.

UseNagleAlgorithm set to false - will turn off Nagle optimization and dramatically improve performance.

There's a great blog that explains this: Nagle’s Algorithm is Not Friendly towards Small Requests .

Nagling is a TCP optimization on the sender and it is designed to reduce network congestion by coalescing small send requests into larger TCP segments... This is achieved by holding back small segments either until TCP has enough data to transmit a full sized segment or until all outstanding data has been acknowledged by the receiver... The test is run as a worker role accessing our storage account in the same geo location. It inserts messages which are 480 bytes in length. The results show that the average latency improves by more than 600% with Nagling turned off

Upvotes: 1

Related Questions