WCF: UserNamePasswordValidator concurrency
От: Аноним  
Дата: 21.04.11 11:13
Оценка:
Возникла следующая проблема с сабжем: вызовы Validate выполняются последовательно независимо от параллельных вызовов со стороны многих клиентов. Т.е. подключилось скажем 1000 клиентов и каждый последовательно проходит валидацию. Это ооочень сильно бьет по производительности в случае параллельных вызовов методов службы от многих клиентов.

Это такой баг или чем-то обусловлено? Как победить? Как вообще можно хостить службу ожидающую высокой нагрузки?

з.ы. Более полно проблема описана здесь.
Re: WCF: UserNamePasswordValidator concurrency
От: perekrestov Украина  
Дата: 21.04.11 11:31
Оценка:
Здравствуйте, Аноним, Вы писали:

Попробуйте

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]


но тогда вам прийдется добавить логику синхронизации в классе сервиса.
Re[2]: WCF: UserNamePasswordValidator concurrency
От: Аноним  
Дата: 21.04.11 11:36
Оценка:
Здравствуйте, perekrestov, Вы писали:

P>
P>[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
P>


У службы настроен ConcurrencyMode.
Я в p.s. исходного сообщения указал ссылку, где подробно описаны мытарства, там было проделано вообще все, что только можно. Стивен Чен из MSFT сначала откликнулся на вопрос, а потом позорно слился.
Re[2]: WCF: UserNamePasswordValidator concurrency
От: perekrestov Украина  
Дата: 21.04.11 12:32
Оценка:
Здравствуйте, perekrestov, Вы писали:

P>но тогда вам прийдется добавить логику синхронизации в классе сервиса.


А что если поставить InstanceContextMode в Single...
Конечно, для уменьшения кол-ва проверок креденшиалзов можно использовать сессию, но там уже, определенно, не basicHttpBinding
Это существенно позволит вам снизить кол-во обращений вашего кастомного валидатора в базу

[ServiceContract(SessionMode = SessionMode.Required)] //Required будет давать вам "отлуп" в виде экзепшена, если будете использовать несоотв. биндинг (например, basicHttpBinding)
public interface IMyContract
{
}

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession, /*опционально, если вам нужно*/ ConcurrencyMode=ConcurrencyMode.Multiple)]
public class MyContract:IMyContract
{
}

ну и сконфигурить биндинг...


или
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single, ConcurrencyMode=ConcurrencyMode.Multiple)]
Re[3]: WCF: UserNamePasswordValidator concurrency
От: perekrestov Украина  
Дата: 21.04.11 12:35
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, perekrestov, Вы писали:


Да, и код валидатора в студию. Авось, вы там локами балуетесь
Re[4]: WCF: UserNamePasswordValidator concurrency
От: Аноним  
Дата: 21.04.11 12:57
Оценка:
Здравствуйте, perekrestov, Вы писали:

P>Да, и код валидатора в студию. Авось, вы там локами балуетесь


код валидатора

Thread.Sleep(1000);


никаких локов нигде вообще не в теле службы ни в коде валидатора. более того как только выключаю валидатор вызовы сразу становятся параллельными
Re[3]: WCF: UserNamePasswordValidator concurrency
От: Аноним  
Дата: 21.04.11 13:02
Оценка:
Здравствуйте, perekrestov, Вы писали:

P>А что если поставить InstanceContextMode в Single...

P>Конечно, для уменьшения кол-ва проверок креденшиалзов можно использовать сессию, но там уже, определенно, не basicHttpBinding
P>Это существенно позволит вам снизить кол-во обращений вашего кастомного валидатора в базу

это тоже было проделано — см. ссылку.

P>
P>[ServiceContract(SessionMode = SessionMode.Required)] //Required будет давать вам "отлуп" в виде экзепшена, если будете использовать несоотв. биндинг (например, basicHttpBinding)
P>public interface IMyContract
P>{
P>}

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


P>[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession, /*опционально, если вам нужно*/ ConcurrencyMode=ConcurrencyMode.Multiple)]
P>public class MyContract:IMyContract
P>{
P>}
P>

P>ну и сконфигурить биндинг...


P>или

P>
P>[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single, ConcurrencyMode=ConcurrencyMode.Multiple)]
P>


ну можно вообще обойтись без сессии в таком случае — использовать WSBinding — он устанавливает логическую сессию и производит аутентификацию единожды. но проблемы это не решает когда пользователи работают по схеме: подключился, вызвал метод-два, отключился.
Re: WCF: UserNamePasswordValidator concurrency
От: Аноним  
Дата: 21.04.11 13:23
Оценка:
Здравствуйте, Аноним, Вы писали:

