ASP.NET Core In Process Hosting on IIS with ASP.NET Core 2.2(转载)
ASP.NET Core 2.2 has been out for a while now and with it come some significant improvements to the hosting model if you plan on hosting in IIS. In previous versions you were required to host ASP.NET Core applications by proxying requests from IIS into the ASP.NET Core Kestrel server with IIS effectively as a Reverse Proxy.
In version 2.2 ASP.NET Core adds support for direct in-process hosting which improves throughput considerably using an easy mechanism that allows switching between in-process and out-of-process hosting.
ASP.NET Core 2.2 adds InProcess Hosting on IIS
The original versions of ASP.NET Core required you to host on IIS using an Out of Process model that proxies through IIS. Requests hit IIS and are forwarded to your ASP.NET Core app running the Kestrel Web Server.
Out of Process Hosting (pre v2.2 model)
Figure 1 - Out of Process Hosting uses IIS as proxy to forward requests to your dotnet.exe hosted Console application.
With ASP.NET Core 2.2 there's now an In Process hosting model on IIS which hosts ASP.NET Core directly inside of an IIS Application pool without proxying to an external dotnet.exe instance running the .NET Core native Kestrel Web Server.
In Process Hosting (v2.2 and later)
Figure 2 - With In Process hosting your application runs inside of the IIS application pool and uses IIS's intrinsic processing pipeline.
The In Process model does not use Kestrel and instead uses a new Web Server implementation (IISHttpServer) that is hosted directly inside of the IIS Application Pool that is some ways similar to the way classic ASP.NET was plumbed into IIS.
This implementation accesses native IIS objects to build up the request data required for creating an HttpContext which is passed on to the ASP.NET Core middleware pipeline. As with the old version, the the Application Pool that hosts the ASP.NET Core Module does not have to be running .NET since the module hooks into the native code IIS pipeline.
Although this sounds like a fairly drastic change, from an application compatibility aspect I've not run into any issues that have had any effect on my applications other than faster request throughput.
This feature improves throughput for ASP.NET Core requests on IIS significantly.
Microsoft has done a great job of introducing this hosting model with minimal impact on existing configuration: It's easy to switch between the old OutOfProcess and InProcess models via a simple project configuration switch that is propagated into the deployed web.config file.
OutOfProcess or InProcess? Use InProcess
For new applications that are deployed to IIS you almost certainly will want to use InProcess hosting because it provides better performance and is generally less resource intensive as it avoids the extra network hop between IIS and Kestrel and maintaining an additional process on the machine that needs to be monitored.
There are a few cases when OutOfProcess hosting might be desirable, such as for trouble shooting and debugging a failing server (you can run with console logging enabled for example) or if you want to be 100% compatible between different deployments of the same application, whether it's on Windows or Linux, since Kestrel is the primary mechanism used to handle HTTP requests on all platforms. With the InProcess model you're not using Kestrel, but rather a custom IISHttpServer implementation that directly interfaces with IIS's request pipeline.
But for most intents and purposes I think running InProcess on IIS is the way to go, unless you have a very specific need to require Kestrel and OutOfProcess hosting.
New ASP.NET Core projects automatically configure projects for InProcess hosting, but if you're coming from an older project you may have to update your project settings explicitly.
Settings Affected
Switching between hosting modes is very easy and requires only a configuration switch either inside of your .csproj file or in web.config.
Project Change - <AspnetCoreHostingModel>
The first change is in the project file where you can specify the hosting model by using the <AspNetCoreHostingModel> key.
To use InProcess hosting add the following to your Web project's .csproj file:
<PropertyGroup> <TargetFramework>netcoreapp2.2</TargetFramework> <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel> </PropertyGroup>
The relevant project setting is the AspNetCoreHostingModel which can be InProcess or OutOfProcess. When missing it defaults to the old OutOfProcess mode that uses an external Kestrel server with IIS acting as a proxy.(经测试,这一点在ASP.NET Core 3.0中又不一样了,如果在ASP.NET Core 3.0的.csproj项目文件中,缺失AspNetCoreHostingModel标签,那么ASP.NET Core 3.0项目发布后,生成的web.config文件默认是InProcess模式的)
This affects how dotnet publish creates your configuration when you publish your project and what it generates into the web.config file when the project is published.
web.config Change
The <AspnetCoreHostingModel> project setting affects the generated build output by writing configuration data into the web.config file for the project. Specifically it sets the the hostingModel attribute on the <aspNetCore> element that is generated:
<?xml version="1.0" encoding="utf-8"?> <configuration> <location path="." inheritInChildApplications="false"> <system.webServer> <handlers> <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" /> </handlers> <!-- hostingModel is the new property here --> <aspNetCore processPath="dotnet" arguments=".\WebApplication1.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="InProcess" /> </system.webServer> </location> </configuration>
If the <AspNetCoreHostingModel> key in the project is set to OutOfProcess, the hostingModel attribute is not generated(ASP.NET Core 3.0还是会生成hostingModel属性,值为OutOfProcess) and the application defaults to OutOfProcess.
Refresh web.config on Publish
I found that unlike the rest of the files in the publish output folder the web.config file was not updated on a new publish unless I deleted the file (or the entire publish folder). If you make changes that affect the IIS configuration I recommend to nuke the publish folder and doing a clean publish.
Note that you can easily switch between modes after publishing by simply changing the value between InProcess and OutOfProcess in the web.config in the Publish folder. This can be useful for debugging if you want to log output on a failing application with verbose log settings enabled for example.
Just remember that if you change publish output it will be overwritten next time you publish again.
Cool - this single setting is all you need to change to take advantage of InProcess hosting and you'll gain a bit of extra speed connecting to your application.
Checking for InProcess or OutOfProcess Hosting
Once an application is in production you might want to ensure that you're using the appropriate hosting mechanism. You can check in a couple of ways.
Check for the dotnet process
You can check for a dotnet process that runs your application's dll. If you're running out of process you should have a dotnet process that's running your application's dll:
OutOfProcess uses dotnet.exe to run your application in proxy forwarding mode when using IIS and you can see that separate process in the Process list.
If the dotnet.exe process is running with your application's specific command line, you know your app is running Out Of Process.
Check the Response Server Header
You can also check the HTTP response for the server and check for either Kestrel or Microsoft IIS as the Web Server for OutOfProcess and Inprocess modes respectively :
OutOfProcess
Out of Process IIS Hosting forwards requests to an externally hosted ASP.Core application running Kestrel.
InProcess
In Process IIS Hosting implements the Web server host inside of the Asp.Net Core Module using IIS infrastructure. The Server reads Microsoft-IIS/10.0.
Performance
So the obvious reason to use the new In Process model is that it's faster and uses less resources as it's running directly in process of the IIS Application Pool. There is no internal HTTP traffic and overhead and requests are processed immediately.
Summary
While IIS is getting marginalized in favor of hosting on Linux and Docker, remember that IIS is still Azure's default ASP.NET Core deployment model if you publish to an AppService and don't explicit specify platform. This means IIS is still in use in more scenarios than just self-hosted IIS applications, so it's not going away anytime soon. And Microsoft just backed that up with the new in processing hosting features that provide much better performance.
You now have two options for hosting on IIS using either the now classic Out of Processing that proxies requests through IIS and uses a completely self-contained ASP.NET Core console application using the .NET Based Kestrel Web Server, or you can use the In Process Hosting model which is more similar to the way classic ASP.NET used to interface with IIS through its own native APIs.
The new In Process model is considerably faster in terms of request throughput so in almost all cases when hosting on IIS you'll want to choose the InProcess model.
The key setting to remember is to set:
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
in your project or set it to OutOfProcess to use the old mode. The setting will generate the required hostingModel attribute in web.config which can also be explictly set in this file to make runtime changes to the host behavior.
This is a great improvement that gets you a decent performance bump for literally setting a switch.
本文根据下文裁剪:
ASP.NET Core In Process Hosting on IIS with ASP.NET Core 2.2
还可以参考:
Host ASP.NET Core on Windows with IIS
In-process hosting with IIS and ASP.NET Core
Out-of-process hosting with IIS and ASP.NET Core