ASP.NET Core 6 基础入门系列(15) 项目在IIS下部署的两种进程托管模型

系列目录     【已更新最新开发文章,点击查看详细】  
  • ASP.NET Core 6 基础入门系列(14) 项目发布与IIS部署
  • ASP.NET Core 6 基础入门系列(13) Web 服务器介绍
  • ASP.NET Core 6 基础入门系列(12) 项目的多种启动方式及问题
  • ASP.NET Core 6 基础入门系列(11) 项目结构详解之项目入口Program.cs 
  • ASP.NET Core 6 基础入门系列(10) 项目结构详解之appsettings.json
  • ASP.NET Core 6 基础入门系列(9) 项目结构详解之launchSettings.json
  • ASP.NET Core 6 基础入门系列(8) 项目结构详解之MVC
  • ASP.NET Core 6 基础入门系列(7) 项目结构详解之wwwroot
  • ASP.NET Core 6 基础入门系列(6) 项目结构详解之依赖项
  • ASP.NET Core 6 基础入门系列(5) 项目结构详解之项目文件管理
  • ASP.NET Core 6 基础入门系列(4) 项目结构简介
  • ASP.NET Core 6 基础入门系列(3) 新建 ASP.NET Core MVC 6.0 项目 
  • ASP.NET Core 6 基础入门系列(2) 开发环境准备
  • ASP.NET Core 6 基础入门系列(1) ASP.NET Core 6 简介

  在前一篇博客《ASP.NET Core 6 基础入门系列(14) ASP.NET Core 项目发布与IIS部署》中简单的介绍了Web项目的发布与IIS中部署的流程。ASP.NET Core 在 IIS下部署有 In-ProcessOut-of-Process 两种部署模式。

  ASP.NET Core Module (ANCM) 是插入 IIS 管道的本机 IIS 模块,能让 ASP.NET Core 应用程序通过 IIS 运行。 使用以下任一方式通过 IIS 运行 ASP.NET Core 应用:

  • 在 IIS 工作进程 (w3wp.exe) 内托管 ASP.NET Core 应用,称为进程内托管模型
  • 将 Web 请求转发到运行 Kestrel 服务器(dotnet.exe 进程)的后端 ASP.NET Core 应用,称为进程外托管模型

开发者需要对这两类托管模型进行权衡。 默认情况下使用的是进程内托管模型,因为这样可以得到更好的性能和诊断。

 In-Process 进程内托管部署模式

  使用进程内托管,ASP.NET Core 应用运行在与 IIS 工作进程相同的进程(w3wp.exe)中(如果采用 IIS Express,则工作进程为 iisexpress.exe)。 进程内承载相较进程外承载提供更优的性能,因为请求并不通过环回适配器进行代理,环回适配器是一个网络接口,用于将传出的网络流量返回给同一计算机。 IIS 使用 Windows 进程激活服务 (WAS)处理进程管理。

下图说明了 IIS、ASP.NET Core 模块和进程内托管的应用之间的关系:

该模式下使用的服务器类型是 IISHttpServer。图中的 ASP.NET Core Module 会将原始的请求转发给这个服务器(IISHttpServer),并将 IISHttpServer 生成的响应转交给 IIS 服务器进行回复。

  In-Process 是默认采用的部署模式,所以不需要为此进行任何设置。关于IIS下部署ASP.NET Core 项目,请参考我的博客ASP.NET Core 6 基础入门系列(14) 项目发布与IIS部署

修改 Program.cs 文件,使用如下代码获取当前处理程序的名称

重新发布,再次访问,从下图的输出结果中可以看出 ASP.NET Core 应用实际上就是运行在IIS的工作进程(w3wp.exe)中。

查看发布目录,则会发现生成的程序集和配置文件如下图所示

应用既然部署在IIS中,那么具体的配置自然就定义在web.config中,查看该文件的内容如下图所示

(1)第6行中的 path="*" verb="*" 表明所有的请求都被映射到  AspNetCoreModuleV2 这个 module 上,这就是上面介绍的 ASP.NET Core Module。

(2)如果 Module 启动 ASP.NET Core 管道并与之交互,则由第8行的 <aspNetCore> 配置节中的 processPath 属性指定的应用程序来控制。