честно говоря я не ожидал подобного — это просто хэдшот любому highload серверу на wcf. неужели никто не разрабатывает ничего серьезного (высоконагруженного) на wcf раз не наткнулся на такой нехилый bottlneck'и?
Re[5]: WCF: UserNamePasswordValidator concurrency
От: perekrestov Украина  
Дата: 21.04.11 13:42
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, perekrestov, Вы писали:


P>>Да, и код валидатора в студию. Авось, вы там локами балуетесь


А>код валидатора


А>
А>Thread.Sleep(1000);
А>


А>никаких локов нигде вообще не в теле службы ни в коде валидатора. более того как только выключаю валидатор вызовы сразу становятся параллельными

Log4Net appender, который вы используете не тормозит, параллельно "лоча" потоки?

Да, и стрейсить сервис не мешало бы. Было бы понятно, что там происходит.
+ Антонелло интересно высказался по поводу физических параметров сервера (кол-во ядер и т.п.).
Re[2]: WCF: UserNamePasswordValidator concurrency
От: perekrestov Украина  
Дата: 21.04.11 13:45
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Аноним, Вы писали:


А>честно говоря я не ожидал подобного — это просто хэдшот любому highload серверу на wcf. неужели никто не разрабатывает ничего серьезного (высоконагруженного) на wcf раз не наткнулся на такой нехилый bottlneck'и?


Балансировка с WCF работает, но там есть серьезные ограничения на биндинги и бихейворы
Re[6]: WCF: UserNamePasswordValidator concurrency
От: Аноним  
Дата: 21.04.11 13:53
Оценка:
Здравствуйте, perekrestov, Вы писали:

P>Да, и стрейсить сервис не мешало бы. Было бы понятно, что там происходит.

делаю простой тест, создаю 30 каналов с разными credentials (итого разные фабрики каналов) и вызываю асинхронно метод. метод — пустой. настройки оптимальные (Concurrency) и т.д. Получаю следующую картину ответов: отправлено 30 запросов и через
30(!) секунд начинают приходить ответы с интервалом паузы в указанной Validate!

P>+ Антонелло интересно высказался по поводу физических параметров сервера (кол-во ядер и т.п.).

Антоннело высказал извиняюсь полный бред тупо набивая посты. Ему разжевали, что вызовы Validate выполняются последовательно в то время как методы службы параллельно, но считает уместным сумничать на тему занятых ядер...
Re[3]: WCF: UserNamePasswordValidator concurrency
От: Аноним  
Дата: 21.04.11 13:59
Оценка:
Здравствуйте, perekrestov, Вы писали:

P>Балансировка с WCF работает, но там есть серьезные ограничения на биндинги и бихейворы

балансировка ? throttling? да, работает, но распространяется только методы служб. а на PasswordValidator's сие как оказалось не рапространяется. итого полезность wcf я для себя на сегодня вижу только в решении следующем: подключилось дофига клиентов, прошли по очереди(!) аутентификацию и наконец-то заработали параллельно ну это очевидный баг, почему мелкософт так позорно слился в той теме мало того, что не пофиксив, так еще и не отписавшись. сразу скажу: автор той темы — не я, я наткнулся на сей баг вчера. гугля нашел только одну такую тему с подобной проблемой.
Re[7]: WCF: UserNamePasswordValidator concurrency
От: perekrestov Украина  
Дата: 21.04.11 14:01
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, perekrestov, Вы писали:


P>>Да, и стрейсить сервис не мешало бы. Было бы понятно, что там происходит.

А>делаю простой тест, создаю 30 каналов с разными credentials (итого разные фабрики каналов) и вызываю асинхронно метод. метод — пустой. настройки оптимальные (Concurrency) и т.д. Получаю следующую картину ответов: отправлено 30 запросов и через
А>30(!) секунд начинают приходить ответы с интервалом паузы в указанной Validate!

P>>+ Антонелло интересно высказался по поводу физических параметров сервера (кол-во ядер и т.п.).

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

Хм, да точно. Невнимательно прочитал. Сорри.
Остается только повторить тоже самое у себя на машине. А, все-таки, трейс не помешал бы.

