Производительность ASP.NET Core: Kestrel, пулы соединений, потоковые ответы

↑ 7.1 Производительность .NET и кэширование · ← Предыдущая

Желательно~3 мин чтенияУровень: senior

Зачем это на собесе

Какие рычаги есть у ASP.NET Core-приложения при высокой нагрузке.

Объяснение

Основные рычаги:

ОбластьЧто делать
Асинхронностьникакого .Result; async I/O по всей цепочке (см. Антипаттерны: async void, .Result, sync over async)
ThreadPoolне блокировать потоки; при starvation — диагностика, а не SetMinThreads вслепую
KestrelHTTP/2/3, лимиты (MaxConcurrentConnections, MaxRequestBodySize), keep-alive
СоединенияIHttpClientFactory, пул БД (Maximum Pool Size), Redis multiplexer
СериализацияSystem.Text.Json + source generators, стриминг больших ответов
Ответысжатие (Brotli), ETag/кэш, IAsyncEnumerable
EF/данныепроекции, AsNoTracking, пагинация, индексы
GCServer GC в контейнерах, лимиты памяти, TieredPGO, ReadyToRun/NativeAOT для старта
ЛогированиеLoggerMessage, уровни, асинхронные sinks
// Потоковая выдача больших списков
app.MapGet("/export", async (AppDbContext db, HttpResponse res, CancellationToken ct) =>
{
    res.ContentType = "application/x-ndjson";
    await foreach (var o in db.Orders.AsNoTracking().AsAsyncEnumerable().WithCancellation(ct))
        await res.WriteAsync(JsonSerializer.Serialize(o) + "\n", ct);
});
 
// Source generator для JSON
[JsonSerializable(typeof(OrderDto))] partial class AppJsonContext : JsonSerializerContext;
builder.Services.ConfigureHttpJsonOptions(o => o.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonContext.Default));

Метод: измерить (нагрузочный тест, метрики) → найти узкое место (обычно БД, внешние вызовы, а не код фреймворка) → исправить.

Нюансы и подводные камни

  • Kestrel не узкое место в типичных приложениях: чаще БД и блокировки.
  • Лимиты CPU в контейнере влияют на число потоков и GC: задавайте DOTNET_ переменные осознанно.
  • Слишком большие пулы соединений перегружают БД.
  • Буферизация всего ответа перед отправкой увеличивает память и задержку.
  • Профилирование нужно на реалистичных данных.

Практика

  1. Проведите нагрузочный тест эндпоинта и найдите узкое место.
  2. Включите JSON source generator и сравните аллокации.
  3. Настройте потоковую выдачу экспорта на 1 млн записей.

Вопросы с ответами

Связанные темы