Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 "Укрощение" Service Broker или "велосипед очередности"  [new]
orunbek
Member

Откуда: Гималай
Сообщений: 2101
Приветствую всех.
В нескольких темах до этого писал про необходимость создания системы очереди в одной системе (тема.
В котором поступают запросы и эти запросы в зависимости от типа запроса обрабатываются через Web-сервисы различных поставщиков.
Решил данную проблему через Service Broker, в котором запросы поступают в единую очередь а обработка делается через .NET CLR хранимку (активируемая хранимка), которая и в зависимости от типа запроса и пропускает через нужный веб-сервис.
Вкратце, алгортим обработки запросов следующий:
1. Идет логическая обработка исходных данных для запроса. При этом может быть возникнет необходимость блокировки таблицы запросов в режиме UPDLOCK (т.е. новые данные не будут вставляться пока блокировка не снимется)
2. Алгортим обработки этих запросов у каждого web-сервиса различный, и "глюки" тоже могут быть разными, иногда в одном web-сервисе могут произойти сбой, в других в это же время все может работать нормально. Обычно обработка одного запроса по всем веб-сервисам производится в течение 1-2 секунды, и.... в принципе никаких проблем не возникает. Но во время глюков веб-сервисов, если "зависла" обработка определенных запросов то 1ый шаг, логическая обработка запросов с необходимость UPDLOCK блокировок тоже "ждет и подвисает". Так как в .NET CLR данные из очереди берутся инструкцией
WAITFOR (RECEIVE TOP (1) conversation_handle, message_type_name, message_body FROM SB_Charges_TargetQueue), TIMEOUT 1000

обернутой в транзакцию.

Если же эту инструкцию не выполнять в BEGIN TRAN... COMMIT TRAN есть риск того, что одна и та же запись из очереди Service Broker обработаются 2 раза, но из-за потенциальных глюков веб-сервисов, есть риск зависания предварительной обработки запросов.
На ум приходит вариант обработки без запросов, просто поставить на INSERT в таблицу запросов вызов .NET CLR хранимки с передачей ID добавленой записи.
Но в данном случае пропадает возможность контролирования количества запущенных хранимок. Чтобы "всю память не сожрали". Нужно хоть как-то контролировать. Или есть ли возможность определения количества в данный момент работающих хранимок определенного типа, к примеру сколько в данный момент запущено хранимки SP_QueryProcessor.
Или какие риски обработки очередей Service Broker без BEGIN TRAN?
Есть ли обходные пути не блокировать обработку очереди?

Хотя на ум приходит еще вариант обработки очереди следующим образом, взять данные из очереди в BEGIN TRAN... COMMIT TRAN
а потом только пускать через веб-сервис.

Посоветуйте камрады.
Спасибо, заранее.

P.S. Но в любом случае интересна возможность определения количества активно работающих хранимок определенного типа.
5 июн 12, 08:12    [12665366]     Ответить | Цитировать Сообщить модератору
 Re: "Укрощение" Service Broker или "велосипед очередности"  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74930
автор
Если же эту инструкцию не выполнять в BEGIN TRAN... COMMIT TRAN есть риск того, что одна и та же запись из очереди Service Broker обработаются 2 раза


М.б. поможет: BOL->Conversation Group Locks
5 июн 12, 08:44    [12665425]     Ответить | Цитировать Сообщить модератору
 Re: "Укрощение" Service Broker или "велосипед очередности"  [new]
dmitry stakanov
Member

Откуда:
Сообщений: 241
orunbek,

можете подробнее бизнес логику процесса описать?

пс мое мнение, чем раньше коммит при выборке из очереди, тем лучше, если это конечно позволяет бизнес логика.
ппс отцы брокера рекомендуют выбирать TOP N, ни в коем случае не TOP 1. там кстати весь бест практис по сб. к сожалению ссылки у меня нет)
5 июн 12, 11:02    [12666288]     Ответить | Цитировать Сообщить модератору
 Re: "Укрощение" Service Broker или "велосипед очередности"  [new]
mike909
Member

Откуда:
Сообщений: 662
orunbek,

orunbek
WAITFOR (RECEIVE TOP (1) conversation_handle, message_type_name, message_body FROM SB_Charges_TargetQueue), TIMEOUT 1000
Если же эту инструкцию не выполнять в BEGIN TRAN... COMMIT TRAN есть риск того, что одна и та же запись из очереди Service Broker обработаются 2 раза

Одно сообщение всегда обрабатывается только одним reader_ом, и не зависит от Вашей дополнительной транзакции.
Более того, пока commit_а нет, все следующие сообщения и сообщения в других диалогах, объединенных в одну группу (см. RELATED_CONVERSATION_GROUP) будут недоступны для других reader_ов.
Следовательно Ваша дополнительная транзакция влияет только на то, когда сообщение будет удалено из очереди SB, и на то, когда остальные Reader_ы смогут "почитать" следующие сообщения.
Риски:
1) Если commit_ить сразу после получения сообщения, то можно потерять его в результете exception_ов при последующей обработки. Т.к. сообщение будет удалено из очереди SB.
2) Если commit_ить после обработки, то можно получить блокировку очереди SB после 5_ти rollback_ов (в sql2k8 и выше такое поведение начтраивается).
Для устранения этих рисков я сохраняю необходимые данные из прочитанного сообщения в "таблицу запросов" затем commit.
Минус данного подхода - если по одному диалогу может приходить более одного запроса, и последовательность обработки важна, то такой подход не применим (хотя и эту задачу можно решить разбив предварительную обработку на насколько сервисов SB ...).

