Внутрипроцессное размещение в службах IIS и ASP.NET Core

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

На следующей схеме показана связь между IIS, модулем ASP.NET Core и приложением, размещенным внутри процесса.

Модуль ASP.NET Core в сценарии внутрипроцессного размещения

Включение внутрипроцессного размещения

Начиная с ASP.NET Core 3.0, внутрипроцессное размещение включено по умолчанию для всех приложений, развертываемых в службах IIS.

Чтобы явным образом настроить внутрипроцессное размещение для приложения, задайте для свойства <AspNetCoreHostingModel> значение InProcess в файле проекта (.csproj).

<PropertyGroup>
  <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup>

Общая архитектура

В общем виде запрос выполняется и обрабатывается следующим образом.

  1. Запрос поступает из Интернета в драйвер HTTP.sys в режиме ядра.
  2. Драйвер направляет собственный запрос к IIS на настроенный порт веб-сайта — обычно 80 (HTTP) или 443 (HTTPS).
  3. Модуль ASP.NET Core получает собственный запрос и передает его на HTTP-сервер IIS (IISHttpServer). HTTP-сервер IIS — это реализация внутрипроцессного сервера для IIS, в которой запрос преобразовывается из собственной формы в управляемую.

После того как HTTP-сервер IIS обработает запрос:

  1. Запрос отправляется в конвейер ПО промежуточного слоя ASP.NET Core.
  2. Конвейер ПО промежуточного слоя обрабатывает запрос и передает его в качестве экземпляра HttpContext в логику приложения.
  3. Ответ приложения передается обратно в службы IIS через HTTP-сервер IIS.
  4. IIS отправляет ответ клиенту, который инициировал запрос.

CreateDefaultBuilder добавляет экземпляр IServer. При этом вызывается метод UseIIS для загрузки CoreCLR и размещения приложения внутри рабочего процесса IIS (w3wp.exe или iisexpress.exe). Тесты производительности демонстрируют, что размещение внутрипроцессного приложения .NET Core обеспечивает значительно более высокую пропускную способность по сравнению с размещением приложения вне процесса и направлению запросов через прокси-сервер к Kestrel.

Приложения, опубликованные в виде одного исполняемого файла, не могут быть загружены по модели внутрипроцессного размещения.

Настройка приложения

Чтобы настроить параметры IIS, включите конфигурацию служб для IISServerOptions в Program.cs. В следующем примере происходит отключение AutomaticAuthentication:

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Server.IIS;
using Microsoft.EntityFrameworkCore;
using RPauth.Data;

var builder = WebApplication.CreateBuilder(args);

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();

builder.Services.Configure<IISServerOptions>(options =>
{
    options.AutomaticAuthentication = false;
});

builder.Services.AddTransient<IClaimsTransformation, MyClaimsTransformation>();
builder.Services.AddAuthentication(IISServerDefaults.AuthenticationScheme);

builder.Services.AddRazorPages();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapRazorPages();

app.Run();
Параметр Значение по умолчанию Параметр
AutomaticAuthentication true Если значение — true, сервер IIS задает свойство HttpContext.User, использующее проверку подлинности Windows. Если значение — false, сервер только предоставляет идентификатор для HttpContext.User и отвечает на явные запросы защиты от AuthenticationScheme. Для работы AutomaticAuthentication необходимо включить в службах IIS проверку подлинности Windows. Дополнительные сведения: Проверка подлинности Windows.
AuthenticationDisplayName null Задает отображаемое имя для пользователей на страницах входа.
AllowSynchronousIO false Разрешены ли синхронные операции ввода-вывода для HttpContext.Request и HttpContext.Response.
MaxRequestBodySize 30000000 Возвращает или задает максимальный размер текста запроса для HttpRequest. Обратите внимание, что сами службы IIS ограничены параметром maxAllowedContentLength, который обрабатывается перед тем, как MaxRequestBodySize задается в IISServerOptions. Изменение MaxRequestBodySize не влияет на maxAllowedContentLength. Чтобы увеличить maxAllowedContentLength, добавьте запись в web.config, чтобы задать maxAllowedContentLength большее значение. Дополнительные сведения см. в разделе Конфигурация.

