Производительность WCF с net.tcp - PullRequest
6 голосов
/ 25 марта 2009

У меня есть служба WCF net.tcp, размещенная с помощью встроенного ServiceHost, и при выполнении некоторых стресс-тестов я получаю странное поведение. В первый раз, когда я отправляю кучу запросов, от 5 до 10 запросов отвечают быстро, а остальные возвращаются с интервалом около 2 секунд. Во второй раз, когда я отправляю запросы, 10 - 20 возвращаются быстро и отдыхают с интервалом в 2 секунды.

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

Служба, которую я тестирую, имеет небольшую задержку, поэтому я могу получить много открытых соединений одновременно, если эта задержка будет удалена, запросы будут возвращаться так быстро, что у меня будет, возможно, 2-5 открытых соединений одновременно. Эта задержка предназначена для имитации соединений с БД и других исходящих вещей.

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

У меня мог бы быть таймер в клиенте, который вызывает службу, чтобы она работала, но это кажется плохим решением.

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

Полагаю, мой вопрос в том, ЧТО это - распределение, выделяемое при высокой нагрузке службы WCF, и КАК я могу настроить службу для предварительного распределения большего количества выделенных объектов.

EDIT: Я провел еще какое-то тестирование и, глядя на процесс TaskMgr, вижу, что когда сервисный хост «отдыхает», открыто 10 потоков, но когда я начинаю отправлять запросы, счетчик потоков увеличивается. Пока счетчик потоков высок, сервис-хост может быстро обрабатывать входящие запросы, но если я приостанавливаю отправку запросов, открытый счетчик потоков уменьшается, и последующие запросы начинают обрабатываться дольше.

Теперь, как я могу сказать серверу-хосту держать открытыми несколько потоков? Или больше 10-12, которые он хранит по умолчанию?

Ответы [ 4 ]

6 голосов
/ 26 марта 2009

Что ж, после долгих поисков в гугле кажется, что проблема в пуле потоков. Пул потоков CLR выделяет несколько потоков и, когда они используются, регулирует создание новых потоков и через некоторое время освобождает неиспользуемые потоки.

Существует некоторая путаница с ошибкой, которая означала, что ThreadPool не принял вызов SetMinThreads.

http://www.michaelckennedy.net/blog/PermaLink,guid,708ee9c0-a1fd-46e5-8fa0-b1894ad6ce0f.aspx

Я не уверен, что эта ошибка решена или что, потому что, когда я изменяю настройки ThreadPool, проблема сохраняется.

1 голос
/ 16 мая 2009

Ошибка, на которую вы ссылаетесь, исправлена ​​в .NET 3.5 SP1. Возможно, это как-то связано с проблемой, я думаю, что более вероятно (гораздо более вероятно), что удушение - это ваша проблема, а не нить, как указал Морис.

<system.serviceModel>
  <service name="???" >
   <endpoint ... />
  </service>
</system.serviceModel>

Какое ограничение газа для этого "пустого" конфига? 10 сеансов, 16 одновременных звонков! Осторожно.

Подробнее о потоке: http://www.michaelckennedy.net/blog/2008/08/20/ThreadPoolBugInNET20SP1IsFixed.aspx

1 голос
/ 25 марта 2009

То, что определяет, как запрос может обрабатываться одновременно, - это ServiceThrottlingBehavior. Существует несколько различных пределов, которые ограничивают объем обрабатываемого запроса. Это также зависит от используемой вами привязки, например, wsHttpBinding по умолчанию использует сеансы, в то время как basicHttpBinding не использует сеансы, и ограничение сеансов по умолчанию 10 не является проблемой.

Подробнее см. http://msdn.microsoft.com/en-us/library/ms735114.aspx.

0 голосов
/ 23 июля 2012

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

  public YourService()
    {
        int workerThreads;
        int portThreads;
        ThreadPool.GetMinThreads(out workerThreads, out portThreads);
        ThreadPool.SetMinThreads(200, portThreads);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...