#asp.net #web-services #iis
#asp.net #веб-сервисы #iis
Вопрос:
У меня есть 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-land.
Вот соответствующий раздел 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. У @DanB здесь есть хороший момент — как вы измеряете количество одновременных подключений?
2. @JeremyMcGee Я измеряю количество одновременных подключений, запуская TCPView на сервере, чтобы узнать, сколько внутренних подключений выполняется рабочими процессами IIS.
3. Веб-клиенты работают на независимых машинах или на одной и той же машине? (Проверка того, что регулирование на стороне клиента не выполняется.)
4. @JeremyMcGee Отдельные машины. 1 соединение клиент-сервер на машину. Кроме того, мы знаем, что где-то в сети нет никакого регулирования, потому что, когда мы напрямую обращаемся к серверной части (что также происходит через HTTP), мы не сталкиваемся с узким местом.
5. Роб, ты когда-нибудь находил окончательное решение этой проблемы?
Ответ №1:
Большинство ответов, представленных здесь, касаются количества входящих запросов к вашему серверному веб-сервису, а не количества исходящих запросов, которые вы можете сделать из своего ASP.net приложение к вашей серверной службе.
Здесь не ваш серверный веб-сервис регулирует частоту запросов, а количество открытых подключений, которые ваше вызывающее приложение готово установить к той же конечной точке (тот же URL).
Вы можете удалить это ограничение, добавив следующий раздел конфигурации в свой файл machine.config:
<configuration>
<system.net>
<connectionManagement>
<add address="*" maxconnection="65535"/>
</connectionManagement>
</system.net>
</configuration>
Конечно, вы могли бы выбрать более разумное число, если хотите, например, 50 или 100 одновременных подключений. Но приведенное выше откроет его до максимума. Вы также можете указать конкретный адрес для правила ограничения открытия выше, а не «*», который указывает все адреса.
Документация MSDN для System.Net.connectionManagement
Еще один отличный ресурс для понимания управления подключением в .NET
Надеюсь, это решит вашу проблему!
РЕДАКТИРОВАТЬ: Упс, я вижу, что у вас есть управление соединениями, упомянутое в вашем коде выше. Я оставлю свою приведенную выше информацию, поскольку она актуальна для будущих пользователей с той же проблемой. Однако, пожалуйста, обратите внимание, что в настоящее время на большинстве современных серверов есть 4 разных файла machine.config!
Существует .NET Framework v2, работающий как под 32-разрядной, так и под 64-разрядной версией, а также .NET Framework v4, также работающий как под 32-разрядной, так и под 64-разрядной версией. В зависимости от выбранных вами настроек для вашего пула приложений вы можете использовать любой из этих 4 разных файлов machine.config! Пожалуйста, проверьте все 4 файла machine.config, которые обычно находятся здесь:
- C:WindowsMicrosoft.NETFrameworkv2.0.50727CONFIG
- C:WindowsMicrosoft.NETFramework64v2.0.50727CONFIG
- C:WindowsMicrosoft.NETFrameworkv4.0.30319Config
- C:WindowsMicrosoft.NETFramework64v4.0.30319Config
Комментарии:
1. Да, я рассмотрел эту базу. В любом случае спасибо, @BenSwayne! Я подтвердил, что я изменил правильный
machine.config
(64-разрядный 4.0).2. @RobSobers: В этом случае я бы немного с подозрением относился к коду реализации. Возможно, у вас заканчиваются потоки или что-то в этом роде? Можете ли вы добавить код вызова веб-службы TcpClient в консольное приложение и посмотреть, сможете ли вы повысить скорость запросов? Это докажет, является ли это специфичной для IIS конфигурацией или более широкой конфигурацией .NET или вашим кодом.
3. Идет ли эта строка на клиентском компьютере?
4. спасибо, ваши настройки объединяются с настройкой processModel из codeproject.com/Articles/133738 /… исправлен «ISAPI ‘C:windowsMicrosoft.NetFrameworkv2.0.050727aspnet_isapi.dll ’сообщил о себе как о неработоспособном состоянии по следующей причине: «Обнаружена взаимоблокировка» проблема
5. @BenSwayne применяется ли та же концепция и для SMTP-соединений? Я разрабатываю приложение для массовой отправки электронной почты, так будет ли это свойство connectionManagement также полезно при отправке массовых писем (с использованием многопоточности для функции mail.send )?
Ответ №2:
Я понимаю, что вопрос может быть довольно старым, но вы говорите, что серверная часть работает на том же сервере. Это означает, что на другом порту, возможно, отличном от порта 80 по умолчанию.
Я читал, что при использовании элемента конфигурации «connectionManagement» вам необходимо указать номер порта, если он отличается от значения по умолчанию 80.
ССЫЛКА: настройка maxConnection может не работать, даже если AutoConfig = false в ASP.NET
Во-вторых, если вы решите использовать конфигурацию по умолчанию (address =»*»), дополненную вашим собственным значением, специфичным для бэкэнда, вы можете подумать о том, чтобы сначала указать конкретное значение! В противном случае, если выполняется запрос, сначала совпадает *, и по умолчанию используется 2 соединения. Точно так же, как при использовании раздела в web.config.
ССЫЛКА: элемент <удалить> для управления подключением (настройки сети)
Надеюсь, это кому-то поможет.
Ответ №3:
Возможно ли, что вы используете ссылку на веб-службу на основе WCF? По умолчанию используется ServiceThrottlingBehavior.MaxConcurrentCalls равно 16.
Вы могли бы попробовать обновить элемент поведения ссылки на службу <serviceThrottling>
<serviceThrottling
maxConcurrentCalls="999"
maxConcurrentSessions="999"
maxConcurrentInstances="999" />
(Обратите внимание, что я бы рекомендовал приведенные выше настройки.) Дополнительные сведения о настройке соответствующего элемента см. в MSDN <behavior>
.
Комментарии:
1. Хотелось бы, чтобы мы были, но это не так. Потребляемая служба выполняется в Apache / Python / mod_wsgi на другом компьютере, и, как упоминал Роб, это явно не проблема.
2. Ссылки на службы находятся на клиенте. Как ваш клиент использует службу Apache?
3. Как сказал Джон: регулирование устанавливается на клиенте, использующем веб-сервис. Возможно, фраза «ваше поведение службы» немного вводит в заблуждение. Имеет ли это больше смысла, когда оно формулируется как «поведение вашей ссылки на службу»?
4. @john Оно используется через a
TcpClient
(служба использует пользовательские двоичные двоичные объекты, а не WCF / SOAP или аналогичные). Эти параметры конфигурации, похоже , оказывают на вас чисто влияние, если вы используетеServiceHost
, нетTcpClient
; я что-то упускаю?5. Почему бы не использовать «Добавить ссылку на службу»?
Ответ №4:
Вы пытались программно установить значение статического свойства DefaultConnectionLimit?
Вот хороший источник информации об этой настоящей головной боли … ASP.NET Использование потоков в IIS 7.5, IIS 7.0 и IIS 6.0 с обновлениями для framework 4.0.
Комментарии:
1. Я полагаю, это не должно иметь значения, но я все равно попробую.
2. Вот как мы исправили это несколько лет назад. У нас были проблемы с параллелизмом, и это, казалось, прояснило ситуацию. Net.ServicePointManager. DefaultConnectionLimit = 1000 — это то, что мы использовали. Вы должны установить его ПЕРЕД созданием классов соединений.
Ответ №5:
Смотрите Раздел «Потоки» на этой странице: http://msdn.microsoft.com/en-us/library/ff647786.aspx , в сочетании с разделом «Соединения».
Вы пробовали повысить атрибут maxconnection вашего параметра processModel?
Комментарии:
1. Да, у меня есть. Но в той статье, которую вы процитировали, указывается кое-что интересное, что когда-либо в другой статье по этой теме не упоминалось:
maxconnection
атрибут не применяется к вызовам локальной веб-службы. В данном конкретном случае веб-служба является локальной, но у нас такая же проблема в другой среде, где служба не является локальной.2. @RobSobers — Я думаю, что приведенная выше ссылка достойна второго взгляда. Проверьте часть о
minLocalRequestFreeThreads
— Этот рабочий процесс использует этот параметр для постановки в очередь запросов с локального хоста (где веб-приложение вызывает веб-службу на том же сервере ), если количество доступных потоков в пуле потоков падает ниже этого числа. Этот параметр аналогичен minFreeThreads, но он применяется только к запросам, использующим localhost .3. @Ahmad Да, я тоже установил
minLocalRequestFreeThreads
(см. Мойmachine.config
вопрос.
Ответ №6:
Если оно не определено в веб-службе, приложении или сервере (apache или IIS), на котором размещается расходный материал веб-службы, вы можете создавать бесконечные соединения до сбоя
Ответ №7:
при тестировании производительности я использую RPS, то есть сколько запросов в секунду может обслуживать сервер в пределах допустимой задержки.
теоретически один сервер может одновременно выполнять столько запросов, сколько на нем ядер..
Не похоже, что проблема в ASP.net это потоковая модель, поскольку она потенциально может обслуживать тысячи rps. Похоже, проблема может быть в вашем приложении. Используете ли вы какие-либо примитивы синхронизации?
кроме того, какова задержка в ваших веб-службах, они очень быстро реагируют (в течение микросекунд), если нет, то вы можете рассмотреть асинхронные вызовы, чтобы в конечном итоге не блокировать
Если это чего-то не дает, возможно, вы захотите профилировать свой код с помощью Visual studio или redgate profiler