Одновременные запросы WCF накапливаются на сервере при использовании WSHttpBinding

StackOverflow https://stackoverflow.com/questions/832871

Вопрос

У меня есть клиент/серверное приложение WCF, которое обменивается данными через HTTP с помощью WSHttpBinding.

Настройка сервера:самостоятельный хостинг с использованием стандарта WCF ServiceHost.Мой фактический класс обслуживания определяется как:

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, 
 InstanceContextMode = InstanceContextMode.PerSession, 
 UseSynchronizationContext = false)]

Настройка клиента:используя клиентский прокси, созданный визуальной студией, используя синхронный сервисные звонки(proxy.call_server_method блокируется до тех пор, пока сервер не ответит полностью.)

Сценарий:У меня есть один конкретный вызов метода, выполнение которого на сервере занимает 20 секунд.Клиент вызывает этот метод в отдельном потоке, поэтому он не задерживается, и ConcurrencyMode.Multiple означает, что WCF также должен выполнить его в отдельном потоке на сервере.

Эта теория подтверждается тем фактом, что когда я настраиваю свое приложение на использование NetTcpBinding, все работает нормально.

Проблема:
Если я настрою приложение для использования WSHttpBinding, то этот длинный вызов метода приводит к «резервному копированию» http-запросов.Я проверил это поведение как путем проверки своих журналов, так и путем отладки HTTP-запросов с помощью Fiddler.

Пример:

  • Клиент инициирует 20-секундный запрос в фоновом потоке
  • Клиент инициирует запросы B и C в приоритетном потоке
  • Запросы B и C отправляются на сервер, который не обрабатывает их, пока не будет выполнен 20-секундный запрос.

Но иногда:

  • Запросы B и C не получить отправку (они даже не появляются в скрипаче) до тех пор, пока не вернется 20-секундный запрос (это бывает редко).
    • Примечание:параметр <add address="*" maxconnection="100"/> в клиентском app.config это (по-видимому) прекратилось.
  • Запрос B отправляется и получает ответ немедленно, а запрос C задерживается до завершения 20-секундного запроса (это бывает редко).

Вот временная шкала скрипача, демонстрирующая проблему:(нажмите, чтобы увеличить версию)

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

Так, Вопросы:

  • Какого черта здесь происходит?Почему это работает нормально, используя NetTcpBinding и не работать с использованием WSHttpBinding?
  • Почему такое непоследовательное поведение?
  • Что я могу сделать, чтобы это исправить?

Примечания:

  • Сервер не блокируется.Я установил точки останова и использовал !syncblk и он постоянно сообщает, что блокировки не удерживаются.
  • Это не моя нить (в противном случае NetTcpBinding не должен работать)
  • У меня есть <serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="1000" maxConcurrentSessions="1000" /> установить в app.config сервера
  • 20-секундный вызов просто ожидает таймера, он не нагружает процессор, диск или сеть.
  • Я бы предпочел решение, которое не требовало бы перепроектирования приложения для использования асинхронных вызовов...это большая куча устаревшего кода, и я действительно не хочу возиться с вещами, которых не понимаю.
Это было полезно?

Решение 3

[Ответ для себя, чтобы показать другим пользователям, каким было наше окончательное решение]

В конце концов мне так и не удалось это решить.
Нашим окончательным решением было отключить наше приложение от WSHttpBinding и на NetTcpBinding в производстве — мы все равно планировали сделать это в конечном итоге из соображений производительности.

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

Другие советы

За пределами WCF существует некоторый дроссель (что-то в .Net или Windows), который по умолчанию разрешает не более двух одновременных исходящих HTTP-соединений.К сожалению, я не могу вспомнить на всю жизнь название этой вещи (и то, что вы поместили бы в app.config или свое приложение, чтобы переопределить это).Учитывая, что вы не видите, что запросы покидают клиент, и что это только HTTP, я думаю, вы нажимаете «эту штуку».Я буду продолжать искать его название.

Обновлять:Нашел — попробуйте это на клиенте (но измените цифру «2» на большее число):

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

Мы наблюдали точно такие же симптомы со службой JSON, размещенной в IIS/ASP.NET.

Основная причина заключалась в том, что запросы синхронизировались ASP.NET, а не WCF.Нам пришлось отключить состояние сеанса (на уровне приложения), чтобы получить одновременные методы WCF.

Веб.конфигурация:<system.web> <sessionState mode="Off" /> </system.web>

Обратите внимание, что наш сервис использует webHttpBinding, а не wsHttpBinding.Так что я не уверен, что это решит и проблему Ориона.

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

http://support.microsoft.com/kb/183110

http://support.microsoft.com/kb/282402

Я предполагаю, что WSHttpBinding использует настройки WinINET при выдаче запросов.

Если вы перейдете на BasicHttpBinding, это сработает?

Так ли это звучит это твоя проблема, Регулирование сеанса, что-то, что укусило меня за задницу.

Рассмотрите возможность использования ConcurrencyMode.Multiple на услуги по вызову, чтобы разрешить одновременное звонки.

Я забыл - может это был заказ?Я думаю, возможно, RM через http сохраняет порядок, а может быть, сеансы Tcp - нет (если вы явно не запросите этого)?Есть ли в контракте на обслуживание атрибут, описывающий упорядоченные/неупорядоченные сеансы (я забыл).

Не уверен, но иногда проблемы с одновременными вызовами из приложения Silverlight связаны с управлением соединениями браузера.Для меня решением было поместить это в наш метод App.xaml.cs, Application_Startup, как описано здесь: http://weblogs.asp.net/olakarlsson/simulentially-calling-multiple-methods-on-a-wcf-service-from-silverlight

WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top