使用 IIS 和 ASP.NET Core 進行同處理序裝載

同處理序裝載會在與 IIS 背景工作處理序相同的處理序中執行 ASP.NET Core 應用程式。 因為要求未透過回送介面卡 (將連出網路流量傳回同一部電腦的網路介面) 進行 proxy 處理,所以同處理序裝載會提供優於跨處理序裝載的效能。

下圖說明 IIS、ASP.NET Core 模組和同處理序裝載應用程式之間的關聯性:

ASP.NET Core Module in the in-process hosting scenario

啟用同處理序裝載

自 ASP.NET Core 3.0 起,所有部署到 IIS 的應用程式預設都會啟用同處理序裝載。

若要明確設定應用程式進行同處理序裝載,請將專案檔 (.csproj) 中的 <AspNetCoreHostingModel> 屬性值設定為 InProcess

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

一般架構

要求的一般流程如下所示:

  1. 要求會從 Web 到達核心模式的 HTTP.sys 驅動程式。
  2. 驅動程式會在網站設定的連接埠上將原生要求路由至 IIS,此連接埠通常是 80 (HTTP) 或 443 (HTTPS)。
  3. ASP.NET Core 模組會接收原生要求,並將其傳遞至 IIS HTTP 伺服器 (IISHttpServer)。 IIS HTTP 伺服器是 IIS 的同處理序伺服程式實作,可將要求從原生轉換為受控。

在 IIS HTTP 伺服器處理要求之後:

  1. 要求會傳送至 ASP.NET Core 中介軟體管線。
  2. 中介軟體管線會處理要求,並將其作為 HttpContext 執行個體傳遞至應用程式的邏輯。
  3. 應用程式的回應會透過 IIS HTTP 伺服器傳回 IIS。
  4. IIS 會將回應傳送到起始該要求的用戶端。

CreateDefaultBuilder 會透過呼叫 UseIIS 方法來啟動 CoreCLR 以新增 IServer,並在 IIS 工作者處理序 (w3wp.exeiisexpress.exe) 內裝載應用程式。 效能測試指出,相較於將 .NET Core 應用程式裝載於處理序外,並將要求 Proxy 處理至 Kestrel,裝載於處理序內可提供明顯更高的要求輸送量。

發佈為單一檔案可執行檔的應用程式無法由同處理序裝載模型載入。

應用程式設定

若要設定 IIS 選項,請在 Program.cs 中加入 IISServerOptions 的服務設定。 下列範例會停用 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 伺服器會設定由 Windows 驗證所驗證的 HttpContext.User。 若為 false,則伺服器僅會對 HttpContext.User 提供身分識別,並在 AuthenticationScheme 明確要求時回應挑戰。 必須在 IIS 中啟用 Windows 驗證以讓 AutomaticAuthentication 作用。 如需詳細資訊,請參閱 Windows 驗證
AuthenticationDisplayName null 設定使用者在登入頁面上看到的顯示名稱。
AllowSynchronousIO false 是否要針對 HttpContext.RequestHttpContext.Response 允許同步 I/O。
MaxRequestBodySize 30000000 取得或設定 HttpRequest 的要求本文大小上限。 請注意,IIS 本身具有限制 maxAllowedContentLength,此限制將在 IISServerOptions 中設定 MaxRequestBodySize 時處理。 變更 MaxRequestBodySize 將不會影響 maxAllowedContentLength。 若要增加 maxAllowedContentLength,請在 web.config 中新增項目,以將 maxAllowedContentLength 設定為較高的值。 如需更多詳細資料,請參閱組態

同處理序和跨處理序裝載之間的差異

同處理序裝載時具有下列特性:

  • 使用 IIS HTTP 伺服器 (IISHttpServer),而不是 Kestrel 伺服器。 針對同處理序,CreateDefaultBuilder 呼叫 UseIIS 以:

    • 註冊 IISHttpServer
    • 設定伺服器在 ASP.NET Core 模組後方執行時應該接聽的連接埠和基底路徑。
    • 設定主機以擷取啟動錯誤。
  • requestTimeout 屬性 不適用於同處理序裝載。

  • 不支援在應用程式之間共用應用程式集區。 每個應用程式使用一個應用程式集區。

  • 應用程式的架構 (位元) 和已安裝的執行階段 (x64 或 x86) 必須符合應用程式集區的架構。 例如,針對 32 位元 (x86) 發佈的應用程式必須為其 IIS 應用程式集區啟用 32 位元。 如需詳細資訊,請參閱建立 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();

