-
Notifications
You must be signed in to change notification settings - Fork 25.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
In-process hosting model coverage #8658
Conversation
Link fix
d23ade7
to
41db000
Compare
|
||
* Host an ASP.NET Core app inside of the IIS worker process (`w3wp.exe`), called the [in-process hosting model](#in-process-hosting-model). | ||
|
||
* Redirect web requests to a backend ASP.NET Core app running the [Kestrel server](xref:fundamentals/servers/kestrel), called the [out-of-process hosting model](#out-of-process-hosting-model). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Redirect -> Forward
|
||
![ASP.NET Core Module](aspnet-core-module/_static/ancm-inprocess.png) | ||
|
||
A request arrives from the web to the kernel-mode HTTP.sys driver. The driver routes the request to IIS on the website's configured port, usually 80 (HTTP) or 443 (HTTPS). The module manages the native request context and converts it into a managed request <xref:Microsoft.AspNetCore.Http.HttpContext> for a custom <xref:Microsoft.AspNetCore.Hosting.Server.IServer> implementation, `IISHttpServer`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
custom
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The module receives the native request and passes control to IISHttpServer, which is what converts that request from native to managed.
|
||
### Out-of-process hosting model | ||
|
||
Because ASP.NET Core apps run in a process separate from the IIS worker process, the module handles process management. The module starts the process for the ASP.NET Core app when the first request arrives and restarts the app if it crashes. This is essentially the same behavior as seen with apps that run in-process that are managed by the [Windows Process Activation Service (WAS)](/iis/manage/provisioning-and-managing-iis/features-of-the-windows-process-activation-service-was). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
restarts it if it shuts down or crashes.
|
||
The module specifies the port via an environment variable at startup, and the IIS Integration Middleware configures the server to listen on `http://localhost:{port}`. Additional checks are performed, and requests that don't originate from the module are rejected. The module doesn't support HTTPS forwarding, so requests are forwarded over HTTP even if received by IIS over HTTPS. | ||
|
||
After Kestrel picks up the request from the module, the request is pushed into the ASP.NET Core middleware pipeline. The middleware pipeline handles the request and passes it on as an `HttpContext` instance to the app's logic. The app's response is passed back to IIS, which pushes it back out to the HTTP client that initiated the request. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIS Integration also adds middleware that update Request.Scheme, Connection.RemoteIP, and request.PathBase to account for the forwarding that has taken place.
When using [IIS](/iis/get-started/introduction-to-iis/introduction-to-iis-architecture) or [IIS Express](/iis/extensions/introduction-to-iis-express/iis-express-overview) as a reverse proxy for ASP.NET Core, the ASP.NET Core app runs in a process separate from the IIS worker process. In the IIS process, the [ASP.NET Core Module](xref:fundamentals/servers/aspnet-core-module) coordinates the reverse proxy relationship. The primary functions of the ASP.NET Core Module are to start the ASP.NET Core app, restart the app when it crashes, and forward HTTP traffic to the app. For more information, see [ASP.NET Core Module](xref:fundamentals/servers/aspnet-core-module). | ||
::: moniker range=">= aspnetcore-2.2" | ||
|
||
When using [IIS](/iis/get-started/introduction-to-iis/introduction-to-iis-architecture), the ASP.NET Core app either runs in the same process as the IIS worker process (the *in-process* hosting model) or in a process separate from the IIS worker process (the *out-of-process* hosting model). When using [IIS Express](/iis/extensions/introduction-to-iis-express/iis-express-overview), the app always runs with the in-process hosting model. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIS Express supports in-proc and out-of-proc.
|
||
* Sharing an app pool among apps isn't supported. Use one app pool per app. | ||
|
||
* When using [Web Deploy](/iis/publish/using-web-deploy/introduction-to-web-deploy) or manually placing an [app_offline.htm file in the deployment](xref:host-and-deploy/iis/index#locked-deployment-files), the app might not shut down immediately if there's an open connection. For example, a websocket connection may delay app shut down. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this different from our normal graceful shutdown behavior out of proc?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be the same.
|
||
public static IWebHostBuilder CreateWebHostBuilder(string[] args) => | ||
WebHost.CreateDefaultBuilder(args) | ||
.UseContentRoot(AppDomain.CurrentDomain.BaseDirectory) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pakrym can UseIIS do this for you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, this section can go.
@@ -117,8 +266,20 @@ If a file with the name *app_offline.htm* is detected in the root directory of a | |||
|
|||
While the *app_offline.htm* file is present, the ASP.NET Core Module responds to requests by sending back the contents of the *app_offline.htm* file. When the *app_offline.htm* file is removed, the next request starts the app. | |||
|
|||
::: moniker range=">= aspnetcore-2.2" | |||
|
|||
When using the out-of-process hosting model, the app might not shut down immediately if there's an open connection. For example, a websocket connection may delay app shut down. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
||
**In-process hosting model** | ||
|
||
A typical *Program.cs* calls <xref:Microsoft.AspNetCore.WebHost.CreateDefaultBuilder*> to begin setting up a host. `CreateDefaultBuilder` calls the <xref:Microsoft.AspNetCore.Hosting.WebHostBuilderIISExtensions.UseIISIntegration*> method to boot the [CoreCLR](/dotnet/standard/glossary#coreclr) and host the app inside of the IIS worker process (`w3wp.exe`). Performance tests indicate that hosting a .NET Core app in-process delivers higher request throughput compared to hosting the app out-of-process and proxying requests to [Kestrel](xref:fundamentals/servers/kestrel). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UseIIS?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's there ... ur asking for more coverage on it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For in-proc it's UseIIS, not UseIISIntegration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aye! I see it. Add UseIIS to CreateDefaultBuilder aspnet/MetaPackages#278
... | ||
``` | ||
|
||
The ASP.NET Core Module generates a dynamic port to assign to the back-end process. `CreateDefaultBuilder` calls the <xref:Microsoft.AspNetCore.Hosting.WebHostBuilderIISExtensions.UseIISIntegration*> method, which picks up the dynamic port and configures Kestrel to listen on `http://localhost:{dynamicPort}/`. This overrides other URL configurations, such as calls to `UseUrls` or [Kestrel's Listen API](xref:fundamentals/servers/kestrel#endpoint-configuration). Therefore, calls to `UseUrls` or Kestrel's `Listen` API aren't required when using the module. If `UseUrls` or `Listen` is called, Kestrel listens on the port specified when running the app without IIS. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If
UseUrls
orListen
is called, Kestrel only listens on the ports specified when running the app without IIS.
@Tratcher I addressed the non-❓ feedback. |
The ASP.NET Core Module only works with Kestrel. The module is incompatible with [HTTP.sys](xref:fundamentals/servers/httpsys) (formerly called [WebListener](xref:fundamentals/servers/weblistener)). | ||
::: moniker range=">= aspnetcore-2.2" | ||
|
||
When hosting out-of-process, the module only works with Kestrel. The module is incompatible with [HTTP.sys](xref:fundamentals/servers/httpsys) (formerly called [WebListener](xref:fundamentals/servers/weblistener)). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mention here that inprocess has isn't own IIS server implementation.
|
||
ASP.NET Core ships two server implementations: | ||
ASP.NET Core ships three server implementations: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be done in a separate PR, but I think we should make inprocess and out of process separate pages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TL;DR
I considered it, but it looks like organization, reader flow (navigation), and/or duplication will ensue and make a big mess if the hosting model scenarios are split.
Full explanation
I'll describe the landscape and what I ran into.
In ancient times, the team set up the outline like this ...
- Fundamentals
- Servers - Basic descriptions and links
- Kestrel - Description and configuration
- HTTP.sys - Description and configuration
- ANCM - Basic description only (no config)
- Servers - Basic descriptions and links
- Host-and-deploy ("Publishing" in the olden days) - Basic descriptions and links
- IIS - Description and configuration
- ANCM - Configuration
These topics and the content they provide are NOT easy to arrange.
🐉 There be dragons here! 🐉
- Kestrel is behind a proxy or on its own. Kestrel is fully baked in; others are more hybrid.
- ANCM/IIS bear some explanation early (Fundamentals), but IIS isn't part of .NET Core and fits better in more of a "host/deploy/proxy" set of topics (Host-and-deploy).
- IIS has a ton of config.
- ANCM has a lot of separate config.
One thing that could be done is that Kestrel and HTTP.sys could be split between basic overview and configuration. Kestrel in the Server node could merely be an overview (like ANCM/IIS is). Kestrel in the Host-and-deploy node could hold the configuration. Same deal for HTTP.sys. That would consistently introduce server concepts in Fundamentals but configure every scenario in Host-and-deploy (i.e., Kestrel can "host," so it fits; one just doesn't "deploy" anything to it like reverse proxy scenarios). I'd also pitch making that ANCM topic in the Servers node ANCM and IIS and introduce them with greater balance + see what, if anything, of a general nature in the Host-and-deploy IIS topic can be moved there.
Anyway .... that's a digression!
I considered splitting ANCM in-proc and out-of-proc, but I wasn't looking at the Servers node for that split because the content is so minimal. It's just about three paragraphs of text, a list, and an image. If in-proc and out-of-proc are split out, the reader flow is ...
- Servers landing
- In-proc page
- Back to Servers landing
- Out-of-proc page
- Back to Servers landing
... mmm ... 🤔 ... not so good.
The other spot to consider for a split is with the configuration in the Host-and-deploy node.
There's no natural way to split the hosting models without creating one of two problems ...
- A lot of duplicated content.
- An ugly navigation flow for the reader (same as above ☝️)
If configuration is split out for the two hosting models with common config in an ANCM landing page, then the outline is ...
- host-and-deploy/ancm/index - Common config
- host-and-deploy/ancm/in-proc - In-proc config
- host-and-deploy/ancm/out-of-proc - Out-of-proc config
BUT consider ...
- That landing page doesn't explain in-proc/out-of-proc config (it just links). The reader has to navigate in and out of the other two topics, then they nav back to the common config in the landing page for the rest of the ANCM config.
- The landing page either skips the
hostingModel
attribute and pulls it from the attributes table (bad) or the attribute table gets duplicated across the in-proc and out-of-proc topics (also bad; especially bad because in-proc and out-of-proc topics start to maintain common content).
I didn't see a good workable outline for either the Servers node or the Host-and-deploy node. Therefore as you see, I in-lined the content in both spots.
Do you have a different outline/approach in mind?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that duplicate content/ navigation flow makes the change confusing. This organization seems fine then 😄
I've made all of the requested changes except for ...
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like for us to continue iterating on this. I will write some documentation on how now there are two ANCM modules and roll forward behavior. Would you prefer me making a PR directly or sending you a word document?
@jkotalik I suggest Word doc. It's easier to me to position + wordsmith paragraphs at the same time that way. Give me notes tho if you have a specific location where you think something should go. Best to do that by referencing the line numbers on the diff. If you'd prefer not to go that far, then I'll work out locations, and you can tell me on review of the commit if you think the spots I chose look good. |
Sounds good. I'll work on something within the next couple of days. |
@jkotalik I'm back tomorrow ... but if you need more time, no worries ... I have a ton of stuff to work on the rest of this week. We could pick back up with this next week. |
I have some stuff locally but nothing complete yet. I should have some time tonight to crank it out. |
@jkotalik can you give me an ETA on finishing the review? |
I already approved this current iteration here. Do you prefer to have my documentation with this current PR or in a separate PR? |
@jkotalik Current PR if that suits your schedule. If you need several more days tho, then we can go ahead here and push this forward to a merge. |
I would need at least one day. Want to schedule a meeting tomorrow for us to sync on what I have so far? |
I scrolled up and noticed ...
... which doesn't seem to pertain directly to "in-proc" updates. We're talking about adding one section to the ANCM configuration reference topic to cover the additional content? If so, I think your hunch was right. Let's do a new issue+PR. Is it easier for you to have a meeting over sending notes/text? |
Yep! I'll make a separate PR/ send you notes once I wrap up documentation.
Now that we aren't merging two docs together, we shouldn't need a meeting. |
@jkotalik Ok, thanks. We can push forward here with a UE review now to wrap this puppy up. |
<configuration> | ||
<system.webServer> | ||
<handlers> | ||
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has to be AspNetCoreModuleV2
<configuration> | ||
<system.webServer> | ||
<handlers> | ||
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here.
Fixes #5599
Fixes #5449
Fixes #5403
Internal Review Topic (fundamentals/servers/ancm)
Internal Review Topic (fundamentals/servers/index)
Internal Review Topic (host-and-deploy/ancm)
Internal Review Topic (host-and-deploy/iis/index)