SQL Service Broker один центральный SQL и несколько вспомогательных SQL

Система состоит из одного центрального SQL-сервера и двух или более вспомогательных серверов. Спутниковые серверы собирают измеренные данные и отправляют их на центральный сервер. Смотрите картинку: введите здесь описание изображения

(Изображение взято с официального сайта Service Broker. Протоколы связи и изменены.)

Мне нужно максимально упростить процесс добавления еще одного спутникового SQL. Я имею в виду, что настройка недавно добавленного SQL-спутника должна быть такой же, как и для других машин SQL-сателлита. Это вообще возможно?

Все SQL-серверы расположены в одном домене, шифрование на основе сертификатов не требуется — по крайней мере, сейчас. Сейчас в приоритете простота и скорость развертывания. Безопасность может быть улучшена на более позднем этапе.

Другими словами, может ли вспомогательный SQL использовать те же типы сообщений, тот же код создания контракта, ту же настройку конечной точки...

Я немного запутался с маршрутизацией и привязкой к цели. Вы можете это прокомментировать?


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


Ответы (1)


Самый простой из самых простых для развертывания — это следующий конфиг:

  1. Используйте одни и те же типы сообщений и контракты везде. Это необходимо в любых ситуациях, так что это само собой разумеется.
  2. Не используйте безопасность диалога. просто GRANT SEND ON SERVICE::[<servicename>] TO [public] везде. Это устраняет необходимость в сертификатах баз данных и привязках удаленных служб.
  3. Используйте сертификаты для конечных точек, но не обменивайтесь ими (экспортируйте, импортируйте, создайте логин и т. д.). Есть хитрость: GRANT CONNECT ON ENDPOINT::[<brokerendpointname>] TO [public] позволяет двум конечным точкам подключаться с использованием SSL (сертификатов) даже без обмена сертификатами.
  4. Используйте транспортную маршрутизацию (то есть включите специальный маршрут TRANSPORT и назовите свои службы, используя соглашение [tcp://hostname:port/servicename].

Позвольте мне объяснить, почему я рекомендую эту настройку:

  • Удаление безопасности диалога упрощает развертывание примерно в 10 раз. Безопасность диалога позволяет службе аутентифицировать и авторизовать отправителя каждого сообщения, но в относительно контролируемых средах (интрасеть) вы можете развертывать ее на основе доверия: любое сообщение, полученное службой, считается отправленным авторизованным отправитель.
  • Использование сертификатов для конечных точек обычно считается сложным из-за необходимости обмениваться сертификатами, чтобы разрешить подключение, но трюк с предоставлением подключения к public на конечной точке брокера устраняет необходимость обмена сертификатами. Все машины, использующие этот трюк, могут взаимодействовать друг с другом без какой-либо предварительной настройки, что даже лучше, чем использование проверки подлинности Windows на конечных точках (для которых требуется разрешение на подключение к domain\machine$ ro, требуется развертывание экземпляров SQL Server с использованием определенных учетные записи домена). Опять же, вы теряете возможность сказать «Нет» при подключении, вы будете принимать подключение от любого экземпляра SQL в вашей интрасети.
  • С маршрутизацией TRANSPORT любой экземпляр SQL Server, который присоединяется к «группе», готов к работе: поскольку имя службы содержит имя хоста, все остальные машины уже знают, как взаимодействовать с этой машиной, и не требуют явные маршруты для добавления.

Эта конфигурация действительно максимально близка к «подключи и работай». Новые машины могут подключаться к любым существующим службам SQL Server SSB немедленно, не требуя каких-либо изменений конфигурации на других существующих машинах.

Вот пример того, как настроить машины для такого развертывания. Допустим, вы хотите начать с развертывания центрального сервера на MACHINE1:

use master;
go

create database master key...
create certificate [MACHINE1] with subject 'MACHINE1';
create endpoint BROKER as tcp (listener_port 4022) for service_broker 
  (authentication certificate [MACHINE1]);
grant connect on endpoint::BROKER to [public];
go

use db1;
create message type...
create contract ...
create queue ...
create service [tcp://MACHINE1:4022/CentralService] 
   on ...
   ([...]);
grant send on service::[tcp://MACHINE1:4022/CentralService] to [public];
create route transport with address = 'TRANSPORT';
go

Вот и все. Теперь давайте объявим узел, скажем, на хосте MACHINE2:

use master;
go

create database master key...
create certificate [MACHINE2] with subject 'MACHINE2';
create endpoint BROKER as tcp (listener_port 4022) for service_broker 
  (authentication certificate [MACHINE2]);
grant connect on endpoint::BROKER to [public];
go

use db2;
create message type...
create contract ...
create queue ...
create service [tcp://MACHINE2:4022/Satellite] 
   on ...
   ([...]);
grant send on service::[tcp://MACHINE2:4022/Satellite] to [public];
create route transport with address = 'TRANSPORT';
go

Вот и все. Теперь происходят две вещи:

  • поскольку обе конечные точки на MACHINE1 и MACHINE2 используют аутентификацию на основе сертификатов и предоставили общедоступное подключение, они могут подключаться и обмениваться сообщениями как есть, без необходимости обмениваться (экспортировать и импортировать) свои сертификаты конечных точек
  • поскольку обе базы данных создали специальный маршрут TRANSPORT, а имена служб имеют специальный синтаксис [tcp://machine:port/service], две службы могут немедленно обмениваться сообщениями как есть, без какой-либо явной маршрутизации.

Лучше всего, как вы добавляете новый узел, скажем, MACHINE3:

use master;
go

create database master key...
create certificate [MACHINE3] with subject 'MACHINE3';
create endpoint BROKER as tcp (listener_port 4022) for service_broker 
  (authentication certificate [MACHINE3]);
grant connect on endpoint::BROKER to [public];
go

use db2;
create message type...
create contract ...
create queue ...
create service [tcp://MACHINE3:4022/Satellite] 
   on ...
   ([...]);
grant send on service::[tcp://MACHINE3:4022/Satellite] to [public];
create route transport with address = 'TRANSPORT';
go

Теперь, скройте любое изменение в MACHINE1 или MACHINE2, новый узел MACHINE3 сможет обмениваться сообщениями с центральной службой, а также, при необходимости, со спутником MACHINE2. Конечные точки принимают любого для подключения, поэтому MACHINE3 приветствуется, а используемые имена служб автоматически маршрутизируются специальным механизмом маршрутизации TRANSPORT. В этом прелесть этой конфигурации, plug-and-play: добавление нового узла требует 0 конфигурации на других узлах.

Так что дает? Самая большая проблема — это безопасность. Любой сотрудник может загрузить SQL Server Express на свой рабочий стол, настроить неавторизованную сателлитную ноду и начать обмен сообщениями с центральной службой. На самом деле его ничто не остановит, вы явно открыли все ворота. Более тонкая проблема возникает, когда служба перемещается. Когда служба [tcp://MACHINE3:4022/Satellite] перемещается (например, посредством резервного копирования/восстановления базы данных) в MACHINE4, имя службы по-прежнему является допустимым именем синтаксиса маршрута TRANSPORT, но неправильным. В зависимости от того, насколько важно сохранить существующий разговор, вы можете отключить службу и создать новую с именем [tcp://MACHINE4:4022/Satellite] и участником (вы не можете переименовать службу, вы должны удалить и создать новую) . Если сохранение существующего диалога имеет решающее значение, существуют обходные пути, так как добавление явного маршрута для него в базу данных центральной службы будет иметь приоритет над маршрутом TRANSPORT последней инстанции, и сообщения будут быть перенаправлены правильно. Важно то, что существуют решения :)

person Remus Rusanu    schedule 28.07.2012
comment
Небольшой связанный с этим вопрос: могут ли типы сообщений для запроса и ответа использовать один и тот же идентификатор? (Хорошо ли начать новый вопрос о том, как выбрать строки идентификации?) Спасибо. - person pepr; 03.08.2012
comment
Это полностью зависит от бизнес-правил - person Remus Rusanu; 03.08.2012
comment
Должны ли мастер-ключ и сертификат создаваться в базе данных master? Является ли master фиксированной точкой во вселенной для сервисного брокера? (Причина в том, что я хотел бы избежать ситуации, когда кому-то еще нужен мастер-ключ, т.е. это потребует совместного использования пароля.) - person pepr; 07.08.2012
comment
Конечные точки являются объектами уровня экземпляра, поэтому их можно настроить только через [master]. Используемый сертификат должен быть основным. Закрытый ключ, связанный с сертификатом, также должен быть главным и должен быть зашифрован главным ключом базы данных, чтобы конечная точка могла получить к нему доступ без вмешательства пользователя (без вмешательства пользователя). открытие сертификата) из-за фонового характера действий конечной точки. Поэтому ответ Да, это должно быть в master. - person Remus Rusanu; 07.08.2012
comment
Пожалуйста, взгляните на новый вопрос stackoverflow.com/q/28982099/1346705, связанный с переносом решения на SQL 2014. - person pepr; 11.03.2015