同處理序裝載會在與 IIS 背景工作處理序相同的處理序中執行 ASP.NET Core 應用程式。 因為要求未透過回送介面卡 (將連出網路流量傳回同一部電腦的網路介面) 進行 proxy 處理,所以同處理序裝載會提供優於跨處理序裝載的效能。

下圖說明 IIS、ASP.NET Core 模組和同處理序裝載應用程式之間的關聯性:

ASP.NET Core Module in the in-process hosting scenario

啟用同處理序裝載

自 ASP.NET Core 3.0 起,所有部署到 IIS 的應用程式預設都會啟用同處理序裝載。

若要明確設定應用程式進行同處理序裝載,請將專案檔 (.csproj) 中的 <AspNetCoreHostingModel> 屬性值設定為 InProcess

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

一般架構

要求的一般流程如下所示:

  1. 要求會從 Web 到達核心模式的 HTTP.sys 驅動程式。
  2. 驅動程式會在網站設定的連接埠上將原生要求路由至 IIS,此連接埠通常是 80 (HTTP) 或 443 (HTTPS)。
  3. ASP.NET Core 模組會接收原生要求,並將其傳遞至 IIS HTTP 伺服器 (IISHttpServer)。 IIS HTTP 伺服器是 IIS 的同處理序伺服程式實作,可將要求從原生轉換為受控。

在 IIS HTTP 伺服器處理要求之後:

  1. 要求會傳送至 ASP.NET Core 中介軟體管線。
  2. 中介軟體管線會處理要求,並將其作為 HttpContext 執行個體傳遞至應用程式的邏輯。
  3. 應用程式的回應會透過 IIS HTTP 伺服器傳回 IIS。
  4. IIS 會將回應傳送到起始該要求的用戶端。

CreateDefaultBuilder 會透過呼叫 UseIIS 方法來啟動 CoreCLR 以新增 IServer,並在 IIS 工作者處理序 (w3wp.exeiisexpress.exe) 內裝載應用程式。 效能測試指出,相較於將 .NET Core 應用程式裝載於處理序外,並將要求 Proxy 處理至 Kestrel,裝載於處理序內可提供明顯更高的要求輸送量。

發佈為單一檔案可執行檔的應用程式無法由同處理序裝載模型載入。

應用程式設定

若要設定 IIS 選項,請在 ConfigureServices 中加入 IISServerOptions 的服務設定。 下列範例會停用 AutomaticAuthentication:

services.Configure<IISServerOptions>(options => 
{
    options.AutomaticAuthentication = false;
});
選項 預設 設定
AutomaticAuthentication true 若為 true,IIS 伺服器會設定由 Windows 驗證所驗證的 HttpContext.User。 若為 false,則伺服器僅會對 HttpContext.User 提供身分識別,並在 AuthenticationScheme 明確要求時回應挑戰。 必須在 IIS 中啟用 Windows 驗證以讓 AutomaticAuthentication 作用。 如需詳細資訊,請參閱 Windows 驗證
AuthenticationDisplayName null 設定使用者在登入頁面上看到的顯示名稱。
AllowSynchronousIO false 是否要針對 HttpContext.RequestHttpContext.Response 允許同步 I/O。
MaxRequestBodySize 30000000 取得或設定 HttpRequest 的要求本文大小上限。 請注意,IIS 本身具有限制 maxAllowedContentLength,此限制將在 IISServerOptions 中設定 MaxRequestBodySize 時處理。 變更 MaxRequestBodySize 將不會影響 maxAllowedContentLength。 若要增加 maxAllowedContentLength,請在 web.config 中新增項目,以將 maxAllowedContentLength 設定為較高的值。 如需更多詳細資料,請參閱組態

同處理序和跨處理序裝載之間的差異

同處理序裝載時具有下列特性:

  • 使用 IIS HTTP 伺服器 (IISHttpServer),而不是 Kestrel 伺服器。 針對同處理序,CreateDefaultBuilder 呼叫 UseIIS 以:

    • 註冊 IISHttpServer
    • 設定伺服器在 ASP.NET Core 模組後方執行時應該接聽的連接埠和基底路徑。
    • 設定主機以擷取啟動錯誤。
  • requestTimeout 屬性 不適用於同處理序裝載。

  • 不支援在應用程式之間共用應用程式集區。 每個應用程式使用一個應用程式集區。

  • 應用程式的架構 (位元) 和已安裝的執行階段 (x64 或 x86) 必須符合應用程式集區的架構。 例如,針對 32 位元 (x86) 發佈的應用程式必須為其 IIS 應用程式集區啟用 32 位元。 如需詳細資訊,請參閱建立 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();
    }
    
  • 不支援網頁套件 (單一檔案) 部署