Ответ 1
Обновлено для ASP.Net Core 2.0. Как указал poke, сервер был разделен между хостингом и транспортом, где libuv принадлежит транспортному уровню. Libuv ThreadCount
был перемещен в свои собственные LibuvTransportOptions
и они устанавливаются отдельно в конструкторе веб-хостов с помощью UseLibuv()
ext:
-
Если вы проверите класс
LibuvTransportOptions
в github, вы увидите опциюThreadCount
:/// <summary> /// The number of libuv I/O threads used to process requests. /// </summary> /// <remarks> /// Defaults to half of <see cref="Environment.ProcessorCount" /> rounded down and clamped between 1 and 16. /// </remarks> public int ThreadCount { get; set; } = ProcessorThreadCount;
-
Опция может быть установлена в вызове
UseLibuv
вашего веб-хостера. Например:public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseLibuv(opts => opts.ThreadCount = 4) .UseStartup<Startup>() .Build();
В ASP.NET Core 1.X конфиг Libuv был частью сервера kestrel:
-
Если вы проверите класс
KestrelServerOptions
в егоKestrelServerOptions
github, вы увидите, что есть опцияThreadCount
:/// <summary> /// The number of libuv I/O threads used to process requests. /// </summary> /// <remarks> /// Defaults to half of <see cref="Environment.ProcessorCount" /> rounded down and clamped between 1 and 16. /// </remarks> 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<Startup>() .Build(); host.Run(); }
Копаем исходный код:
- Вы можете видеть потоки слушателя libuv (или
KestrelThreads
), создаваемые вKestrelEngine
- В некоторых местах будут вызываться методы
ThreadPool
чтобы они могли запускать код в пуле потоков CLR вместо потоков libuv. (ИспользуяThreadPool.QueueUserWorkItem
). Кажется, что пул по умолчанию имеет максимум 32K потоков, которые можно изменить через config. -
Frame<TContext>
делегирует фактическое приложение (например,Frame<TContext>
приложение ASP.Net) для обработки запроса.
Таким образом, мы могли бы сказать, что он использует несколько циклов libuv для IO. Фактическая работа выполняется над управляемым кодом со стандартными рабочими потоками с использованием пула потоков CLR.
Я хотел бы найти более авторитетную документацию об этом (официальные документы не дают подробностей). Лучшее, что я нашел, - это то, что Дамиан Эдвардс говорит о Кестреле на 9 канале. Около 12 минут он объясняет:
- libuv использует модель однопоточного цикла обработки событий
- Kestrel поддерживает несколько циклов событий
- Kestrel выполняет только операции ввода-вывода в циклах libuv
- Вся работа, не связанная с вводом-выводом (включая все, что связано с HTTP, например анализ, кадрирование и т.д.) Выполняется в управляемом коде в стандартных рабочих потоках .net.
Кроме того, быстрый поиск вернулся:
- Дэвид Фаулер говорит о пуле потоков в Kestrel здесь. Это также подтверждает, что запрос может все еще перемещаться между потоками в ASP.Net Core. (как это было в предыдущих версиях)
- Этот блог пост, глядя на Kestrel, когда он вышел
- Этот вопрос о том, как потоки управляются в ASP.Net Core.