Меня интересует модель запроса/ответа в однопоточном приложении .NET, размещенном в IIS. Например, если это приложение WebAPI, которое является однопоточным для чтения большого файла, обработки его (выполнение некоторых строковых манипуляций с содержимым) и возврата обработанного содержимого в ответе API, и ради аргумента предположим, что оно принимает 10 минут на обработку файла.
Теперь я прочитал, что сопоставление IIS ASP.NET здесь многопоточное:
Так что же произойдет, если я сделаю 20 запросов к одному и тому же API в течение минуты?
Если для обработки вашего запроса требуется больше нескольких секунд, нет смысла выполнять эту работу непосредственно в веб-приложении. Вместо этого переместите его в фоновый процесс. Клиенты могут инициировать работу, нажав на ваш API, затем они могут опросить результат (или использовать веб-перехватчики или другие методы, чтобы уведомить их).





По умолчанию IIS обрабатывает запросы одновременно. Если вы ничего не делаете активно, чтобы предотвратить это, вы начнете обрабатывать один и тот же файл в 2 потоках одновременно, если 2 запроса поступят одновременно.
Вы можете использовать один из примитивов синхронизации, например lock(...) или мьютекс, если одновременная обработка нежелательна. Однако; если обработка занимает 10 минут, вы уверены, что хотите сделать это как часть веб-запроса? Могут быть лучшие альтернативы.
Без некоторых настроек IIS будет обрабатывать запросы одновременно, как и любой другой сервер.
Если размер очереди запросов, время ожидания запроса и размер пула потоков будут установлены на соответствующие значения, запрос № 2 будет обработан после того, как он проведет 10 минут в очереди запросов IIS.
Никакой настойчивости. Только ОЗУ.
Это довольно необычный сценарий - ждать завершения таких длинных запросов, а затем возвращать ответ через некоторое время. С точки зрения проектирования системы имеет смысл поставить этот расчет в очередь в диспетчере фоновых заданий или кэшировать результаты, когда это возможно, возвращая данные немедленно, а не ожидая много минут.
Немного другой вариант, который приходит мне в голову, выглядит следующим образом:
10 минут на обработку задания — это гипотетический сценарий для преувеличения времени и использования его в качестве платформы для обсуждения того, как будут обслуживаться различные потоки. В более широком плане я определенно согласен с вами в том, что его следует обслуживать в очереди сообщений, иначе фоновый процесс займет так много времени для его обработки.
Здесь — хорошая статья, в которой описаны все слои, которые HTTP-запрос прошел до того, как он попал в ваш код :) Каждый слой имеет свою конфигурацию и ограничения.
Обратите внимание, что пул потоков .net растет довольно медленно, он добавляет 2 потока в секунду. Если у вас будет код синхронной блокировки в ваших контроллерах (используйте блокировку или мьютекс) и отправьте 100 запросов на сервер, ваш код обработает последний запрос только через 45 секунд: 10 запросов будут обработаны немедленно (учитывая размер пула потоков по умолчанию) , то пул потоков будет расти (медленно) и будет обрабатывать все оставшиеся 90 запросов за 45 секунд (добавляя 2 потока в пул).
Каково общее ограничение на количество потоков, которые может запускать IIS? Или есть?
Дайте определение ИИС? Ваше приложение ограничено памятью и количеством дескрипторов для запуска потоков. Для пула потоков вы можете использовать ThreadPool.GetMaxThreads(), чтобы определить емкость вашего веб-сайта. W3WP имеет собственный конфигурация, конфигурация HTTP.sys — здесь.
По умолчанию все, что запускается в IIS, является многопоточным.