Как настроить asp.net kestrel для низкой задержки? - PullRequest
0 голосов
/ 09 января 2019

Я пытаюсь реализовать приложение asp.net 2.2 для обслуживания HTTP-запросов с наименьшей возможной задержкой (не пропускная способность, это не для производства, а для какой-то конкуренции). Предполагается, что приложение будет работать в среде контейнера Docker для Linux с 4 ядрами, а мои обработчики связаны с процессором по 0,2 ... 3 мс каждый. Соединения предварительно созданы и поддерживаются в рабочем состоянии, но в настоящее время я получаю около 0,6 ... 0,8 мс времени обработки для пустых обработчиков (отвечая 200 OK), с заметным дрожанием и случайными скачками до 20-50 мс, что я не могу объяснить.

Существуют ли какие-либо конкретные настройки Kestrel / Sockets / Threads / CLR, которые могут помочь минимизировать время ответа на каждый запрос? Или маршрут C / C ++ с EPOLL - мой единственный вариант, если я хочу уменьшить его до 0.1..0.2 мс?

Ответы [ 2 ]

0 голосов
/ 19 января 2019

Спасибо всем, кто ответил. В итоге я реализовал собственный HTTP-сервер с системными вызовами epoll_wait (), это был единственный способ снизить задержку до необходимого мне уровня. Кестрел предлагал примерно в 2-2,5 раза большую задержку.

Пожалуйста, имейте в виду, что Kestrel по-прежнему является отличным выбором для большинства производственных нужд, он оптимизирован для максимальной производительности с разумной задержкой.

0 голосов
/ 09 января 2019

Низкая задержка, безусловно, возможна с ASP.NET Core / Kestrel.

Вот крошечное веб-приложение, демонстрирующее это ...

using System.Net;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;

public static void Main(string[] args)
{
    IWebHost host = new WebHostBuilder()
        .UseKestrel()
        .Configure(app =>
        {
            // notice how we don't have app.UseMvc()?
            app.Map("/hello", SayHello);  // <-- ex: "http://localhost/hello"
        })
        .Build();

    host.Run();
}

private static void SayHello(IApplicationBuilder app)
{
    app.Run(async context =>
    {
        // implement your own response
        await context.Response.WriteAsync("Hello World!");
    });
}

Я уже много раз отвечал на подобные вопросы до здесь и здесь .

Если вы хотите сравнить среду ядра ASP.NET с другими, это отличный визуальный элемент https://www.techempower.com/benchmarks/#section=data-r16&hw=ph&test=plaintext. Как видите, ASP.NET Core имеет исключительные результаты и является ведущей платформой для C #.

В моем блоке кода выше я отметил отсутствие app.UseMvc(). Если вам это нужно, я сделал очень подробный ответ о том, как увеличить задержку в этом ответе: В чем разница между AddMvc () и AddMvcCore ()?


.NET Core Runtime (CoreRT)

Если вам по-прежнему нужна дополнительная производительность, я бы посоветовал вам взглянуть на .Net Core Runtime (CoreRT) .

Обратите внимание, что на момент написания этой статьи этот параметр, вероятно, необходимо было рассмотреть более подробно, прежде чем приступить к этому для производственной системы.

«CoreRT обеспечивает большую часть производительности и всех преимуществ развертывания собственной компиляции, сохраняя при этом возможность писать на вашем любимом языке программирования .NET.»

CoreRT предлагает большие преимущества, которые важны для многих приложений.

  • Собственный компилятор создает ОДИН ФАЙЛ, включая приложение, управляемые зависимости и CoreRT.
  • Собственные скомпилированные приложения запускаются быстрее, так как они выполняют уже скомпилированный код. Им не нужно ни генерировать машинный код во время выполнения, ни загружать JIT-компилятор.
  • Собственные скомпилированные приложения могут использовать оптимизирующий компилятор, что приводит к более высокой пропускной способности благодаря более качественному коду (оптимизация компилятора C ++). И компиляторы LLILLC и IL в CPP полагаются на оптимизирующие компиляторы.

Эти преимущества открывают новые сценарии для разработчиков .NET

  • Скопируйте один исполняемый файл с одного компьютера и запустите на другом (такого же типа) без установки среды выполнения .NET.
  • Создайте и запустите образ докера, который содержит один исполняемый файл (например, один файл в дополнение к Ubuntu 14.04).

Linux-специфичные оптимизации

Есть хорошая библиотека, которая пытается иметь дело с очень специализированными случаями. В частности, для Linux (но этот код безопасен для других операционных систем). Принцип, лежащий в основе этой оптимизации, заключается в замене транспортной библиотеки libuv (которую использует ASP.NET Core) другой оптимизацией, специфичной для Linux.

Он напрямую использует примитивы ядра для реализации API-интерфейса транспорта. Это уменьшает количество объектов, выделенных кучей (например, uv_buf_t, SocketAsyncEventArgs), что означает, что давление ГХ меньше. Реализации, основанные на API xplat, будут объединять объекты для достижения этой цели.

using RedHat.AspNetCore.Server.Kestrel.Transport.Linux; // <--- note this !

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseLinuxTransport()     // <--- and note this !!!
        .UseStartup()
        .Build();

// note: It's safe to call UseLinuxTransport on non-Linux platforms, it will no-op

Вы можете посмотреть репозиторий для этого промежуточного ПО на GitHub здесь https://github.com/redhat-developer/kestrel-linux-transport

enter image description here

enter image description here

Источник: https://developers.redhat.com/blog/2018/07/24/improv-net-core-kestrel-performance-linux/

...