Вероятно очередь запросов строится одним потоком и там же происходит аутентификация.
А WCF рантайм, в зависомости от настроек сервиса (InstanceContextMode, SessionMode, Concurency, Binding и прочего) выгребает реквесты с этой очереди.
Но это только догадки, нужно в литературу посмотреть, и, конечно, рефлектором.
Re[8]: WCF: UserNamePasswordValidator concurrency
От: Аноним  
Дата: 21.04.11 14:38
Оценка:
Здравствуйте, perekrestov, Вы писали:

Вобщем перебирая варианты обнаружил, что таки Validate выполняется параллельно — порциями по ~10. Откуда эта цифра и как на нее влиять пока не понял.
Re[9]: WCF: UserNamePasswordValidator concurrency
От: rumatavz  
Дата: 22.04.11 10:09
Оценка:
А>Вобщем перебирая варианты обнаружил, что таки Validate выполняется параллельно — порциями по ~10. Откуда эта цифра и как на нее влиять пока не понял.

А куда Вам больше?
Увеличение одновременно выполняемых потоков только увеличит накладные расходы на переключение контекстов, а быстрее выполнятся всё равно не будет, т.к. число физических процессоров ограничено.
Re[10]: WCF: UserNamePasswordValidator concurrency
От: Аноним  
Дата: 22.04.11 12:08
Оценка:
Здравствуйте, rumatavz, Вы писали:

R>А куда Вам больше?

есть куда. во время выполнения запросов к БД проц фактически простаивает большую часть времени. создание параллельных запросов увеличивает пропускную сопсобность в разы.

R>Увеличение одновременно выполняемых потоков только увеличит накладные расходы на переключение контекстов, а быстрее выполнятся всё равно не будет, т.к. число физических процессоров ограничено.

не в кассу

з.ы. провел несколько раз еще простейшие тесты и таки выполняется все последовательно. в ветке мелкософта отписался если кому интересно
Re[11]: WCF: UserNamePasswordValidator concurrency
От: rumatavz  
Дата: 22.04.11 14:10
Оценка: +1
R>>А куда Вам больше?
А>есть куда. во время выполнения запросов к БД проц фактически простаивает большую часть времени. создание параллельных запросов увеличивает пропускную сопсобность в разы.

Отсюда вывод — работать с базой асинхронно.
В случае с множеством потоков большая часть из них будет простаивать, а поток — не бесплатный ресурс.
Re[12]: WCF: UserNamePasswordValidator concurrency
От: Аноним  
Дата: 22.04.11 14:58
Оценка:
Здравствуйте, rumatavz, Вы писали:

R>Отсюда вывод — работать с базой асинхронно.

как вы пришли к этому выводу? WCF вызывает метод Validate который должен выдать "результат". О какой асинхронности доступа к БД вы говорите? что она даст нам в этом случае?

R>В случае с множеством потоков большая часть из них будет простаивать, а поток — не бесплатный ресурс.

все эти банальности как бы общеизвестны.
раскройте тему применительно к топику
Re[13]: WCF: UserNamePasswordValidator concurrency
От: rumatavz  
Дата: 22.04.11 15:53
Оценка:
R>>Отсюда вывод — работать с базой асинхронно.
А>как вы пришли к этому выводу? WCF вызывает метод Validate который должен выдать "результат". О какой асинхронности доступа к БД вы говорите? что она даст нам в этом случае?

Я имел ввиду, что если есть пул потоков, из которых выполняется одновременно выполняется только 10, то асинхронный вызов — в духе BeginRead позволил бы потоку вернуться в пул и обрабатывать другой вызов во время работы с БД(даже если WCF просто вызывает какой то метод, который выдаёт результат).

В данном случае признаю неуместность совета, т.к. даже если поток спит остальные запросы всё равно ожидают .
Re[14]: WCF: UserNamePasswordValidator concurrency
От: Аноним  
Дата: 22.04.11 16:03
Оценка:
Здравствуйте, rumatavz, Вы писали:

R>Я имел ввиду, что если есть пул потоков, из которых выполняется одновременно выполняется только 10, то асинхронный вызов — в духе BeginRead позволил бы потоку вернуться в пул и обрабатывать другой вызов во время работы с БД(даже если WCF просто вызывает какой то метод, который выдаёт результат).

это понятно. проблема в том, что итого нет и 10 параллельных вызовов, есть последовательное выполнение. более того, я руками делал ThreadPool.SetMinThreads(350, 350), тротлинг тоже задан в такие значения, но все тщетно. судя по молчанию мелкософта — все очень плохо и баг имеет место быть. самое ужасное, что автор подобного топика на msdn создал тему пол года назад, а ответа все нет. они просто тупо тихо слились — не икомментировать, не исправлять
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.