(3)第8行的 hostingModel="inprocess" 表示部署模式为进程内容托管。

  IISHttpServer 的注册实现在 IWebHostBuilder 接口的 UseIIS() 扩展方法中。由于这个扩展方法并没有提供一个 Action<IISServerOptions> 委托参数对 IISServerOptions 配置选项进行设置,所以不得不采用原始的方式对它进行设置。由于 IHostBuilder 接口的 ConfigureWebHostDefaults 扩展方法内部会调用这个方法,所以我们并不需要为此做额外的工作。

(一)启用进程内托管

自 ASP.NET Core 3.0 起,默认情况下已为部署到 IIS 的所有应用启用进程内托管。若要显式配置进程内托管的应用,请在项目文件 (.csproj) 中将 <AspNetCoreHostingModel> 属性的值设置为 InProcess

未使用 IIS 托管时,ASP.NET Core 项目模板默认使用 Kestrel 服务器。

(二)一般体系结构

请求的常规流程如下:

  1. 请求从 Web 到达内核模式 HTTP.sys 驱动程序。
  2. 驱动程序将本机请求路由到网站的配置端口上的 IIS,通常为 80 (HTTP) 或 443 (HTTPS)。
  3. ASP.NET Core Module 接收本机请求,并将其传递给 IIS HTTP 服务器 (IISHttpServer)。 (IIS HTTP 服务器是将请求从本机转换为托管的 IIS 进程内服务器实现)

在 IIS HTTP 服务器处理请求后:

  1. 请求被发送到 ASP.NET Core 中间件管道。
  2. 中间件管道处理该请求并将其作为 HttpContext 实例传递给应用的逻辑(如配置文件中配置的 processPath=".\DotNet6_Web_Study.exe" 对应的 DotNet6_Web_Study.dll)。
  3. 应用的响应通过 IIS HTTP 服务器传递回 IIS。 
  4. IIS 将响应发送到发起请求的客户端。

CreateDefaultBuilder 添加 IServer 实例的方式是:调用 UseIIS() 方法来启动 CoreCLR 和将应用托管在 IIS 工作进程(w3wp.exe 或 iisexpress.exe)内。 性能测试表明,与在进程外托管应用并将请求代理传入 Kestrel 相比,在进程中托管 .NET Core 应用可提供明显更高的请求吞吐量。 作为单个文件可执行文件发布的应用无法由进程内托管模型加载。

(三)应用程序配置

要配置 IIS 选项,请在 Program.cs 中包括 IISServerOptions 的服务配置。

    WebApplicationBuilder builder = WebApplication.CreateBuilder(args);builder.Services.Configure<IISServerOptions>(options =>{options.AllowSynchronousIO = true;});

IISServerOptions中的所有属性及含义如下

 Out-of-Process 进程外托管部署模式

  ASP.NET Core用在 IIS 中还可以采用 Out-of-Process 模式进行部署。如下图所示

在这种部署模式下,采用 KestrelServer 的 ASP.NET Core 应用运行在独立的 dotnet.exe 进程中,ASP.NET Core Module 会负责进程管理。当IIS接收到目标应用的请求时,如果目标应用所在的进程并未启动,则 ASP.NET Core Module 还负责执行“dotnet”命令激活此进程,相当于充当了 WAS(Windows ActivationService)的作用。使用单独的进程还可以托管同一个应用池中的多个应用。

  1. 请求从 Web 到达内核模式 HTTP.sys 驱动程序。
  2. 驱动程序将请求路由到网站的配置端口上的 IIS。 配置的端口通常是 80 (HTTP) 或 443 (HTTPS)。
  3. 此模块将该请求转发到应用的随机端口上的 Kestrel。 随机端口不是 80 或 443。

  在激活 ASP.NET Core 承载进程之前,ASP.NET Core Module 会选择一个可用的端口,该端口和当前应用的路径(该路径将作用 ASPNET Core 应用的 PathBase)被写入环境变量,对应环境变量名称分别为“ASPNETCORE_PORT”和“ASPNETCORE_ APPL_PATH”。以 Out-Of-Process 模式部署 ASP.NET Core 应会接收 IIS 转发的请求,为了能够过滤其他来源的请求,ASP.NET Core Module 会生成一个 Token 并写入环境变量“ASPNETCORE_TOKEN”。后续转发的请求会利用一个报头“MS-ASPNETCORE-TOKEN”传递此Token, ASP.NET Core 应用校验是否与之前生成的Token匹配。

  ASPNET Core Module 还会利用环境变量传递其他设置,如认证方案被写入环境变量“ASPNETCORE _IIS_HTTPAUTH",另一个 “ASPNETCORE_IIS_WEBSOCKETS_SUPPORTED环境变量用来设置 Web Socket的支持状态。由于这些环境变量名称的前缀都是“ASPNETCORE_”,所以它们都会作为默认配置源。KestrelServer 最终会绑定到基于该端口的本地址终节点(localhost)进行监听。由于监听地址是由 ASP.NET Core Module 控制的,所以它只需将请求转发到该地址,最终将接收到的响应交给IIS返回。由于这里涉及本地回环网(Loopback)的访问,其性能自然不如 In-Process 部署模式。

