Тест пропускной способности ASP.NET Core 5.0 в Kestrel, IIS, Nginx и Caddy

в 14:03, , рубрики: Без рубрики

Начиная с версии 2.2. ASP.NET Core поддерживает режим внутрипроцессного размещения приложения (InProcess) в IIS, направленный на улучшение производительности кода. Рик Страл написал статью, в которой подробно исследовал эту тему. С тех пор прошло три года, теперь платформа ASP.NET Core добралась до версии 5.0. Как это повлияло на производительность ASP.NET Core-проектов на различных серверах?

Тест пропускной способности ASP.NET Core 5.0 в Kestrel, IIS, Nginx и Caddy - 1

Результаты исследования Рика Страла

Рик Страл в своей статье занимался тестирование ASP.NET Core-кода на Windows — в Kestrel и в IIS (в режимах InProcess и OutOfProcess). Его интересовало количество запросов в секунду, обрабатываемых системой. В результате он пришёл к выводу о том, что первое место по производительности получает использование IIS в режиме InProcess, второе — Kestrel, третье — IIS в режиме OutOfProcess.

Обзор эксперимента

Рик не провёл испытания, позволяющие выявить различия в выполнении ASP.NET Core-кода на Windows- и на Linux-серверах. А вопрос о том, что в 2021 году лучше выбрать для проектов, основанных на ASP.NET Core 5.0, интересует многих из тех, кого я знаю. Поэтому я решил, используя подход к тестированию, похожий на тот, которым пользовался Рик, узнать о том, сколько запросов в секунду может обработать ASP.NET Core 5.0-приложение на Windows и на Linux.

Тестовое окружение

Так как Windows 10, Ubuntu Desktop и другие настольные операционные системы не в полной мере отражают особенности сопоставимых с ними серверных дистрибутивов, я решил выбрать для тестов серверные версии соответствующих ОС. Это были свежеустановленные копии систем с последними патчами, перед выполнением тестов они были один раз перезагружены.

▍Windows-сервер:

  • Провайдер: Microsoft Azure East Asia Region.
  • ОС: Windows Server 2019 Data Center.
  • Характеристики системы: B2S / 2 vCPU, 4GB RAM, Premium SSD.
  • Окружение: IIS с поддержкой статического и динамического сжатия контента, отсутствие интеграции с ASP.NET 3.5 или 4.x, на сервере установлена платформа ASP.NET Core 5.0.2 Runtime.

Тест пропускной способности ASP.NET Core 5.0 в Kestrel, IIS, Nginx и Caddy - 2

Сведения о Windows-сервере

▍Linux-сервер

  • Провайдер: Microsoft Azure East Asia Region.
  • ОС: Ubuntu Server 20.04 LTS.
  • Характеристики системы: B2S / 2 vCPU, 4GB RAM, Premium SSD.
  • Окружение: включено использование BBR, установлены Nginx, Caddy и ASP.NET Core 5.0.2 Runtime.

Тест пропускной способности ASP.NET Core 5.0 в Kestrel, IIS, Nginx и Caddy - 3

Сведения о Linux-сервере

▍Инструменты для проведения тестов

Рик пользовался West Wind Web Surge, но этот инструмент доступен только на платформе Windows, а это нас не устроит. Я решил воспользоваться опенсорсным кросс-платформенным инструментом bombardier, о котором однажды писали в официальном .NET-блоге Microsoft.

▍Тестовое приложение

Я создал новый проект ASP.NET Core 5.0 Web API, в котором имеется лишь один метод:

[ApiController]
[Route("[controller]")]
public class TestController : ControllerBase
{
    [HttpGet]
    public string Get()
    {
        return $"Test {DateTime.UtcNow}";
    }
}

Для того чтобы не усложнять проект, я не проверял JSON-сериализацию и другие механизмы. Вы, если вам это интересно, вполне можете исследовать их самостоятельно.

Проект скомпилирован с применением конфигурации Release и опубликован с использованием FDD. Настройки логирования оставлены в стандартном состоянии:

"LogLevel": {
  "Default": "Information",
  "Microsoft": "Warning",
  "Microsoft.Hosting.Lifetime": "Information"
}

▍Методика тестирования

Я запускал проект, используя следующие конфигурации:

  • Kestrel.
  • IIS в режиме InProcess.
  • IIS в режиме OutOfProcess.
  • Обратный прокси Nginx.
  • Обратный прокси Caddy.