Различия между внутрипроцессным и внепроцессным размещением

При внутрипроцессном размещении применимы следующие характеристики:

  • HTTP-сервер IIS (IISHttpServer) используется вместо сервера Kestrel. При внутрипроцессном размещении CreateDefaultBuilder вызывает UseIIS в следующих целях.

    • Регистрация IISHttpServer.
    • Настройка порта и базового пути, которые будет прослушивать сервер при выполнении за модулем ASP.NET Core.
    • Настройка перехвата ошибок запуска на узле.
  • Атрибут requestTimeout не применяется к внутрипроцессному размещению.

  • Совместное использование пула приложений среди приложений не поддерживается. Используйте один пул приложений для каждого приложения.

  • Архитектура (разрядность) приложения и установленная среда выполнения (x64 или x86) должны соответствовать архитектуре пула приложений. Например, для приложений, опубликованных для 32-разрядной архитектуры (x86), необходимо включить поддержку этой архитектуры для пулов приложений IIS. Дополнительные сведения см. в разделе Создание сайта IIS.

  • Обнаружены отключения клиентов. Маркер отмены HttpContext.RequestAborted аннулируется при отключении клиента.

  • При размещении в процессе AuthenticateAsync не вызывается внутри для инициализации пользователя. Таким образом, реализация IClaimsTransformation, используемая для преобразования утверждений после каждой проверки подлинности, не активируется по умолчанию. При преобразовании утверждений с реализацией IClaimsTransformation вызовите AddAuthentication для добавления служб проверки подлинности:

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Server.IIS;
using Microsoft.EntityFrameworkCore;
using RPauth.Data;

var builder = WebApplication.CreateBuilder(args);

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();

builder.Services.Configure<IISServerOptions>(options =>
{
    options.AutomaticAuthentication = false;
});

builder.Services.AddTransient<IClaimsTransformation, MyClaimsTransformation>();
builder.Services.AddAuthentication(IISServerDefaults.AuthenticationScheme);

builder.Services.AddRazorPages();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapRazorPages();

app.Run();

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

На следующей схеме показана связь между IIS, модулем ASP.NET Core и приложением, размещенным внутри процесса.

Модуль ASP.NET Core в сценарии внутрипроцессного размещения

Включение внутрипроцессного размещения

Начиная с ASP.NET Core 3.0, внутрипроцессное размещение включено по умолчанию для всех приложений, развертываемых в службах IIS.

Чтобы явным образом настроить внутрипроцессное размещение для приложения, задайте для свойства <AspNetCoreHostingModel> значение InProcess в файле проекта (.csproj).

<PropertyGroup>
  <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup>

Общая архитектура

В общем виде запрос выполняется и обрабатывается следующим образом.

  1. Запрос поступает из Интернета в драйвер HTTP.sys в режиме ядра.
  2. Драйвер направляет собственный запрос к IIS на настроенный порт веб-сайта — обычно 80 (HTTP) или 443 (HTTPS).
  3. Модуль ASP.NET Core получает собственный запрос и передает его на HTTP-сервер IIS (IISHttpServer). HTTP-сервер IIS — это реализация внутрипроцессного сервера для IIS, в которой запрос преобразовывается из собственной формы в управляемую.

После того как HTTP-сервер IIS обработает запрос:

  1. Запрос отправляется в конвейер ПО промежуточного слоя ASP.NET Core.
  2. Конвейер ПО промежуточного слоя обрабатывает запрос и передает его в качестве экземпляра HttpContext в логику приложения.
  3. Ответ приложения передается обратно в службы IIS через HTTP-сервер IIS.
  4. IIS отправляет ответ клиенту, который инициировал запрос.