(一)启用进程外托管模型

编辑项目文件,修改配置如下

OutOfProcess 表示进程外托管。

(1)<AspNetCoreHostingModel> 的值不区分大小写,因此 inprocess 和 outofprocess 均为有效值。

(2)使用进程外托管应用时,使用 Kestrel 服务器,而不是 IIS HTTP 服务器 (IISHttpServer)。对于进程外托管,CreateDefaultBuilder 会调用 UseIISIntegration 来进行以下操作:

  • 在 ASP.NET Core Module 后运行时,配置服务器应侦听的端口和基本路径。
  • 配置主机以捕获启动错误。

要配置 IIS 选项,请在 ConfigureServices 中包括 IISOptions 的服务配置。

(二)进程名称

  将项目重新发布,查看发布后的web.config文件

第8行的 hostingModel="outofprocess" 表示为进程外托管。

通过下面的代码获取进程名称

浏览器中访问站点,从下图的输出结果中可以看出 ASP.NET Core 应用实际上就是运行在应用程序本身的进程中

修改web.config内容如下

浏览器中访问站点,从下图的输出结果中可以看出 ASP.NET Core 应用实际上就是运行在 dotnet.exe 进程中

(三)验证环境变量是否存在

通过以下代码逻辑来验证:

重新发布程序,在浏览器中访问

进程内和进程外托管之间的差异

在进程内托管时,将应用以下特征:

  • 使用 IIS HTTP 服务器 (IISHttpServer),而不是 Kestrel 服务器。 对于进程内托管,CreateDefaultBuilder 会调用 UseIIS 来进行以下操作:

    • 注册 IISHttpServer
    • 在 ASP.NET Core Module 后运行时,配置服务器应侦听的端口和基本路径。
    • 配置主机以捕获启动错误。
  • requestTimeout 属性不适用于进程内托管。

  • 不支持在应用之间共享应用池。 每个应用使用一个应用池。

  • 应用和已安装的运行时(x64 或 x86)的体系结构(位数)必须与应用池的体系结构匹配。 例如,为 32 位 (x86) 发布的应用必须已为其 IIS 应用程序池启用 32 位。 有关详细信息,请参阅创建 IIS 站点部分。

  • 检测到客户端连接断开。 客户端断开连接时,将取消 HttpContext.RequestAborted 取消标记。

  • 在进程内托管时,不会在内部调用 AuthenticateAsync 来初始化用户。 因此,默认情况下不激活每次身份验证后用于转换声明的 IClaimsTransformation 实现。 使用 IClaimsTransformation 实现转换声明时,请调用 AddAuthentication 以添加身份验证服务:

var builder = WebApplication.CreateBuilder(args);builder.Services.AddTransient<IClaimsTransformation, MyClaimsTransformation>();
builder.Services.AddAuthentication(IISServerDefaults.AuthenticationScheme);
  • 不同的启动方式对应的服务器


参考文献:

  • 《使用 IIS 在 Windows 上托管 ASP.NET Core》https://learn.microsoft.com/zh-cn/aspnet/core/host-and-deploy/iis/?view=aspnetcore-6.0
  • 《用于 IIS 的 ASP.NET Core 模块 (ANCM)》https://learn.microsoft.com/zh-cn/aspnet/core/host-and-deploy/aspnet-core-module?view=aspnetcore-6.0
系列目录     【已更新最新开发文章,点击查看详细】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/886776.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ASP.NET Core 6 基础入门系列(14) 项目发布与IIS部署

系列目录 【已更新最新开发文章,点击查看详细】ASP.NET Core 6 基础入门系列(13) Web 服务器介绍 ASP.NET Core 6 基础入门系列(12) 项目的多种启动方式及问题 ASP.NET Core 6 基础入门系列(11) 项目结构详解之项目入口Program.cs ASP.NET Core 6 基础入门系列(10) 项目结…

ASP.NET Core 6 基础入门系列(1) ASP.NET Core 6.0 简介

系列目录 【已更新最新开发文章,点击查看详细】预备知识1: C#5、C#6、C#7、C#8、C#9、C#10 预备知识2: .NET 对比 .NET Framework 预备知识3: ASP.NET Core 概述 预备知识4: ASP.NET Core 与 ASP.NET 宏观对比 预备知识5: ASP.NET 请求处理机制 预备知识6: AS…

老年人1

用servlet构建一个javaweb项目并配置好环境

数据类型拓展

数据类型扩展 整数拓展 整数拓展:进制 二进制0b开头 十进制 八进制0开头 十六进制0x开头public class Demo03 {public static void main(String[] args) {//整数拓展: 进制 二进制0b开头 十进制 八进制0开头 十六进制0x开头int i =10;int i2 =010…

寒假打工记

通过联系老师和亲戚获得了家教途径 以下是于中介的沟通总结: 找工作的话尽量不要通过中介简绍,会潜在收取大量的费用,导致工作收益太低,带三个高一学生数学2小时100,不足以提供食宿费;此外还应事先谈好薪资结算时间,以免拖欠。 以下是与学生家长的沟通总结: 与家长沟通…

亲测可用,IDEA中使用满血版DeepSeek R1!支持深度思考!免费!免配置!

之前介绍过在IDEA中使用DeepSeek的方案,但是很多人表示还是用的不够爽,比如用CodeChat的方案,只支持V3版本,不支持带推理的R1。想要配置R1的话有特别的麻烦。作者:程序员 Hollis之前介绍过在IDEA中使用DeepSeek的方案,但是很多人表示还是用的不够爽,比如用CodeChat的方案…

Vscode中Eigen库的导入问题

Vscode中Eigen库的导入问题.Vscode中Eigen库的导入问题 在Vscode中,C++外部库(这里为Eigen)的导入问题主要有库的zip文件下载、在c_cpp_properties.json和tasks.json文件中进行路径配置。另外,如果运行代码使用Code Runner插件,还需要在Code Runner中进行路径配置(即使在…

最新更新!扣子(Coze)接入地表最强DeepSeek-R1大模型,超全攻略,手把手教学,完全免费教程

‍ 最新消息,国产地表最强大模型可以接入Coze平台了,今天斜杠君为大家带来了最细接入攻略,大家快学起来吧~ 备注:需要登录专业版火上引擎接入,开通专业版的同学需要开通一下。 接下来,话不多说,斜杠君用最简单的方式教给大家。 大家可以关注收藏,以免之后找不到,而且也…

1.如何在python中安装playwright

1.如何在python中安装playwright 打开pycharm,进入终端,输入如下的2个命令行代码即可自动完成playwright的安装 pip install playwright ——》在python中安装playwright第三方模块 playwright install ——》安装playwright所需的工具插件和所支持的浏览器 看到这里,是否想…

最新扣子(Coze)案例教程:DeepSeek 图像生成,用扣子应用打造超萌表情包生成器,手把手教学,完全免费教程

上一篇文章和大家分享了如何把DeepSeek-R1接入到扣子智能体中进行使用,这篇教程让我们来应用一下DeepSeek,使用DeepSeek结合工作流中的图像生成节点,打造一个表情包生成器的应用。 应用作用:输入一个人物或动物主题,生成一组表情包。 首先我们来看一下生成后的效果: 图像…

我悟了!原来本地图片预览还能这样搞

在网页开发中,经常会遇到需要让用户上传图片并在上传前进行预览的需求。这样做的好处显而易见:用户可以立即看到自己选择的图片是否正确,避免了不必要的上传和服务器资源浪费,提升了用户体验。Hey, 我是 Immerse 本文首发于 【沉浸式趣谈】,我的个人博客 https://yaolifen…

octave画高通滤波、超前,滞后补偿器的幅频响应图

octave代码非常简单:pkg load control s=tf(s); k=0.5; sysG1=k*(0.005*s)/(0.005*s+1); sysG2=k*(0.8*s+1)/(0.1*s+1); sysG3=k*(s+1)/(5*s+1); figure bode(sysG1) figure bode(sysG2) figure bode(sysG3)也可以借助循环,看如下代码:1 pkg load control2 s=tf(s);3 k=0.5;…