Далее, а не хотите ли запуск CLR_ок разместить в других сервисах SB, т.е.:
1) Задачи для первого сервиса SB:
1.1 Читать новые запросы от клиентов
1.2 На основе логической обработки клиентского запроса создавать диалоги к "рабочим сервисам", объединяя их в одну RELATED_CONVERSATION_GROUP
1.3 Получать "результат выполнения" от "рабочих сервисов"
1.4 Пост-обработка всех результатов и отсылка клиенту (если требуется).
1.5 Мониторинг выполнения, перезапуск сбойных/зависших запросов к "рабочим сервисам"
1.6 Еще много чего, у меня накручено на этот сервис, но только не само выполнение - это основная мысль.
2) Задачи для второго и последующих однотипных (у всех один и тот-же Reader) сервисов SB:
2.1 Тупо и храбро выполняем что запросили. У Вас - запуск CLR_ок
2.2 Отправка результатов сервису из п.п. 1
Соответственно, можно играясь кол-вом Reader_ов у "рабочих сервисов" оптимально настроить выполнение для каждого "типа хранимок".

orunbek
P.S. Но в любом случае интересна возможность определения количества активно работающих хранимок определенного типа.

Ваша задача решена ?
5 июн 12, 11:30    [12666580]     Ответить | Цитировать Сообщить модератору
 Re: "Укрощение" Service Broker или "велосипед очередности"  [new]
orunbek
Member

Откуда: Гималай
Сообщений: 2101
Всем спасибо.
Достаточно интересные способы были предложены, в особенности расписанный способ от mike909, за что ему спасибо.
И спасибо за подсказку по Conversation Group Locks pkarklin'у.
Данная система это первое что я построил используя систему очередности MSSQL Service Broker.
Но как высказал свое мнение dmitry stakanov, и о том же я и писал во время написания данной темы, попробую реализовать комбинированный вариант.
Т.е. быстрое чтение записи из очереди и вставка в спец.таблицу очередей, для того чтобы не потерять и сразу передаю обработчику, который пускает запрос через необходимый веб-сервис, затем после обработки отмечаю что запись в спец.таблице очередей обработана.
При этом логическая пред-обработка не будет зависеть от глюков внешних веб-сервисов.
Как думаете?
5 июн 12, 17:30    [12670106]     Ответить | Цитировать Сообщить модератору
 Re: "Укрощение" Service Broker или "велосипед очередности"  [new]
mike909
Member

Откуда:
Сообщений: 662
dmitry stakanov
orunbek,

можете подробнее бизнес логику процесса описать?

пс мое мнение, чем раньше коммит при выборке из очереди, тем лучше, если это конечно позволяет бизнес логика.
ппс отцы брокера рекомендуют выбирать TOP N, ни в коем случае не TOP 1. там кстати весь бест практис по сб. к сожалению ссылки у меня нет)

TOP N, рекомендуют.
Ну это выгодно только при большом потоке сообщений по одному диалогу. Что-то мне такие задачи не встречались.
Да и прочитав X[0..N] сообщений усложняется обработка "отравленн_ого(ых)" сообщений.

To orunbek.
В качестве примера по RELATED_CONVERSATION_GROUP Service Broker прочитать все мессаджи
orunbek
При этом логическая пред-обработка не будет зависеть от глюков внешних веб-сервисов.
Как думаете?

Скорее пост-обработка результатов, т.к. пред-обработка, imho, выполняется до запуска каких либо веб-сервисов.
5 июн 12, 18:46    [12670603]     Ответить | Цитировать Сообщить модератору
 Re: "Укрощение" Service Broker или "велосипед очередности"  [new]
orunbek
Member

Откуда: Гималай
Сообщений: 2101
mike909
dmitry stakanov
orunbek,

можете подробнее бизнес логику процесса описать?

пс мое мнение, чем раньше коммит при выборке из очереди, тем лучше, если это конечно позволяет бизнес логика.
ппс отцы брокера рекомендуют выбирать TOP N, ни в коем случае не TOP 1. там кстати весь бест практис по сб. к сожалению ссылки у меня нет)

TOP N, рекомендуют.
Ну это выгодно только при большом потоке сообщений по одному диалогу. Что-то мне такие задачи не встречались.
Да и прочитав X[0..N] сообщений усложняется обработка "отравленн_ого(ых)" сообщений.

To orunbek.
В качестве примера по RELATED_CONVERSATION_GROUP Service Broker прочитать все мессаджи
orunbek
При этом логическая пред-обработка не будет зависеть от глюков внешних веб-сервисов.
Как думаете?

Скорее пост-обработка результатов, т.к. пред-обработка, imho, выполняется до запуска каких либо веб-сервисов.

Как уже писал выше в пред-обработке есть блокировка таблицы запросов в режиме UPDLOCK, что и подвисало в случаях когда были глюки на стороне веб-сервиса, из-за того что WAITFOR был обернут в транзакцию.
Сейчас делаю вариант чтения записи из очереди и моментальное закрытие транзакции, и уж потом обработка через веб-сервис.
Соответственно даже если будут глюки, то пред-обработка с UPDLOCK не будет подвисать.
5 июн 12, 21:04    [12671017]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить