Understanding what options are available for ASP.net Core hosting and their impact on the web application.
The new ASP.NET core 2.2 was upgraded with some improvements to the hosting model if you were to host it with IIS. In the previous versions you were expected to host the ASP.NET Core applications by using a proxy web server such as IIS on windows or NGINX or Apache. However with the new ASP.NET Core 2.2 you could directly host the ASP.NET Core application in Windows within the IIS or IISExpress without the need for an external server. This improves throughput as the new In-Process hosting mechanism doesn’t require internal HTTP requests hopping or other inter-process communication.
In this post I’ll focus on the new In-Process hosting model since that’s what’s changed and is improved, however I’ll be also evaluating the basics of Out-Of-Process hosting model as well and under where it could be best used.
The earlier versions of ASP.NET Core required you to host the application in IIS using an Out-of-Process hosting model that proxies through IIS. Requests that hit IIS or IISExpress are forwarded to the ASP.NET Core web application running within Kestrel Web Server. However with the new In-Process hosting model this is not the case. Instead of forwarding requests to Kestrel, a new Web Server implementation (IISHttpServer) is hosted directly inside the IIS Application Pool, which then serves the request. This is some ways similar to how classic ASP.NET was used to operate.
This implementation accesses native IIS objects to build up the request data required for creating an HttpContext which is then passed on to the ASP.NET Core middleware pipeline. As with the Out-Of-Process hosting model 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.
Apparently this has much high throughput and performance improvement when compared to the Out-Of-Process hosting model.
In the In-Process hosting model, the ASP.NET Core application runs in the same process as its IIS Worker Process. IIS worker process is the main thread or process which is how the IIS or the IISExpress works on a Windows based server or a machine. This is the default behavior if the web application is hosted in IIS or IISExpress. So in your visual studio if you chose to debug or develop your application via the IIS or IISExpress the application is hosted and run within this IIS worker process.
However do keep in mind that ASP.NET Core applications that target the .NET framework doesn’t support In-Process hosting yet.
The following diagram depict how an in-process hosting model would operate. As you may notice there three important players in this scenario ( ASP.NET Core Module, IHTTPServer, Application Code)
When the request hits the Web server (assuming this is a Windows based server) the kernel mode HTTP.sys driver processes the request and routes the native request to IIS or IISExpress to the websites configured port. The ASP.NET core module which receives the native request and passes it to the IIS HTTP Server. The IIS HTTP Server is in-process server implementation which converts the request from native to managed. Thereafter the request is sent to the ASP.NET Core middleware pipeline.
The pipeline handles the request and passes it on to the HTTPContext instance to the application logic. The response of the application is then passes back through the same path. i.e it passes the middleware pipeline and thereafter to the IIS HTTP Server, which then sends the request to the client.
If you happen to choose IISExpress or IIS to start ASP.NET core application in Visual Studio it runs the application as a In-Process hosting model. To experiment in which process the application is run you could edit the StartUp.cs as shown below and then choose IISExpress to run the application.
Out-of-process hosting model
In the Out-Of-Process hosting model the ASP.NET Core application runs in a separate process from that of the IIS or IIS Express process. This was the case for all ASP.NET Core application prior to version 2.2 . In this model the IIS basically acts like a proxy server.
It’ll be the responsibility of the ASP.NET Module to mange the ASP.NET Core application process. Upon request from the web the ASP.NET Core Module starts the ASP.NET Core application. When the requests arrive from the web to the kernel-mode HTTP.sys driver it routes the requests to IIS (or any other web server). The ASP.NET Core Module forwards the requests to Kestrel on a random port for the app, which isn’t port 80 or 443.
After Kestrel picks up the request from the ASP.NET Core Module, the request is pushed into the ASP.NET Core middleware pipeline. The middleware handles the request and passes it on as an HTTPContext instance to the ASP.NET Core application logic. The ASP.NET Core application response is passed back to IIS, which pushes it back out to the HTTP client that initiated the request.
By default if you run the web application via command line (dotnet.exe) the web application is hosted as an out of process hosting model, regardless of what you choose in the AspNetHostingModel in the project file.
Typically in production when out-of-process hosting model is used, two web servers are involved in serving the web application, first the external web server and second the internal web server. Usually the external web server is an IIS server or it could be NGINX or Apache web server. The external web server acts as the reverse proxy server, where as the it’s the Kestrel which processes the requests.
A question arises as to why you require two web servers rather than using the Kestrel as the internet facing web server. In the next section I will elaborate more with a brief over view to what Kestrel is.
Kestrel is open-source event-driven, asynchronous I/O based server used to host ASP.NET Core applications on any platform.
It’s a listening server and a command-line interface. It is based on the libuv library, the same one used by node.js. Libuv supports an event-driven style of programming. Some of its core utilities include non-blocking network support and asynchronous file system access with other benefits.
The Kestrel web server is not meant to be an Internet facing web server, but rather an application server that handles very specific data processing tasks. Kestrel is optimized for application scenarios and it not meant for other things like static file serving or managing the server’s lifetime.
For this reason you generally do not want to run Kestrel directly in a Web application. This is true on Windows with IIS and also on Linux where you tend to use a Web server NGINX or Apache to handle non-application concerns.
Following are some of many reason why you may want to use a fully fledged web server as opposed to something like Kestrel
- Kestrel cant do port sharing, like what IIS or Apache does.
- Manage life time of the application.
- Static file serving- Not that Kestrel can’t do it but its not optimized for it.
- Administration Features
- Managing SSL certificates
- Full logging and Http Request tracing facilities
In-Process Vs Out-Of-Process
Given the above facts you most certainly want to use the In-Process hosting model since it provides better performance and consumes less resources as it doesn’t require an additional process for Kestrel, plus it also avoids extra communication between the IIS and Kestrel.
However there are cases where you may want to opt for Out-Of-Process hosting such as in the case of hosting of the same web application in Windows and in Linux. When talking about hosting the application in different platforms Kestrel is the primary mechanism used to handle HTTP requests on all platforms.
However running In-Process on IIS is the way to go, unless you have a very specific need to require Kestrel.