Service Broker, как отправить таблицу с собранными данными? XML-сообщения или нет?

Технологическая машина использует SQL Server Express для сбора данных, таких как температура... База данных обновляется, скажем, каждые несколько секунд (т.е. низкий трафик). Машина и ее SQL Server должны работать независимо от чего бы то ни было. Иногда технологический компьютер (т.е. SQL Server) отключается вместе с машиной.

Центральный SQL Server Standard Edition должен собирать данные со многих машин, подобных приведенным выше.

Какой сценарий вы бы порекомендовали?

  • Машина отправляет каждую новую строку таблицы при ее создании (т.е. каждые несколько секунд одну строку).
  • Машина активирует процесс отправки данных, скажем, каждый час, и отправляет все строки с вновь собранными данными.
  • Любой другой подход?

Если я хорошо понимаю идею Service Broker, будет одно имя типа сообщения запроса, одно имя типа ответного сообщения, одно имя контракта. Каждая из связанных баз данных на машинах SQL будет иметь одну очередь сообщений и соответствующую службу.

Я очень новичок в Service Broker. В учебных примерах показано, как отправлять сообщения в виде XML-фрагментов. Это реальный способ отправки строк таблицы? Как я могу надежно преобразовать результат команды SELECT во фрагмент XML и обратно?

Спасибо, Петр

Внимание: соответствующий вопрос Service Broker — как извлечь строки из XML-сообщения? был создан.


person pepr    schedule 18.07.2012    source источник


Ответы (2)


Я также рекомендую отправлять по мере обновления базы данных одно сообщение на вставленную строку (одно сообщение на оператор из триггера, как предлагает JAnis, также отлично работает, если ваши операторы INSERT не вставляют огромное количество строк в один оператор).

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

Я видел развертывания, аналогичные тому, что вы пытаетесь сделать, см. Большой объем непрерывного аудита в реальном времени и ETL. Я также рекомендую вам прочитать Повторное использование диалогов.

Service Broker очень хорошо справится с включением и выключением экземпляра Express или отключением в течение длительного времени. Он просто сохранит отправленные сообщения и доставит их после восстановления подключения. Вам просто нужно убедиться, что максимальный размер базы данных в 10 ГБ Express достаточен для хранения сообщений столько времени, сколько необходимо, пока не восстановится подключение.

С чем Service Broker плохо справится, так это с тем, что Express будет отображаться как разные DNS-имена каждый раз при обратном подключении (подумайте о ноутбуке, который подключается из дома, из офиса и из Starbucks). Service Broker использует маршрутизацию базы данных для отправки подтверждений с центрального сервера на ваш экземпляр Express, а для маршрутизации требуется статический DNS. Также важно, чтобы экземпляр Express был доступен с центрального сервера (т. е. не находился за трансляцией сетевых адресов). Для мобильного экземпляра (упомянутого ранее ноутбука) как динамическое имя, так и тот факт, что большую часть времени подключение будет происходить из-за NAT, вызовут проблемы. Использование VPN может решить проблемы, но это обременительно.

person Remus Rusanu    schedule 18.07.2012
comment
Спасибо! OK. Мне кажется разумным сделать отправляющий сайт как можно более простым, т. е. триггером, который вызывает ОТПРАВКУ каждой новой строки через Service Broker. Есть ли смысл, если экспресс-машина ждала ответа? Проблема скорее в односторонней отправке данных. Примечание: серверы Express и Standard будут работать в своего рода физически фиксированной среде. 10 Гб тоже более чем достаточно. Здесь нет проблем. - person pepr; 19.07.2012
comment
Express должен обрабатывать ответы, например. у него должна быть активированная процедура, прикрепленная к его очереди отправителя. Даже при таком одностороннем трафике, как у вас, есть ответ: EndDialog должен быть отправлен вашим центральным стандартным сервером. Читать rusanu.com/2006/04/06/, чтобы понять, почему экспресс-завершение диалогов первым опасно. - person Remus Rusanu; 19.07.2012
comment
Кстати, вы никогда не должны ждать ответа в SSB, даже при двустороннем трафике. Никогда не SEND затем WAITFOR(RECEIVE) в ожидании ответа. Ответ может прийти через несколько минут, часов или даже дней (представьте, что центральный сервер только что вышел из строя, и потребовалось 24 часа, чтобы восстановить его работоспособность...). Приложения SSB должны быть асинхронными, управляемыми событиями. - person Remus Rusanu; 19.07.2012
comment
Обратите внимание на ссылку на соответствующий вопрос в конце обновленного вопроса (stackoverflow.com/q/11563452/1346705). ). - person pepr; 19.07.2012

Что ж, если вы реализуете отправку строк в триггере, то отправка действительно происходит тогда (а не время от времени). Вы всегда можете обрабатывать собранные сообщения на стороне получателя, время от времени активируя процедуру (RECEIVE).

Чтобы отправить строку (строки) в виде XML, вы можете использовать оператор в триггере:

Declare @msg XML;
Set @msg =
    (
        Select  * from Inserted FOR XML RAW, Type
    )

А потом просто отправить сообщение.

person Jānis    schedule 18.07.2012
comment
Спасибо! Насколько я понимаю, FOR XML RAW, TYPE - это специальное расширение Microsoft. Какова обратная операция, которая получает сгенерированные строки XML (как полученное сообщение) и вставляет соответствующие значения в таблицу на другой стороне? Если я правильно понимаю, результатом будет одно значение типа XML, возможно, со многими строками, выраженными в виде элементов XML. Как я могу разделить это значение XML? - person pepr; 19.07.2012
comment
в моем примере строка - это элемент, столбцы - это атрибуты. но вы можете переписать пример, добавив ELEMENS, и тогда столбцы также будут элементами. Вы можете получить данные, используя метод значения типа данных XML — @msg.value('(Row/@ID)[1]', 'int'). - person Jānis; 19.07.2012
comment
@Janis: обратите внимание на ссылку на соответствующий вопрос в конце обновленного вопроса (stackoverflow.com/q/11563452/1346705< /а>). - person pepr; 19.07.2012