Служба WCF для многих одновременных клиентов и доступа к базе данных
Я новичок в сервисах WCF и задаюсь вопросом, каким будет лучший способ решить следующее.
У меня есть много клиентов (~ 200 - ~ 500), которые все время делают запросы моего обслуживания довольно постоянно в течение рабочего дня. Большинство запросов включают опрос базовой базы данных для подачи правильного ответа.
В чем я заинтересован, потенциальное количество соединений с базами данных, порожденных из входящих запросов. Если все клиенты выполняют одновременные запросы, сервер базы данных будет сильно ударяться. Я хотел бы избежать глупого количества подключений к базе данных, если это возможно.
Было бы лучше ограничить количество одновременных подключений к службе WCF и, следовательно, непреднамеренно уменьшить возможное количество подключений к базе данных?
Я посмотрел на то, чтобы сделать службу одиночной, которая порождает потоки для транзакции базы данных, поэтому я могу контролировать количество потоков, но это избыточный уровень и ограничивать соединения с сервисом?
Большое спасибо за любой совет.
Ответы
Ответ 1
Как уже упоминал Маркос - WCF имеет встроенную функцию дросселирования, которую вы можете настроить на сервере. Это предотвратит, что ваш сервер базы данных будет заполнен слишком большим количеством запросов одновременно.
По умолчанию:
<serviceThrottling
maxConcurrentCalls="16"
maxConcurrentSessions="10"
maxConcurrentInstances="26" />
Подробнее см. документы MSDN на ServiceThrottlingBehavior.
Это означает, что максимум 16 вызовов обрабатываются одновременно WCF, то есть IF ваш класс службы WCF позволяет сразу несколько вызывающих абонентов!
В отличие от Маркоса, я бы не рекомендовал сделать ваш сервисный класс WCF singleton. Общей практикой является наличие простого класса обслуживания WCF и использование его в режиме вызова. каждый входящий запрос получит свой собственный, полностью отдельный, вновь созданный экземпляр вашего класса услуг WCF - до максимума, определяемого поведением дросселирования службы и контролируемого средой выполнения WCF.
Если вы сделаете свой класс обслуживания WCF одиночным, вам нужно либо установить его ConcurrencyMode в Multiple - но тогда вам нужно проявлять особую осторожность, чтобы не позволить двум одновременным потокам в вашем классе изменять одни и те же значения друг под другом; многопоточное безопасное программирование - главная задача! Или вы не устанавливаете режим concurrency в Multiple, но тогда ваш единственный и единственный экземпляр класса WCF может обрабатывать запросы только последовательным образом, по одному - не очень масштабируемым!
Первой вызов и один экземпляр службы для каждого запроса, безусловно, намного проще. Это с дросселированием сервисов на месте и с пулом соединений ADO.NET создает очень мощную и хорошо себя зарекомендовавшую среду!
Также см. Дэн Ригсби превосходный пост в блоге по регулированию обслуживания WCF для более подробной информации.
Ответ 2
Если вы используете ADO для подключения к своей базе данных, он должен обеспечить механизм объединения пулов, поэтому вам не нужно иметь дело с этим.
Пожалуйста, прочитайте эту статью для получения дополнительной информации: Объединение пулов ADO.NET с первого взгляда
Ответ 3
У нас есть аналогичный сценарий, и мы решаем его, используя только один коннект из нашего WebService в БД и используя MARS из SqlServer, который работает отлично и довольно быстро. Sql Server действительно знает, как обрабатывать параллельные запросы, о которых вы не должны думать.
Вы избегаете того, что накладные расходы на открытие и закрытие соединений (очевидно, что объединение пулов в этом случае помогает)
Помните также добавить в свой веб-сервис что-то вроде:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,
ConcurrencyMode = ConcurrencyMode.Multiple)]
И в config:
<serviceThrottling maxConcurrentCalls="100"
maxConcurrentSessions="100"
maxConcurrentInstances="100" />
Эта опция находится внутри
<behaviors>
<serviceBehaviors>
<behavior name="...">
Надеюсь, что это поможет:)