CreateDefaultBuilder добавляет экземпляр IServer. При этом вызывается метод UseIIS для загрузки CoreCLR и размещения приложения внутри рабочего процесса IIS (w3wp.exe или iisexpress.exe). Тесты производительности демонстрируют, что размещение внутрипроцессного приложения .NET Core обеспечивает значительно более высокую пропускную способность по сравнению с размещением приложения вне процесса и направлению запросов через прокси-сервер к Kestrel.

Приложения, опубликованные в виде одного исполняемого файла, не могут быть загружены по модели внутрипроцессного размещения.

Настройка приложения

Чтобы настроить параметры IIS, включите конфигурацию служб для IISServerOptions в ConfigureServices. В следующем примере показано, как отключить AutomaticAuthentication:

services.Configure<IISServerOptions>(options => 
{
    options.AutomaticAuthentication = false;
});
Параметр Значение по умолчанию Параметр
AutomaticAuthentication true Если значение — true, сервер IIS задает свойство HttpContext.User, использующее проверку подлинности Windows. Если значение — false, сервер только предоставляет идентификатор для HttpContext.User и отвечает на явные запросы защиты от AuthenticationScheme. Для работы AutomaticAuthentication необходимо включить в службах IIS проверку подлинности Windows. Дополнительные сведения: Проверка подлинности Windows.
AuthenticationDisplayName null Задает отображаемое имя для пользователей на страницах входа.
AllowSynchronousIO false Разрешены ли синхронные операции ввода-вывода для HttpContext.Request и HttpContext.Response.
MaxRequestBodySize 30000000 Возвращает или задает максимальный размер текста запроса для HttpRequest. Обратите внимание, что сами службы IIS ограничены параметром maxAllowedContentLength, который обрабатывается перед тем, как MaxRequestBodySize задается в IISServerOptions. Изменение MaxRequestBodySize не влияет на maxAllowedContentLength. Чтобы увеличить maxAllowedContentLength, добавьте запись в web.config, чтобы задать maxAllowedContentLength большее значение. Дополнительные сведения см. в разделе Конфигурация.

Различия между внутрипроцессным и внепроцессным размещением

При внутрипроцессном размещении применимы следующие характеристики:

  • HTTP-сервер IIS (IISHttpServer) используется вместо сервера Kestrel. При внутрипроцессном размещении CreateDefaultBuilder вызывает UseIIS в следующих целях.

    • Регистрация IISHttpServer.
    • Настройка порта и базового пути, которые будет прослушивать сервер при выполнении за модулем ASP.NET Core.
    • Настройка перехвата ошибок запуска на узле.
  • Атрибут requestTimeout не применяется к внутрипроцессному размещению.

  • Совместное использование пула приложений среди приложений не поддерживается. Используйте один пул приложений для каждого приложения.

  • Архитектура (разрядность) приложения и установленная среда выполнения (x64 или x86) должны соответствовать архитектуре пула приложений. Например, для приложений, опубликованных для 32-разрядной архитектуры (x86), необходимо включить поддержку этой архитектуры для пулов приложений IIS. Дополнительные сведения см. в разделе Создание сайта IIS.

  • Обнаружены отключения клиентов. Маркер отмены HttpContext.RequestAborted аннулируется при отключении клиента.

  • При размещении в процессе AuthenticateAsync не вызывается внутри для инициализации пользователя. Таким образом, реализация IClaimsTransformation, используемая для преобразования утверждений после каждой проверки подлинности, не активируется по умолчанию. При преобразовании утверждений с реализацией IClaimsTransformation вызовите AddAuthentication для добавления служб проверки подлинности:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddTransient<IClaimsTransformation, ClaimsTransformer>();
        services.AddAuthentication(IISServerDefaults.AuthenticationScheme);
    }
    
    public void Configure(IApplicationBuilder app)
    {
        app.UseAuthentication();
    }
    
  • Развертывания веб-пакета (однофайлового) не поддерживаются.