Сервер и публикация приложения
Сервер
Традиционно приложения ASP.NET развертывались на веб-сервере IIS. Однако поскольку ASP.NET Core имеет кроссплатформенную природу, потребовалось отвязать ASP.NET Core от IIS и в целом от Windows. И на данный момент для развертывания приложения ASP.NET Core поддерживает развертывание приложения на следующих веб-серверах:
IIS и IIS Express, а также предоставляет возможность запускать приложение без IIS в рамках собственного процесса с помощью двух дополнительных http-серверов, которые идут вместе с ASP.NET Core:
IIS HTTP Server
Microsoft.AspNetCore.Server.HttpSys (или просто WebListener) (в предыдущих версиях ASP.NET Core назывался WebListener)
Microsoft.AspNetCore.Server.Kestrel (или просто Kestrel)
HTTP.sys и Kestrel представляют два дополнительных http-серверов, которые идут вместе с ASP.NET Core. HTTP.sys работает только на платформе Windows, а Kestrel является кроссплатформенным.
Кроме того, если приложение использует Kestrel, то в качестве прокси-сервера оно может использовать также IIS, Apache и Nginx. То есть Apache, Nginx или IIS будут получать запросы и перенаправлять их приложению, которое работает на Kestrel. Такая схема, когда запросы идут не напрямую на Kestrel, проходят черех IIS/Apache/Nginx, позволяет нам задействовать возможности, которые есть у этих веб-серверов, но отсутствуют у Kestrel.
IIS и IIS Express
По умолчанию приложения ASP.NET работают с сервером IIS. Однако надо заметить, что по сравнению с предыдущими версиями ASP.NET при работе с ASP.NET Core IIS не использует инфраструктуру System.Web , что значительно повышает производительность приложения. Кроме того, IIS поддерживает множество различного функционала, имеет множество возможностей по администрированию и управлению сервером и размещенными на нем приложениями.
AspNetCoreModule
Хостирование приложений ASP.NET Core на IIS происходит с помощью нативного модуля IIS под названием AspNetCoreModule , который сконфигурирован таким образом, чтобы перенаправлять запросы на веб-сервер Kestrel. Этот модуль управляет запуском внешнего процесса dotnet.exe, в рамках которого хостируется приложение, и перенаправляет все запросы от IIS к этому хостирующему процессу.
При получении первого запроса к приложению AspNetCoreModule запускает процесс для этого приложения и перезапускает процесс, если приложение падает.
Вначале все входящие запросы проходят через драйвер Http.Sys, который перенаправляет их на IIS на основной порт (80) или на порт SSL (443). Затем запрос от IIS перенаправляется приложению ASP.NET Core на определенный порт, на котором запущено приложение (любой другой порт, отличный от 80/443). Веб-сервер Kestrel получает запрос и передает его в виде объекта HttpContext в конвейер middleware ASP.NET Core. Конвейер middleware в приложении обрабатывает запрос и возвращает IIS результат обработки, который затем посылается HTTP-клиенту (например, веб-бразеру).
Для использования модуля он должен быть установлен. Он распространяется в рамках пакета ASP.NET Core Server Hosting Bundle. Но при установки Visual Studio с ASP.NET Core модуль AspNetCoreModule уже автоматически устанавливается для IIS Express / IIS, поэтому разработчикам, как правило, не придется его дополнительно доустанавливать.
Также для использования модуля непосредственно в приложении в проекте должен быть установлен Nuget-пакет Microsoft.AspNetCore.Server.IISIntegration .
Для интеграции с IIS для объекта WebHostBuilder вызывается метод UseIISIntegration() . Этот метод ищет переменные окружения, которые устаналиваются модулем AspNetCoreModule, если подобных переменных не установлено, то метод по сути ничего не делает.
Мы можем вызвать этот метод явно в файле Program.cs:
Однако это необязательно делать, поскольку при запуске приложения через IIS система автоматически вызывает данный метод.
Среди преимуществ использования именно IIS, а не Kestrel следует отметить работу со статическими файлами. В стандартном веб-приложении ASP.NET Core за взаимодействие со статическими файлами отвечает middleware StaticFiles, которое было рассмотрено в одной из предыдущих тем. Но на данный момент оно слабо отптимизировано и не поддерживает кэширование. И если мы используем чистый Kestrel, то он при обращении к статическим файлам каждый раз считывает их из файловой системы. А если мы используем IIS в качестве прокси для сервера, то мы можем воспользоваться встроенными возможностями IIS по кэшированию. В частности, IIS кэширует ранее считанный с диска статический файл и при последующих обращениях к нему берет этот файл из кэша, тем самым увеличивая производительность.
Kestrel
Kestrel представляет кроссплатформенный веб-сервер, основанный на кросплатформенной библиотеке асинхронного ввода/вывода libuv. Kestrel по умолчанию включается в проект ASP.NET Core.
При инициализации хоста у объекта WebHostBuilder вызывается метод UseKestrel() , который позволяет задействовать Kestrel. Несмотря на то, что по умолчанию исходный код в файле Program.cs не содержит этого вызова, этот метод вызывается автоматически.
Однако при настройке хоста мы можем явным образом вызвать метод UseKestrel для конфигурации сервера:
Для настройки Kestrela применяются свойства и методы объекта KestrelServerOptions . В частности, метод Listen позволяет установить порт, по которому Kestrel будет запускаться.
Свойство Limits устанавливает предельные значения для различных конфигурационных настроек. Так, свойство MaxConcurrentConnections задает максимально количество оновременно открытых соединений.
Свойство MaxRequestBodySize устанавливает максимальный размер для запроса в байтах.
Свойство MinRequestBodyDataRate задает минимальную скорость передачи данных в запросе в байтах в секунду.
Свойство MinResponseDataRate задает минимальную скорость передачи данных в исходящем потоке в байтах в секунду.
При развертывании на Windows Kestrel может применять IIS в качестве прокси-сервера, а при развертывании на Linux как прокси-серверы могут использоваться Apache и Nginx. Но также Kestrel может работать самостоятельно внтури своего процесса без IIS.
Так, по умолчанию в Visual Studio доступны две возможности для запуска: с проксированием через IIS и напрямую.
При выборе возможностей вариантов запуска мы можем по умолчанию встретить два профиля:
IIS Express (запуск с проксированием через IIS Express)
Профиль, который совпадает с названием проекта (в моем случае это HelloApp) — тот пункт, который позволяет запускать приложение в отдельном процессе без всякого проксирования через IIS. Так как в файле Program.cs установлен в качестве сервера Kestrel (методом UseKestrel() ), то в данном случае приложение будет запускать именно Kestrel. Причем по умолчанию приложение будет запускаться на 5000-порту.
И если мы выберем для запуска второй пункт, то у нас запустится консольное приложение dotnet.exe , которое запустит наше приложение. И после этого мы сможем обращаться к нашему приложению из любого браузера:
Запуск приложения с помощью Kestrel довольно прост, нам не надо устанавливать и настраивать другие веб-серверы. Однако специалисты Microsoft рекомендуют такой способ запуска преимущественно в рамках локальной внутренней сети. А если приложение открыто для глобальной сети интернет, то рекомендумым способом запуска для обеспечения большей безопасности является именно проксирование через IIS, Apache, Nginx. Подобный метод имеет ряд преимуществ по сравнению с обычным запуском приложения на Kestrel в виде самохостирующегося процесса. В частности, прокси-серверы позволяет скрыть приложения, если они не должны быть доступны напрямую. Кроме того, веб-серверы позволяет управлять нагрузкой ко всем приложениям, и предоставляют другие функции по управлению приложениями.
Собственно при создании проекта ASP.NET Core в Visual Studio такой способ используется по умолчанию.
HTTP.sys
HTTP.sys представляет HTTP-сервер для ASP.NET Core, который работает только в ОС Windows. Ранне данный сервер назывался WebListener. Он запускается поверх драйвера ядра Http.Sys . Весь функционал сервера сосредоточен в пакете Microsoft.AspNetCore.Server.HttpSys .
Итак, изменим файл Program.cs, чтобы в нем использовался не Kestrel, а HttpSys:
Если метод UseKestrel() задает в качестве сервера Kestrel, то вызов метода UseHttpSys() аналогичным образом устанавливает в качестве сервера HTTP.sys.
Теперь запустим приложение, выбрав профиль, который совпадает с названием проекта:
И у нас запустится та же самая консоль, что и при работе через Kestrel, только теперь все вызовы к приложению будут идти через WebListener.
Web server implementations in ASP.NET Core
An ASP.NET Core app runs with an in-process HTTP server implementation. The server implementation listens for HTTP requests and surfaces them to the app as a set of request features composed into an HttpContext.
ASP.NET Core ships with the following:
- Kestrel server is the default, cross-platform HTTP server implementation. Kestrel provides the best performance and memory utilization, but it doesn’t have some of the advanced features in HTTP.sys. For more information, see Kestrel vs. HTTP.sys in the next section.
- IIS HTTP Server is an in-process server for IIS.
- HTTP.sys server is a Windows-only HTTP server based on the HTTP.sys kernel driver and HTTP Server API.
When using IIS or IIS Express, the app either runs:
- In the same process as the IIS worker process (the in-process hosting model) with the IIS HTTP Server. In-process is the recommended configuration.
- In a process separate from the IIS worker process (the out-of-process hosting model) with the Kestrel server.
The ASP.NET Core Module is a native IIS module that handles native IIS requests between IIS and the in-process IIS HTTP Server or Kestrel. For more information, see ASP.NET Core Module.
Kestrel vs. HTTP.sys
Kestrel has the following advantages over HTTP.sys:
- Better performance and memory utilization.
- Cross platform
- Agility, it’s developed and patched independent of the OS.
- Programmatic port and TLS configuration
- Extensibility that allows for protocols like PPv2 and alternate transports.
Http.Sys operates as a shared kernel mode component with the following features that kestrel does not have:
- Port sharing
- Kernel mode windows authentication. Kestrel supports only user-mode authentication.
- Fast proxying via queue transfers
- Direct file transmission
- Response caching
Hosting models
Using in-process hosting, an ASP.NET Core app runs in the same process as its IIS worker process. In-process hosting provides improved performance over out-of-process hosting because requests aren’t proxied over the loopback adapter, a network interface that returns outgoing network traffic back to the same machine. IIS handles process management with the Windows Process Activation Service (WAS).
Using out-of-process hosting, ASP.NET Core apps run in a process separate from the IIS worker process, and 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 shuts down or 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).
For more information and configuration guidance, see the following topics:
ASP.NET Core ships with Kestrel server, which is the default, cross-platform HTTP server.
ASP.NET Core ships with Kestrel server, which is the default, cross-platform HTTP server.
Kestrel
Kestrel server is the default, cross-platform HTTP server implementation. Kestrel provides the best performance and memory utilization, but it doesn’t have some of the advanced features in HTTP.sys. For more information, see Kestrel vs. HTTP.sys in this document.
By itself as an edge server processing requests directly from a network, including the Internet.
With a reverse proxy server, such as Internet Information Services (IIS), Nginx, or Apache. A reverse proxy server receives HTTP requests from the Internet and forwards them to Kestrel.
Either hosting configuration—with or without a reverse proxy server—is supported.
For Kestrel configuration guidance and information on when to use Kestrel in a reverse proxy configuration, see Kestrel web server implementation in ASP.NET Core.
ASP.NET Core ships with the following:
When using IIS or IIS Express, the app runs in a process separate from the IIS worker process (out-of-process) with the Kestrel server.
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 shuts down or 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).
The following diagram illustrates the relationship between IIS, the ASP.NET Core Module, and an app hosted out-of-process:
Requests arrive from the web to the kernel-mode HTTP.sys driver. The driver routes the requests to IIS on the website’s configured port, usually 80 (HTTP) or 443 (HTTPS). The module forwards the requests to Kestrel on a random port for the app, which isn’t port 80 or 443.
The module specifies the port via an environment variable at startup, and the IIS Integration Middleware configures the server to listen on http://localhost:
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. Middleware added by IIS Integration updates the scheme, remote IP, and pathbase to account for forwarding the request to Kestrel. The app’s response is passed back to IIS, which pushes it back out to the HTTP client that initiated the request.
For IIS and ASP.NET Core Module configuration guidance, see the following topics:
ASP.NET Core ships with Kestrel server, which is the default, cross-platform HTTP server.
ASP.NET Core ships with Kestrel server, which is the default, cross-platform HTTP server.
Nginx with Kestrel
For information on how to use Nginx on Linux as a reverse proxy server for Kestrel, see Host ASP.NET Core on Linux with Nginx.
Apache with Kestrel
For information on how to use Apache on Linux as a reverse proxy server for Kestrel, see Host ASP.NET Core on Linux with Apache.
HTTP.sys
If ASP.NET Core apps are run on Windows, HTTP.sys is an alternative to Kestrel. Kestrel is recommended over HTTP.sys unless the app requires features not available in Kestrel. For more information, see HTTP.sys web server implementation in ASP.NET Core.
HTTP.sys can also be used for apps that are only exposed to an internal network.
ASP.NET Core server infrastructure
The IApplicationBuilder available in the Startup.Configure method exposes the ServerFeatures property of type IFeatureCollection. Kestrel and HTTP.sys only expose a single feature each, IServerAddressesFeature, but different server implementations may expose additional functionality.
IServerAddressesFeature can be used to find out which port the server implementation has bound at runtime.
Custom servers
If the built-in servers don’t meet the app’s requirements, a custom server implementation can be created. The Open Web Interface for .NET (OWIN) guide demonstrates how to write a Nowin-based IServer implementation. Only the feature interfaces that the app uses require implementation, though at a minimum IHttpRequestFeature and IHttpResponseFeature must be supported.
Server startup
The server is launched when the Integrated Development Environment (IDE) or editor starts the app:
- Visual Studio: Launch profiles can be used to start the app and server with either IIS Express/ASP.NET Core Module or the console.
- Visual Studio Code: The app and server are started by Omnisharp, which activates the CoreCLR debugger.
- Visual Studio for Mac: The app and server are started by the Mono Soft-Mode Debugger.
When launching the app from a command prompt in the project’s folder, dotnet run launches the app and server (Kestrel and HTTP.sys only). The configuration is specified by the -c|—configuration option, which is set to either Debug (default) or Release .
A launchSettings.json file provides configuration when launching an app with dotnet run or with a debugger built into tooling, such as Visual Studio. If launch profiles are present in a launchSettings.json file, use the —launch-profile
HTTP/2 support
HTTP/2 is supported with ASP.NET Core in the following deployment scenarios:
- Kestrel
- Operating system
- Windows Server 2016/Windows 10 or laterвЂ
- Linux with OpenSSL 1.0.2 or later (for example, Ubuntu 16.04 or later)
- HTTP/2 will be supported on macOS in a future release.
- Target framework: .NET Core 2.2 or later
- Operating system
- HTTP.sys
- Windows Server 2016/Windows 10 or later
- Target framework: Not applicable to HTTP.sys deployments.
- IIS (in-process)
- Windows Server 2016/Windows 10 or later; IIS 10 or later
- Target framework: .NET Core 2.2 or later
- IIS (out-of-process)
- Windows Server 2016/Windows 10 or later; IIS 10 or later
- Public-facing edge server connections use HTTP/2, but the reverse proxy connection to Kestrel uses HTTP/1.1.
- Target framework: Not applicable to IIS out-of-process deployments.
†Kestrel has limited support for HTTP/2 on Windows Server 2012 R2 and Windows 8.1. Support is limited because the list of supported TLS cipher suites available on these operating systems is limited. A certificate generated using an Elliptic Curve Digital Signature Algorithm (ECDSA) may be required to secure TLS connections.
- Kestrel
- Operating system
- Windows Server 2016/Windows 10 or laterвЂ
- Linux with OpenSSL 1.0.2 or later (for example, Ubuntu 16.04 or later)
- HTTP/2 will be supported on macOS in a future release.
- Target framework: .NET Core 2.2 or later
- Operating system
- HTTP.sys
- Windows Server 2016/Windows 10 or later
- Target framework: Not applicable to HTTP.sys deployments.
- IIS (in-process)
- Windows Server 2016/Windows 10 or later; IIS 10 or later
- Target framework: .NET Core 2.2 or later
- IIS (out-of-process)
- Windows Server 2016/Windows 10 or later; IIS 10 or later
- Public-facing edge server connections use HTTP/2, but the reverse proxy connection to Kestrel uses HTTP/1.1.
- Target framework: Not applicable to IIS out-of-process deployments.
†Kestrel has limited support for HTTP/2 on Windows Server 2012 R2 and Windows 8.1. Support is limited because the list of supported TLS cipher suites available on these operating systems is limited. A certificate generated using an Elliptic Curve Digital Signature Algorithm (ECDSA) may be required to secure TLS connections.
- HTTP.sys
- Windows Server 2016/Windows 10 or later
- Target framework: Not applicable to HTTP.sys deployments.
- IIS (out-of-process)
- Windows Server 2016/Windows 10 or later; IIS 10 or later
- Public-facing edge server connections use HTTP/2, but the reverse proxy connection to Kestrel uses HTTP/1.1.
- Target framework: Not applicable to IIS out-of-process deployments.
An HTTP/2 connection must use Application-Layer Protocol Negotiation (ALPN) and TLS 1.2 or later. For more information, see the topics that pertain to your server deployment scenarios.