Проблема производительности сервера ASP.NET Core 2.2 kestrel - PullRequest
0 голосов
/ 31 мая 2019

У меня проблема с производительностью сервера kestrel.У меня есть следующий сценарий:

    TestClient(JMeter) -> DemoAPI-1(Kestrel) -> DemoAPI-2(IIS) 

Я пытаюсь создать пример приложения, которое может получить содержимое файла, как и по запросу.TestClient (100 потоков) запрашивает DemoAPI-1, который, в свою очередь, запрашивает DemoAPI-2.DemoAPI-2 считывает фиксированный XML-файл (не более 1 МБ) и возвращает его содержимое в качестве ответа (в производстве DemoAPI-2 не будет подвергаться воздействию внешнего мира).

Когда я тестировал прямой доступ из TestClient-> DemoAPI-2 Я получил ожидаемый результат (хороший), который выглядит следующим образом:

  1. Среднее: 368 мс
  2. Минимум: 40 мс
  3. Максимум: 1056 мс
  4. Пропускная способность: 40,1 / сек

Но когда я попытался получить к нему доступ через DemoAPI-1, я получил следующий результат:

  1. Среднее: 48232 мс
  2. Минимум: 21095мс
  3. Максимум: 49377мс
  4. Пропускная способность: 2,0 / сек

Как вы можете видеть, есть огромная разница. Я не получаю даже 10% пропускная способность DemoAPI-2.Мне сказали, что kestrel более эффективен и быстр по сравнению с традиционными IIS.Кроме того, поскольку в прямом доступе нет проблем, я думаю, что мы можем устранить возможные проблемы в DemoAPI-2.

※ Код DemoAPI-1:

string base64Encoded = null;
            var request = new HttpRequestMessage(HttpMethod.Get, url);
            var response = await this.httpClient.SendAsync(request, HttpCompletionOption.ResponseContentRead).ConfigureAwait(false);

            if (response.StatusCode.Equals(HttpStatusCode.OK))
            {
                var content = await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
                base64Encoded = Convert.ToBase64String(content);
            }
return base64Encoded;

※ Код DemoAPI-2:

[HttpGet("Demo2")]
    public async Task<IActionResult> Demo2Async(int wait)
    {
        try
        {
            if (wait > 0)
            {
                await Task.Delay(wait);
            }
            var path = Path.Combine(Directory.GetCurrentDirectory(), "test.xml");
            var file = System.IO.File.ReadAllText(path);
            return Content(file);
        }
        catch (System.Exception ex)
        {
            return StatusCode(500, ex.Message);
        }
    }

Некоторая дополнительная информация:

  1. Оба API являются асинхронными.
  2. Оба API размещены в разных экземплярах EC2 (C5.xlarge Windows Server2016).
  3. DemoAPI-1 (kestrel) является автономным API (без обратного прокси-сервера)
  4. TestClient (jMeter) для этого тестирования установлен на 100 потоков.
  5. На данный момент никакие другие настройки для сервера kestrel не выполняются.
  6. На данный момент нет фильтра действий, промежуточного программного обеспечения или журналирования, которые могли бы повлиять на производительность.
  7. Связь осуществляется с использованием SSL на 5001порт.
  8. Параметр ожидания для DemoAPI2 на данный момент установлен на 0.
  9. Загрузка ЦП DEMOAPI-1 не превышает 40%.

Ответы [ 2 ]

0 голосов
/ 31 мая 2019

Проблема была связана с проблемой исчерпания порта HttpClient. Я смог решить эту проблему с помощью IHttpClientFactory. Следующая статья может помочь тому, кто сталкивается с подобной проблемой.

https://www.stevejgordon.co.uk/httpclient-creation-and-disposal-internals-should-i-dispose-of-httpclient

0 голосов
/ 31 мая 2019

DEMOAPI-1 выполняет несинхронное чтение потоков:

var bytes = stream.Read(read, 0, DataChunkSize);

while (bytes > 0)
{
  buffer += System.Text.Encoding.UTF8.GetString(read, 0, bytes);
  // Replace with ReadAsync
  bytes = stream.Read(read, 0, DataChunkSize);
}

Это может быть проблемой с пропускной способностью для партиизапросов.

Кроме того, я не совсем понимаю, почему вы не тестируете один и тот же код с IIS и Kestrel, я бы предположил, что вам нужно вносить только изменения среды, а не код.

...