Проблемы с производительностью при выполнении вызовов веб-служб из приложения ASP.NET
Эта статья поможет устранить проблемы с производительностью, возникающие при выполнении вызовов веб-служб из приложения Microsoft ASP.NET.
Исходная версия продукта: ASP.NET
Исходный номер базы знаний: 821268
Симптомы
При выполнении вызовов веб-служб из приложения ASP.NET может возникнуть состязание, низкая производительность и взаимоблокировка. Клиенты могут сообщать о том, что запросы перестают отвечать на запросы или выполняются долго. Если предполагается взаимоблокировка, рабочий процесс может быть переработан.
При вызове метода может появиться следующее сообщение об ошибке об исключении HttpWebRequest.GetResponse
:
"System.InvalidOperationException: в объекте ThreadPool не было достаточно свободных потоков для завершения операции".
В браузере также может появилось следующее сообщение об ошибке об исключении:
"HttpException (0x80004005): истекло время ожидания запроса".
Примечание.
Эта статья также относится к приложениям, которые выполняют HttpWebRequest
запросы напрямую.
Причина
Эта проблема может возникнуть из-за того, что ASP.NET ограничивает количество рабочих потоков и потоков портов завершения, которые вызов может использовать для выполнения запросов.
Как правило, при вызове веб-службы используется один рабочий поток для выполнения кода, который отправляет запрос, и один поток порта завершения для получения обратного вызова от веб-службы. Однако если запрос перенаправляется или требует проверки подлинности, вызов может использовать до двух рабочих потоков и двух потоков портов завершения. Таким образом, вы можете исчерпать управляемое ThreadPool
значение, если одновременно выполняется несколько вызовов веб-служб.
Например, предположим, что ThreadPool
объект ограничен 10 рабочими потоками и что все 10 рабочих потоков в настоящее время выполняют код, ожидающий выполнения обратного вызова. Обратный вызов никогда не может выполняться, так как все рабочие элементы, помещенные в очередь, ThreadPool
блокируются до тех пор, пока поток не станет доступным.
Другим потенциальным источником состязания является maxconnection
параметр, который System.Net
пространство имен использует для ограничения количества подключений. Как правило, это ограничение работает должным образом. Однако если многие приложения пытаются одновременно выполнить несколько запросов к одному IP-адресу, потокам может потребоваться дождаться доступного подключения.
Разрешение
Чтобы устранить эти проблемы, можно настроить следующие параметры в файлеMachine.config в соответствии с вашей ситуацией:
maxWorkerThreads
minWorkerThreads
maxIoThreads
minFreeThreads
minLocalRequestFreeThreads
maxconnection
executionTimeout
Чтобы успешно устранить эти проблемы, выполните следующие действия:
- Ограничьте количество ASP.NET запросов, которые могут выполняться одновременно, приблизительно до 12 на ЦП.
- Разрешить обратным вызовам веб-службы свободно использовать потоки в
ThreadPool
. - Выберите соответствующее
maxconnections
значение для параметра. Выбор зависит от количества ИСПОЛЬЗУЕМЫх IP-адресов и доменов приложений.
Примечание.
Рекомендация ограничить количество запросов ASP.NET до 12 запросов на ЦП является немного произвольной. Однако это ограничение хорошо работает для большинства приложений.
MaxWorkerThreads и maxIoThreads
ASP.NET использует следующие два параметра конфигурации, чтобы ограничить максимальное количество рабочих потоков и потоков завершения, которые используются:
<processModel maxWorkerThreads="20" maxIoThreads="20">
Параметр maxWorkerThreads
и maxIoThreads
параметр неявно умножаются на количество ЦП. Например, если у вас два процессора, максимальное количество рабочих потоков составляет 2 * maxWorkerThreads
.
MinFreeThreads и minLocalRequestFreeThreads
ASP.NET также содержит следующие параметры конфигурации, определяющие, сколько рабочих потоков и потоков портов завершения должно быть доступно для запуска удаленного или локального запроса:
<httpRuntime minFreeThreads="8" minLocalRequestFreeThreads="8">
Если доступных потоков недостаточно, запрос помещается в очередь до тех пор, пока не будет доступно достаточно потоков для выполнения запроса. Таким образом, ASP.NET одновременно не будет выполнять больше следующего количества запросов:
(maxWorkerThreads
* количество ЦП) - minFreeThreads
Примечание.
Параметр minFreeThreads
и minLocalRequestFreeThreads
параметр неявно умножаются на количество ЦП.
MinWorkerThreads
ASP.NET также содержит следующий параметр конфигурации, определяющий, сколько рабочих потоков может быть немедленно доступно для обслуживания удаленного запроса.
<processModel minWorkerThreads="1">
Потоки, управляемые этим параметром, могут создаваться гораздо быстрее, чем рабочие потоки, созданные на основе возможностей настройки потоков по умолчанию среды CLR.
Этот параметр позволяет ASP.NET к запросам на обслуживание, которые могут внезапно заполнить очередь запросов ASP.NET из-за замедления работы внутреннего сервера, внезапного всплеска запросов от клиентской части или чего-то подобного, что приведет к внезапному увеличению числа запросов в очереди.
Значение по умолчанию minWorkerThreads
для параметра — 1. Рекомендуется задать для minWorkerThreads
параметра следующее значение:
minWorkerThreads
= maxWorkerThreads
/ 2
По умолчанию minWorkerThreads
параметр отсутствует ни в Web.config файле, ни в файлеMachine.config . Этот параметр неявно умножается на количество ЦП.
Maxconnection
Параметр maxconnection
определяет, сколько подключений может быть выполнено к определенному IP-адресу. Параметр отображается следующим образом:
<connectionManagement>
<add address="*" maxconnection="2">
<add address="http://65.53.32.230" maxconnection="12">
</connectionManagement>
Если код приложения ссылается на приложение по имени узла, а не по IP-адресу, параметр должен выглядеть следующим образом:
<connectionManagement>
<add address="*" maxconnection="2">
<add address="http://hostname" maxconnection="12">
</connectionManagement>
Наконец, если приложение размещено на порту, отличном от 80, параметр должен включать нестандартный порт в URL-адрес, как показано ниже:
<connectionManagement>
<add address="*" maxconnection="2">
<add address="http://hostname:8080" maxconnection="12">
</connectionManagement>
Параметры параметров, которые рассматриваются ранее в этой статье, находятся на уровне процесса. Однако maxconnection
параметр применяется к уровню AppDomain. По умолчанию, так как этот параметр применяется к уровню AppDomain, можно создать не более двух подключений к определенному IP-адресу из каждого домена приложения в процессе.
ExecutionTimeout
ASP.NET использует следующий параметр конфигурации для ограничения времени выполнения запроса:
<httpRuntime executionTimeout="90"/>
Это ограничение также можно задать с помощью Server.ScriptTimeout
свойства .
Примечание.
При увеличении значения executionTimeout
параметра также может потребоваться изменить processModel
responseDeadlockInterval
параметр .
Рекомендации
Параметры, рекомендуемые в этом разделе, могут работать не для всех приложений. Однако приведенные ниже дополнительные сведения помогут вам внести соответствующие корректировки.
Если вы выполняете один вызов веб-службы к одному IP-адресу с каждой страницы ASPX, корпорация Майкрософт рекомендует использовать следующие параметры конфигурации:
- Задайте для параметра
maxIoThreads
значениеmaxWorkerThreads
100. - Задайте для параметра значение
maxconnection
12*N (где N — это количество ЦП). - Задайте для параметра значение
minFreeThreads
88*N , аminLocalRequestFreeThreads
для параметра — 76*N. - Задайте значение
minWorkerThreads
50. Помните,minWorkerThreads
что по умолчанию отсутствует в файле конфигурации. Его необходимо добавить.
Некоторые из этих рекомендаций включают простую формулу, которая включает количество ЦП на сервере. Переменная, представляющая количество ЦП в формулах, — N.
Если для этих параметров включена технология Hyper-Threading, необходимо использовать количество логических ЦП вместо числа физических ЦП. Например, если у вас есть сервер с четырьмя процессорами с включенным гиперпотоком, то значение N в формулах будет равным 8 , а не 4.
Примечание.
При использовании этой конфигурации можно одновременно выполнить не более 12 ASP.NET запросов на ЦП, так как 100–88=12. Таким образом, по крайней мере 88*N рабочих потоков и 88*N потоков портов завершения доступны для других применений (например, для обратных вызовов веб-службы).
Например, у вас есть сервер с четырьмя процессорами и поддержкой hyper-threading. На основе этих формул для параметров конфигурации, упомянутых в этой статье, используются следующие значения.
<system.web>
<processModel maxWorkerThreads="100" maxIoThreads="100" minWorkerThreads="50"/>
<httpRuntime minFreeThreads="704" minLocalRequestFreeThreads="608"/>
</system.web>
<system.net>
<connectionManagement>
<add address="[ProvideIPHere]" maxconnection="96"/>
</connectionManagement>
</system.net>
Кроме того, при использовании этой конфигурации для каждого домена приложения доступно 12 подключений для каждого ЦП на IP-адрес. Таким образом, в следующем сценарии очень мало состязаний возникает, когда запросы ожидают подключений ThreadPool
, и не исчерпан:
- На веб-сайте размещается только одно приложение (AppDomain).
- Каждый запрос на страницу ASPX выполняет один запрос веб-службы.
- Все запросы относятся к одному и тому же IP-адресу.
Однако при использовании этой конфигурации в сценариях, в которых задействовано одно из указанных ниже действий, скорее всего, будет использоваться слишком много подключений:
- Запросы относятся к нескольким IP-адресам.
- Запросы перенаправляются (код состояния 302).
- Запросы требуют проверки подлинности.
- Запросы выполняются из нескольких доменов приложения.
В этих сценариях рекомендуется использовать меньшее значение для maxconnection
параметра и более высокие значения для minFreeThreads
параметра и minLocalRequestFreeThreads
параметра.
Дополнительная информация
Дополнительные сведения см. в статье Повышение производительности ASP.NET.
Если вы испытываете низкую производительность и проблемы в IIS вместе с ASP.NET, перейдите в следующие блоги Майкрософт:
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по