Затем я применял bombardier. В течение 10 секунд, по 2 соединениям, велась работа с конечной точкой, доступной на localhost. После «прогревочного» раунда испытаний я, друг за другом, проводил ещё 3 раунда и на основе полученных данных вычислял показатель количества запросов, обработанных исследуемой системой за секунду (Request per Second, RPS).

Пожалуйста, обратите внимание на то, что в идеальном случае лучше не использовать инструмент для исследования производительности, обращаясь с его помощью к локальным адресам. Дело в том, что при таком подходе операционная система вынуждена будет делить сетевые ресурсы между инструментом для тестирования и исследуемой программой. Но, так как сети в облачных окружениях не так стабильны, как localhost-подключение, я решил использовать в тестах именно локальное подключение. Это позволило исключить воздействие особенностей сети на результаты.

Результаты тестов

▍Windows + Kestrel

Средний RPS: 18808

Тест пропускной способности ASP.NET Core 5.0 в Kestrel, IIS, Nginx и Caddy - 4

Windows + Kestrel

▍Windows + IIS в режиме InProcess

Средний RPS: 10089

Тест пропускной способности ASP.NET Core 5.0 в Kestrel, IIS, Nginx и Caddy - 5

Windows + IIS в режиме InProcess

▍Windows + IIS в режиме OutOfProcess

Средний RPS: 2820

Тест пропускной способности ASP.NET Core 5.0 в Kestrel, IIS, Nginx и Caddy - 6

Windows + IIS в режиме OutOfProcess

▍Linux + Kestrel

Средний RPS: 10667

Тест пропускной способности ASP.NET Core 5.0 в Kestrel, IIS, Nginx и Caddy - 7

Linux + Kestrel

▍Linux + Nginx

Средний RPS: 3509

Тест пропускной способности ASP.NET Core 5.0 в Kestrel, IIS, Nginx и Caddy - 8

Linux + Nginx

▍Linux + Caddy

Средний RPS: 3485

Тест пропускной способности ASP.NET Core 5.0 в Kestrel, IIS, Nginx и Caddy - 9

Linux + Caddy

Итоги

Вот как выглядят результаты тестирования (от самой быстрой комбинации ОС и серверного ПО — до самой медленной):

  • Windows + Kestrel (18808)
  • Linux + Kestrel (10667)
  • Windows + IIS в режиме InProcess (10089)
  • Linux + Nginx (3509)
  • Linux + Caddy (3485)
  • Windows + IIS в режиме OutOfProcess (2820)

Мои результаты отличаются от тех, что получил Рик, тестируя ASP.NET Core 2.2-проект. В его тестах производительность IIS в режиме InProcess оказывалась выше, чем производительность Kestrel. Но сейчас Kestrel оказывается быстрее IIS в режиме InProcess, и это кажется вполне логичным и ожидаемым.

А вот неожиданностью для меня стало то, что производительность Windows-серверов c Kestrel оказалась выше производительности аналогичных Linux-серверов. Это меня удивило.

В режиме обратного прокси-сервера Nginx и Caddy, в общем-то, показывают одинаковую производительность. И та и другая конфигурации обходят IIS в режиме OutOfProcess.

Конечно, мой простой тест, в ходе которого сервер возвращает обычную строку, не позволяет проверить все нюансы производительности ASP.NET Core 5.0 и исследовать возможности каждого сервера. В реальных проектах присутствует множество факторов, которые воздействуют на производительность. План моего эксперимента не перекрывает все возможные сценарии использования ASP.NET Core 5.0, в нём, наверное, имеются какие-то недочёты. Если вы что-то такое заметите — дайте мне знать.

Дополнение

Мне сообщили, что в .NET 5 у DateTime.UtcNow могут быть проблемы, касающиеся производительности. Я провёл повторные испытания, заменив эту конструкцию на Activity.Current?.Id ?? HttpContext.TraceIdentifier. Получившиеся у меня результаты были выражены немного более высокими показателями, но общая картина осталась почти такой же.

А если увеличить число подключений с 2 до 125 — сервер Kestrel, и на Windows, и на Linux, способен дать гораздо более высокую пропускную способность.

Каким серверным ПО вы пользуетесь в своих проектах?

Тест пропускной способности ASP.NET Core 5.0 в Kestrel, IIS, Nginx и Caddy - 10


Тест пропускной способности ASP.NET Core 5.0 в Kestrel, IIS, Nginx и Caddy - 11

Автор: ru_vds

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js