【问题标题】:Azure Storage Queue poor performance - only 200 RPSAzure 存储队列性能不佳 - 仅 200 RPS
【发布时间】:2017-06-12 12:54:54
【问题描述】:

我使用 Asp.Net Core Web Application (.Net Core) 模板创建了一个 dotnet core web api,该模板为我们提供了 api/values 控制器,并且在帖子中我使用 Windows Azure Storage library v8 向 azure storage queue 发送消息.0. https://www.nuget.org/packages/WindowsAzure.Storage/8.0.0

目前,当我执行单个请求时,队列大约需要一个 avg。完成 AddMessageAsync() 方法需要 140 毫秒,但是当我对每秒 200 个请求进行负载测试时,相同的方法平均需要 800 毫秒才能完成。根据 azure storage queue,它应该能够每秒处理 2000 个请求,但我无法每秒处理 200 个请求。

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

请看下面我的代码示例

Startup.cs - ConfigureServices()

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

电子邮件控制器.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);
}

【问题讨论】:

  • RPS也受WebApp限制,请尝试change tier or scale out of App service plan查看RPS是否有改善?
  • 目前我的 Web 应用程序在 docker 容器中本地运行。
  • 我明白,但如果我评论这一行 await _queue.SendMessage(emailMessage);我每秒收到大约 1814 个请求,平均响应时间为 72 毫秒。有了上面我得到 152 rps 和 600ms 平均响应。
  • Azure 存储还是本地存储模拟器?如果您使用的是 Azure 存储,请尝试使用 local storage emulator 进行测试。
  • 我已经使用本地存储进行了测试,它可以正常工作,获得 200 rps 和 26 毫秒的平均响应,但是如果我更改为云队列,我会看到问题。

标签: c# asp.net azure .net-core azure-queues


【解决方案1】:

确保在应用程序启动时设置以下内容:

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

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

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

有一个很棒的博客解释了这一点:Nagle’s Algorithm is Not Friendly towards Small Requests

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

【讨论】:

    猜你喜欢
    • 2020-10-15
    • 2018-08-01
    • 2014-01-28
    • 2019-05-07
    • 2021-07-07
    • 1970-01-01
    • 1970-01-01
    • 2014-08-23
    • 2011-11-14
    相关资源
    最近更新 更多