C# Azure存储队列性能差-仅200 RPM

C# Azure存储队列性能差-仅200 RPM,c#,asp.net,azure,.net-core,azure-queues,C#,Asp.net,Azure,.net Core,Azure Queues,我已经使用Asp.Net core web应用程序(.Net core)模板创建了一个dotnet core web api,该模板为我们提供了api/values控制器,在帖子中,我正在使用Windows azure存储库v8.0向azure存储队列发送一条消息 当前,当我执行单个请求时,队列平均需要140ms才能完成AddMessageAsync()方法,但当我每秒执行200个请求的负载测试时,相同的方法平均需要800ms才能完成。根据azure存储队列,它应该能够每秒处理2000个请求,但

我已经使用Asp.Net core web应用程序(.Net core)模板创建了一个dotnet core web api,该模板为我们提供了api/values控制器,在帖子中,我正在使用Windows azure存储库v8.0向azure存储队列发送一条消息

当前,当我执行单个请求时,队列平均需要140ms才能完成AddMessageAsync()方法,但当我每秒执行200个请求的负载测试时,相同的方法平均需要800ms才能完成。根据azure存储队列,它应该能够每秒处理2000个请求,但我不能每秒处理200个请求

如果有人能提供一些关于为什么web应用程序api不能按预期运行的信息,我将不胜感激

请看下面我的代码示例

Startup.cs-ConfigureServices()

//添加QueueAccessLayer。
services.AddSingleton();
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();
    }
}
[路由(“api/[控制器]”)]
公共类EmailController:控制器
{
专用IQueueAccessLayer_队列;
公共EmailController(IQueueAccessLayer队列)
{
_队列=队列;
}
//后api/值
[HttpPost]
公共异步任务Post([FromBody]字符串值)
{
var emailMessage=“消息Id-”+Guid.NewGuid();
等待队列。发送消息(emailMessage);
返回新的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);
}
public类QueueAccessLayer:iqueueeaccesslayer
{
私有CloudQueueClient _queueClient;
私有CloudStorageAccount\u storageAccount;
私有CloudQueue\u emailQueue;
私人ILogger_记录器;
公共队列访问层(ILogger记录器)
{
_storageAccount=CloudStorageAccount.Parse(“DefaultEndpointsProtocol=https;AccountName=test1;AccountKey=######”);
_queueClient=\u storageAccount.CreateCloudQueueClient();
_emailQueue=_queueClient.GetQueueReference(“emailQueue”);
_emailQueue.CreateIfNotExistsAsync().Wait();
_记录器=记录器;
}
公共异步任务发送消息(字符串消息)
{
秒表=新秒表();
watch.Start();
CloudQueueMessage=新的CloudQueueMessage(消息);
wait_emailQueue.AddMessageAsync(消息);
看,停;
_logger.LogInformation(msg+“-”+watch.elapsedmillisons+“ms”);
返回true;
}
}
公共接口IQueueAccessLayer
{
任务发送消息(字符串消息);
}

确保在应用程序启动时设置以下各项:

  • ServicePointManager.Expect100Continue=false
  • ServicePointManager.UseNagleAlgorithm=false Expect100Continue设置为false-将减少发送请求时到服务器端的往返次数

    UseNagleAlgorithm设置为false-将关闭Nagle优化并显著提高性能

    有一个很棒的博客解释了这一点:

    Nagling是对发送方的TCP优化,旨在通过将较小的发送请求合并为较大的TCP段来减少网络拥塞。。。这是通过保留小段来实现的,直到TCP有足够的数据来传输一个完整大小的段,或者直到所有未完成的数据都被接收器确认。。。该测试作为工作角色运行,访问同一地理位置的存储帐户。它插入长度为480字节的消息。结果表明,关闭唠叨后,平均延迟提高了600%以上


    RPS也受到WebApp的限制,请尝试检查RPS是否有任何改进?目前我的web app在docker容器中本地运行。我理解,但如果我对此行进行评论,请等待_queue.sendmage(emailMessage);我每秒收到1814个请求,平均响应72ms。通过以上操作,我获得了平均响应为600ms的152 RPM。Azure存储或本地存储模拟器?如果您正在使用Azure存储,请尝试使用进行测试。我已使用本地存储进行了测试,它可以正常工作,获得200 RPM的平均响应,但如果我更改为云队列,我会发现问题。
    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);
    }