Является ли Kestrel одним streamом для обработки запросов, таких как Node.js?

Как Kestrel, так и Node.js основаны на libuv .

В то время как Node.js точно заявляет, что использует цикл событий , я не могу найти, если это так для Kestrel, или если он использует очередь пула streamов / очередь запросов, такую ​​как IIS?

Кестрел за веб-сервером

Кестрел за веб-сервером

Цикл событий Node.js

┌───────────────────────┐ ┌─>│ timers │ │ └──────────┬────────────┘ │ ┌──────────┴────────────┐ │ │ I/O callbacks │ │ └──────────┬────────────┘ │ ┌──────────┴────────────┐ │ │ idle, prepare │ │ └──────────┬────────────┘ ┌───────────────┐ │ ┌──────────┴────────────┐ │ incoming: │ │ │ poll │<─────┤ connections, │ │ └──────────┬────────────┘ │ data, etc. │ │ ┌──────────┴────────────┐ └───────────────┘ │ │ check │ │ └──────────┬────────────┘ │ ┌──────────┴────────────┐ └──┤ close callbacks │ └───────────────────────┘ 

Обновлено для ASP.Net Core 2.0 . Как указано, poke, сервер был разделен между хостингом и транспортом, где libuv относится к транспортному уровню. Libuv ThreadCount был перемещен в свои собственные LibubTransportOptions и они устанавливаются отдельно в вашем веб- UseLibuv() с помощью UseLibuv() ext:

  • Если вы проверите class LibuvTransportOptions в github, вы увидите вариант ThreadCount :

     ///  /// The number of libuv I/O threads used to process requests. ///  ///  /// Defaults to half of  rounded down and clamped between 1 and 16. ///  public int ThreadCount { get; set; } = ProcessorThreadCount; 
  • UseLibuv можно задать в вызове UseLibuv в вашем веб- UseLibuv . Например:

     public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseLibuv(opts => opts.ThreadCount = 4) .UseStartup() .Build(); 

Хотя в ASP.NET Core 1.X, Libuv config был частью сервера kestrel:

  • Если вы проверите class KestrelServerOptions в своем KestrelServerOptions github, вы увидите, что ThreadCount опция ThreadCount :

     ///  /// The number of libuv I/O threads used to process requests. ///  ///  /// Defaults to half of  rounded down and clamped between 1 and 16. ///  public int ThreadCount { get; set; } = ProcessorThreadCount; 
  • Этот параметр можно задать в вызове UseKestrel , например, в новом приложении ASP.Net Core:

     public static void Main(string[] args) { var host = new WebHostBuilder() .UseKestrel(opts => opts.ThreadCount = 4) .UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration() .UseStartup() .Build(); host.Run(); } 

Копаем исходный код:

  • Вы можете видеть streamи прослушивания libuv (или KestrelThreads ), созданные в KestrelEngine
  • Некоторые места будут вызывать методы ThreadPool чтобы они могли запускать код в пуле streamов CLR вместо streamов libuv. (Использование ThreadPool.QueueUserWorkItem ). Кажется, что пул по умолчанию имеет максимум 32K streamов, которые могут быть изменены через config .
  • Frame делегирует фактическое приложение (например, Frame приложение ASP.Net) для обработки запроса.

Таким образом, мы можем сказать, что он использует несколько libuv eventloops для ввода-вывода. Фактическая работа выполняется по управляемому коду со стандартными рабочими streamами, используя пул streamов CLR.

Мне бы хотелось найти более авторитетную документацию об этом ( официальные документы не дают подробностей). Самый лучший, который я нашел, – Дамиан Эдвардс, говорящий о Кестреле на канале 9 . Около минуты 12 он объясняет:

  • libuv использует однопоточную модель цикла событий
  • Kestrel поддерживает несколько циклов событий
  • Kestrel делает только IO работу над циклами libuv
  • Вся работа без ввода-вывода (включая все, что связано с HTTP, например, parsing, кадрирование и т. Д.) Выполняется в управляемом коде на стандартных рабочих streamах .net.

Кроме того, быстрый поиск вернулся:

  • Дэвид Фаулер рассказывает о пуле в пусте в Кестрел. Он также подтверждает, что запрос мог бы по-прежнему переходить между streamами в ASP.Net Core. (как это было в предыдущих версиях)
  • Этот блогпост, глядя на пустельгу, когда он вышел
  • Этот вопрос о том, как управлять streamами в ASP.Net Core.

Резьба является специфичной для транспорта. При использовании транспорта libuv (по умолчанию в версии 2.0), как указано в ответе Daniel JG , существует ряд циклов событий, основанных на количестве логических процессоров на машине, и это можно переопределить, установив значение в параметрах. По умолчанию каждое соединение привязано к определенному streamу, и все операции ввода-вывода выполняются в этом streamе. Пользовательский код выполняется в streamах пула streamов, потому что мы не верим, что пользователи не будут блокировать streamи ввода-вывода. Когда вы делаете вызовы IO в этих streamах пула streamов (например, HttpResponse.WriteAsync ), kestrel выполняет работу по маршалированию этого обратно к соответствующему streamу ввода-вывода, к которому привязан сокет. Типичный stream запросов выглядит следующим образом:

[чтение из сети] отправка в пул streamов -> [http parsing], [выполнить конвейер промежуточного программного обеспечения] вызов для записи -> enqueue user work to IO thread [write to network]

Конечно, вы всегда можете сказать, что пустелька вы профессионал и никогда не блокируете stream ввода-вывода и не запускаете свой код на нем. Но я бы не стал, если бы не знал, что я делаю (а я нет: D).

Interesting Posts

Скорость вставки SQLite замедляется по мере увеличения количества записей из-за индекса

Как фильтровать NSFetchedResultsController (CoreData) с помощью UISearchDisplayController / UISearchBar

Что произойдет, если я активирую свою виртуальную машину Windows XP?

Android eclipse DDMS – не удается получить доступ к данным / данным / на телефоне, чтобы вытащить файлы

Как ограничить загрузку трафика в Firefox

Запросить мой рабочий лист Excel с помощью VBA

Разница между использованием указателей символов и массивов символов

Создание Android-сервиса с помощью Phonegap? (У вас есть приложение для телефонного звонка, даже если оно закрыто)

Как заставить YY_INPUT указывать на строку, а не на stdin в Lex & Yacc (Solaris)

Обновление сайта с git (over ssh)

Каков наилучший выбор для межпроцессного взаимодействия .NET?

Как добавить границу в мой клип-путь: polygon (); Стиль CSS

Как сделать каталог пользователей другим разделом в Snow Leopard?

Начальная C ++ неинициализированная локальная переменная

Удалить раздел и расширить параметр раздела отключен

Давайте будем гением компьютера.