Проблемы с производительностью при выполнении вызовов веб-служб из приложения 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 параметра также может потребоваться изменить processModelresponseDeadlockInterval параметр .

Рекомендации

Параметры, рекомендуемые в этом разделе, могут работать не для всех приложений. Однако приведенные ниже дополнительные сведения помогут вам внести соответствующие корректировки.

Если вы выполняете один вызов веб-службы к одному IP-адресу с каждой страницы ASPX, корпорация Майкрософт рекомендует использовать следующие параметры конфигурации:

  • Задайте для параметра maxIoThreads значение maxWorkerThreads100.
  • Задайте для параметра значение maxconnection12*N (где N — это количество ЦП).
  • Задайте для параметра значение minFreeThreads88*N , а minLocalRequestFreeThreads для параметра — 76*N.
  • Задайте значение minWorkerThreads50. Помните, 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, перейдите в следующие блоги Майкрософт: