Если кто-нибудь разрабатывал высоконагруженное серверное self-hosted WCF приложение, то он мог заметить, что поведение сервиса при множественном доступе основано на каком-то загадочном ограничении. База знаний Майкрософт говорит нам о том, что лимит потоков, которые обслуживают поступающие запросы, рассчитывается так:
Так как на моей машине установлен 4-хядерный процессор, то максимальное количество потоков равно 80, и действительно — на клиенте я создавал по 200-300 потоков, запрашивающих сервер, однако сервер в максимуме создавал 82-83 потока. И как вы понимаете, остальные запрашивающие потоки тупо ставились в очередь.
При этом изменяя параметры указанные в базе знаний Майкрософт:
На более высокие никаких изменений не происходило, и поведение сервера не менялось. Что как минимум странно.
Однако разгадка оказалась простой. Стандартное поведение сервера можно изменить при помощи конфигурации добавлением тега serviceThrottling . Как это сделать описано в MSDN.
Вот мои значения этого тега:
А результате как можно видеть на скриншоте:

Количество потоков на сервере отличается от количества запрашивающих поток на 3-5, и в данном случае составляет 442 на сервере и 445 на клиенте.
Для понимания скриншота коротко опишу что делают сервер и клиент:
Как мы видим на скриншоте, номера потоков в process explorere и консоли клиента совпадают…
количество потоков = 20 * количество ядер процессора
Так как на моей машине установлен 4-хядерный процессор, то максимальное количество потоков равно 80, и действительно — на клиенте я создавал по 200-300 потоков, запрашивающих сервер, однако сервер в максимуме создавал 82-83 потока. И как вы понимаете, остальные запрашивающие потоки тупо ставились в очередь.
При этом изменяя параметры указанные в базе знаний Майкрософт:
<processModel maxWorkerThreads="20" maxIoThreads="20">
На более высокие никаких изменений не происходило, и поведение сервера не менялось. Что как минимум странно.
Однако разгадка оказалась простой. Стандартное поведение сервера можно изменить при помощи конфигурации добавлением тега serviceThrottling . Как это сделать описано в MSDN.
Вот мои значения этого тега:
<serviceThrottling
maxConcurrentCalls="1000"
maxConcurrentSessions="1000"
maxConcurrentInstances="1000"
/>
А результате как можно видеть на скриншоте:

Количество потоков на сервере отличается от количества запрашивающих поток на 3-5, и в данном случае составляет 442 на сервере и 445 на клиенте.
Для понимания скриншота коротко опишу что делают сервер и клиент:
- Сервер принимает запрос, засыпает на 9 секунд ( имитируя к примеру сложный запрос данных из БД ), после чего выдает строку вида "{порядковый номер запроса} ->Hi from thread id = {системный номер потока}".
- Клиент создает 90 000 объектов типа Task и из каждого посылает запрос, после чего выводит ответ сервера в консоль.
Как мы видим на скриншоте, номера потоков в process explorere и консоли клиента совпадают…