Что ограничивает количество одновременных подключений, которые приложение ASP.NET может сделать для веб-службы?

У меня есть приложение ASP.NET 4.0, работающее поверх IIS 7.5 на 64-разрядной машине Windows Server 2008 R2 Enterprise с кусками ОЗУ, ЦП, диска и т.д.

При каждом веб-запросе приложение ASP.NET подключается к веб-службе бэкэнд (через сырые сокеты), которая работает на одном компьютере.

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

Я нашел эту ключевую статью от Microsoft, объясняющую, как настроить настройки IIS для размещения приложений ASP.NET, которые создают множество запросов веб-сервисов: http://support.microsoft.com/?id=821268#tocHeadRef

Я следил за рекомендациями по статье, но до сих пор не повезло. Особенно интересной является настройка maxconnection, которую я даже набрал до 999.

Любые идеи о том, что еще может дросселировать соединения?

Примечание.. Когда я вырезаю IIS из состава и подключаю клиентов напрямую к веб-службе бэкэнда, он с радостью откроет столько подключений, сколько мне нужно, поэтому я уверен, что бэкэнд не является узким местом. Это должно быть что-то в IIS/ASP.NET-стране.

Здесь соответствующий раздел machine.config, который, я уверен, читается приложением (проверено с помощью appcmd.exe):

<system.web>
    <processModel autoConfig="false" maxWorkerThreads="100" maxIoThreads="100" minWorkerThreads="50" />
    <httpRuntime minFreeThreads="176" minLocalRequestFreeThreads="152"/>

    <httpHandlers />

    <membership>
        <providers>
            <add name="AspNetSqlMembershipProvider"
                type="System.Web.Security.SqlMembershipProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
                connectionStringName="LocalSqlServer"
                enablePasswordRetrieval="false"
                enablePasswordReset="true"
                requiresQuestionAndAnswer="true"
                applicationName="/"
                requiresUniqueEmail="false"
                passwordFormat="Hashed"
                maxInvalidPasswordAttempts="5"
                minRequiredPasswordLength="7"
                minRequiredNonalphanumericCharacters="1"
                passwordAttemptWindow="10"
                passwordStrengthRegularExpression="" />
        </providers>
    </membership>

    <profile>
        <providers>
            <add name="AspNetSqlProfileProvider" connectionStringName="LocalSqlServer" applicationName="/"
                type="System.Web.Profile.SqlProfileProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
        </providers>
    </profile>

    <roleManager>
        <providers>
            <add name="AspNetSqlRoleProvider" connectionStringName="LocalSqlServer" applicationName="/"
                type="System.Web.Security.SqlRoleProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
            <add name="AspNetWindowsTokenRoleProvider" applicationName="/"
                type="System.Web.Security.WindowsTokenRoleProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
        </providers>
    </roleManager>
</system.web>
<system.net>
    <connectionManagement>
        <add address="*" maxconnection="999"/>
    </connectionManagement>
</system.net>

Ответ 1

В большинстве представленных здесь ответов указывается количество входящих запросов на ваш бэкэнд-сервер, а не количество исходящих запросов, которые вы можете сделать из вашего приложения ASP.net, в свою внутреннюю службу.

Это не ваш бэкэнд-сервис, который регулирует вашу частоту запросов здесь, это количество открытых соединений, которые ваше вызывающее приложение желает установить на одну и ту же конечную точку (тот же URL-адрес).

Вы можете удалить это ограничение, добавив следующий следующий раздел конфигурации в файл machine.config:

<configuration>
  <system.net>
    <connectionManagement>
      <add address="*" maxconnection="65535"/>
    </connectionManagement>
  </system.net>
</configuration>

Разумеется, вы можете выбрать более разумный номер, если хотите, например, 50 или 100 одновременных подключений. Но вышесказанное откроет его вплоть до макс. Вы также можете указать конкретный адрес для открытого правила ограничения выше, чем "*", который указывает все адреса.

Документация MSDN для System.Net.connectionManagement

Еще один отличный ресурс для понимания ConnectManagement в .NET

Надеюсь, что это решает вашу проблему!

РЕДАКТИРОВАТЬ:. Увы, я вижу, что в вашем коде указано управление соединением. Я оставлю свою информацию выше, поскольку она актуальна для будущих исследователей с той же проблемой. Однако, пожалуйста, обратите внимание, что в настоящее время существует 4 разных файла machine.config на большинстве современных серверов!

Существует .NET Framework v2, работающий под 32-разрядной и 64-разрядной версиями, а также .NET Framework v4, работающий как в 32-битной, так и в 64-разрядной версиях. В зависимости от выбранных вами настроек для пула приложений вы можете использовать любой из этих 4 разных файлов machine.config! Пожалуйста, проверьте все 4 файла machine.config, которые обычно находятся здесь:

  • C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG
  • C:\Windows\Microsoft.NET\Framework64\v2.0.50727\CONFIG
  • C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config
  • C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config

Ответ 2

Возможно ли, что вы используете ссылку на веб-службу на основе WCF? По умолчанию ServiceThrottlingBehavior.MaxConcurrentCalls - 16.

Вы можете попробовать обновить поведение ссылки на службу <serviceThrottling>

<serviceThrottling
    maxConcurrentCalls="999" 
    maxConcurrentSessions="999" 
    maxConcurrentInstances="999" />

(Обратите внимание, что я рекомендую настройки выше.) Подробнее см. MSDN, как настроить соответствующий элемент <behavior>.

Ответ 3

Я понимаю, что вопрос может быть довольно старым, но вы говорите, что сервер работает на одном сервере. Это означает, что на другом порту, возможно, кроме порта 80 по умолчанию.

Я читал, что когда вы используете элемент конфигурации "connectionManagement", вам нужно указать номер порта, если он отличается от 80 по умолчанию.

LINK: Значение maxConnection может не работать даже autoConfig = false в ASP.NET

Во-вторых, если вы решите использовать конфигурацию по умолчанию (address = "*" ), расширенную с вашим собственным конкретным значением для бэкэнд, вы можете сначала рассмотреть значение! В противном случае, если запрос сделан, сначала выполняется *, а по умолчанию - 2 соединения. Также как при использовании раздела в web.config.

LINK: <remove> Элемент для подключения управления (настройки сети)

Надеюсь, что это поможет кому-то.

Ответ 5

Смотрите раздел "Threading" на этой странице: http://msdn.microsoft.com/en-us/library/ff647786.aspx в сочетании с разделом "Подключения".

Пробовали ли вы использовать атрибут maxconnection для параметра processModel?

Ответ 6

Если он не определен в веб-службе или приложении или сервере (apache или IIS), на котором размещается веб-сервисный ресурс, вы можете создавать бесконечные соединения до отказа

Ответ 7

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

теоретически один сервер может запускать столько запросов одновременно, сколько количества ядер на нем.

Не похоже, что проблема - это потоковая модель ASP.net, поскольку она может потенциально обслуживать тысячи rps. Похоже, проблема может быть вашей заявкой. Используете ли вы какие-либо примитивы синхронизации?

также какова латентность ваших веб-сервисов, они очень быстро реагируют (в течение микросекунд), если нет, то вы можете рассмотреть асинхронные вызовы, поэтому вы не блокируете

Если это ничего не делает, то вам может понадобиться профилировать свой код с помощью visual studio или redgate profiler