ASP.NET Core 进程内与进程外的性能对比

2020-09-16 14:27:57 浏览数 (1)

本文内容是《深入去浅出 ASP.NET Core》提供的扩展内容,毕竟在书里说进程内外的性能说明对比,对于初学者而言,稍微复杂了点。

我在 B 站的视频是基于.NET Core 2.2 提供的案例,在书籍中提供的是.NET Core 3.1 的案例。有人问,默认进程到底是进程外还是进程内。

ASP.NET Core 默认进程

ASP.NET Core 2.2 由默认的进程外,所以需要我们指定下项目文件中的进程信息。而从 ASP.NET Core 3.X 开始,dotnet 开发团队又将它修改为了进程内。

所以请记住:

  • ASP.NET Core 2.X 及以前默认是进程外托管
  • ASP.NET Core 3.X 默认为进程内托管

我最近查询了下,应该说最早.NET Core 就不支持进程内,所以也是慢慢迭代到支持进程内的。

ASP.NET Core 的进程内托管

使用 InProcess 托管,应用程序托管在 IIS 工作进程(w3wp.exe 或 iisexpress.exe)中。只有一个 Web 服务器,它是承载我们的应用程序的 IIS 服务器,如图是进程内托管图。

在 ASP.NET Core 2.2 后,IIS 上有了一个 In Process 托管模型,该模型直接在 IIS 应用程序池内部托管 ASP.NET Core,而无需使用代理 dotnet.exe 运行.NET Core 本机 Kestrel Web 服务器的外部实例。

进程内模型不使用 Kestrel,而是使用 IISHttpServer()直接在 IIS 应用程序池内部托管的新 Web 服务器实现,该实现与传统的 ASP.NET 被引入 IIS 的方式有些相似。

此实现形式,应用会访问本机 IIS 对象以建立创建的请求数据,并将 HttpContext 其传递到 ASP.NET Core 中间件管道。

当然这些都是.NET Core 层面的处理,我们作为应用开发者,基本会去关心和留意它。

但是就是这个调整,大大的提高了 ASP.NET Core 在 IIS 上的请求吞吐量。

实际生产环境中 InProces 还是 OutOfProcess

对于部署项目到 IIS 环境中,您几乎肯定希望是采用 InProcess 模式进行托管,因为它提供了更好的性能,并且通常占用的资源较少,因为它避免了 IIS 和 Kestrel 之间可能存在的网络抖动。

但是是其他场景下,我就推荐采用 OutOfProcess 模式了,比如:

  • 用于故障排除和调试故障服务器(例如,您可以在启用控制台日志记录,查看更加详细的信息)。
  • 同一个应用程序实现 100%兼容,无论是部署在 Windows 还是 Linux 上,Kestrel 的主要机制是可以处理所有平台上的 HTTP 请求。
  • 使用 InProcess 模型时,则不会使用 Kestrel 服务(这个在我的书中有详细说明),而是直接与 IIS 的请求管道中的模块进行通信。

调整为进程外托管

我们可以通过修改项目文件,配置AspNetCoreHostingModel值以下

代码语言:javascript复制
<AspNetCoreHostingModel>OutOfProcess</AspNetCoreHostingModel >

然后就可以调整为进程外托管模式。

关于更多进程内和进程外的知识,可以查看《深入浅出 ASP.NET Core》的 5.4 章内容。

West Wind WebSurge 测试

我准备了一个项目 Demo,使用 West Wind WebSurge 软件来测试下进程内与进程外项目的吞吐情况。

它还可以检查服务器的 HTTP 响应,并检查 Web 服务器 Kestrel 或 Microsoft IIS 作为 Web 服务器:

ASP.NET Core2.X 进程外(OutOfProcess)

ASP.NET Core2.X 进程内(Inprocess)

性能对比

使用新的 In Process 模型的明显原因是它更快,使用的资源更少,因为它直接在 IIS 应用程序池的过程中运行。没有内部 HTTP 流量和开销,请求将立即处理。

本次测试,仅仅是为了对比进程内核进程外的性能对比,不作为其他应用程序的抗负载能力的参考。

因为访问的接口很简单,请求仅表明可以大大提高潜在的吞吐量,但是对于长流程的请求和请求访问时间,应用程序处理的开销也增加,所以理性看待。

寻求高的性能始终是一个好主意,提供程序的吞吐量意味着更少的请求延迟,更快的响应时间以及更少的服务器开销,增加更多的负载能力。

我准备了一台 4 核 8G 的笔记本,因为这台笔记本装了很多其他应用,因此产生的结果肯定不如服务器的结果,现在开始进行测试。

进程内托管模式结果

上面的进程内托管模式,我们可以看到一共发送了 3.7W 次请求,每秒 633 次请求的处理速度。

进程外托管模式结果

切换为进程外后,一共处理了 1.3W 次请求,每秒是 217 次请求处理速度。

可以看到进程外的性能比进程内的较低。

再次说明,因为我的 PC 机中安装了和运行了大量的其他应用,给予它测试的内存和 CPU 是不足够的,感兴趣的可以,自己进行测试。

最后

尽管 IIS 被不停的边缘化以支持在 Linux 和 Docker 上托管,但请记住,如果发布到 云原生平台,如 Azure 的 WebAPP 或者其他未明确指定的平台,IIS 依然是 ASP.NET Core 部署的默认模型。这说明 IIS 确实还在很多场景中有广泛的使用,因此它不会很快消失。微软通过新增的进程内模型,提供更好的性能处理机制以此来增加对它的支持。

现在开始,我们有两种选择,

  • 可以使用OutofProcessing(通过 IIS 代理请求)并使用完全独立的 ASP.NET Core 控制台应用程序(通过基于.NET 的 Kestrel Web 服务器使用)托管在 IIS 上,
  • 也可以使用InProcess托管模型,它与经典 ASP.NET 通过其自身的本机 API 与 IIS 进行交互的方式更为相似。
  • In Process 模型在请求吞吐量方面要快得多,因此在几乎所有情况下,在 IIS 上托管时,您都希望选择 InProcess 模型。

文章参考来源:https://weblog.west-wind.com/posts/2019/Mar/16/ASPNET-Core-Hosting-on-IIS-with-ASPNET-Core-22#check-the-response-server-header

案例源代码地址:https://github.com/RickStrahl/AspetCoreIISInprocessHostingSample

0 人点赞