Компонент SQL Server Service Broker для распределенного приложения с беседами, застрявшими в состоянии разговора - PullRequest
0 голосов
/ 05 июня 2018

У меня уже есть небольшой опыт работы с SSB, но я только что сделал это в базах данных на том же сервере.Я никогда не делал это распределенным, используя два разных сервера на разных машинах.Итак, после нескольких исследований я нашел несколько учебных пособий по YouTube и хороший учебник с именно тем, что я хочу, по безопасности.

Но я не могу доставить свое сообщение с сервера А на серверБ. Вопрос в том;Как найти то, что мне не хватает?

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

Я читаю эту книгу под названием «Pro SQL Server 2008 ServiceСломался ", пытаясь найти мой ответ.

Я собрал несколько видео на YouTube.

Я попытался это устранение неполадок, но я не смог 'т использовать ssbdiagnose.Я не знаю, где его найти.


Теперь я собираюсь уточнить и опубликовать свою среду и то, что я сделал до сих пор.

Инициатор - это SQLServer 2016 Express

  • Windows 2010 Pro
  • хост: 192.168.20.44:1433
  • база данных: MarketPlace
  • брандмауэр: выключен
  • Конфигурация сервера: TCP включен
  • SSB: порт 4022 (проверено только через telnet)

Целевой объект - SQL Server 2016 Express

  • Windows Server 2012 R2 Standard Работает в Hyper-V на хосте 192.168.20.44

  • хост: 192.168.20.30:1433

  • база данных: MarketPlace

  • брандмауэр: выключен

  • Конфигурация сервера: TCP включен

  • SSB: порт 4022 (проверено только через telnet)

Сценарии для 192.168.20.44 Сервер инициатора

--###
--All actions related to Basic Service Broker Objects and Dialog Security 
--will be performed in MarketPlace database of 192.168.20.44
--###
--1 Create the Basic Service Broker Objects
--###
USE MarketPlace
GO

ALTER DATABASE MarketPlace
SET Enable_broker;
GO

--1.1 Create Message Types
CREATE Message Type SenderMessageType validation = NONE;
GO

CREATE Message Type ReceiverMessageType validation = NONE;
GO

--1.2 Create Contract on the above message types
CREATE Contract PointOfSaleContract (
    SenderMessageType SENT BY INITIATOR
    ,ReceiverMessageType SENT BY TARGET
    );
GO

--1.3 Create an Initiator queue
CREATE QUEUE InitiatorQueue
    WITH STATUS = ON;
GO

--1.4  Create a Service on the queue and the contract
CREATE Service MarketPlaceService ON QUEUE InitiatorQueue (PointOfSaleContract);
GO

--###
--2 Set up Dialog Security
--###
--2.1 Create a master key in the local database i.e. the database we are going to use for our application.
CREATE Master KEY ENCRYPTION BY Password = 'gs53&"f"!385'
GO

--2.2 Create a user certificate
CREATE Certificate CertificateUserMarketPlace
    WITH Subject = 'CertificateUserMarketPlace'
        ,START_DATE = '2018-01-01'
        ,EXPIRY_DATE = '2020-12-31' ACTIVE
FOR BEGIN_DIALOG = ON;
GO

--2.3 Take a backup of the CertificateUserMarketPlace created and install it into the remote instance
--Copy the certificate to Stage Server Machine
--I Did install the certificates for current user within "automatically select the certificate store" option. Have to?
BACKUP CERTIFICATE CertificateUserMarketPlace TO FILE = 'C:\SSB\CertificateUserMarketPlace.cer';
GO

--2.4 Create a user with the same name as the user who has access rights on the other Database
--I Didn't understand this part. Should I create the very same user on Stage database?
CREATE User UserStage WITHOUT LOGIN
GO

--2.5 Create a user certificate from the user certificate backup file copied from the other server, 
--with authorization to the user created in Step 4
CREATE CERTIFICATE CertificateUserStage AUTHORIZATION UserStage
FROM FILE = 'C:\SSB\CertificateUserStage.cer';
GO

--2.6 Grant connect permissions to the user
GRANT CONNECT
    TO UserStage;
GO

--2.7 Grant send permissions to the user on the local service
GRANT SEND
    ON SERVICE::MarketPlaceService
    TO UserStage;
GO

--2.8 Create a Remote Service Binding with the user created.
CREATE REMOTE SERVICE BINDING ServiceBindingStage TO SERVICE 'StageService'
    WITH USER = UserStage
GO

--###
--3 Set up Transport Security
--All actions related to Transport Security
--will be performed in Master database of 192.168.20.44
--###
USE master
GO

--3.1 Create a master key for master database.
CREATE Master KEY ENCRYPTION BY Password = 'gs53&"f"!385'
GO

--3.2 Create certificate 
CREATE CERTIFICATE EndPointCertificateMarketPlace
    WITH Subject = 'EndPointCertificateMarketPlace'
        ,START_DATE = '2018-01-01'
        ,EXPIRY_DATE = '2020-12-31' ACTIVE
FOR BEGIN_DIALOG = ON;
GO

--3.3 Create End Point that support certificate based authentication
CREATE ENDPOINT ServiceBrokerEndPoint STATE = STARTED AS TCP (LISTENER_PORT = 4022)
FOR SERVICE_BROKER(AUTHENTICATION = CERTIFICATE EndPointCertificateMarketPlace, ENCRYPTION = SUPPORTED);
GO

--3.4 Take a backup of the certificate created and install it into the remote instance
--Copy the certificate to Stage
BACKUP CERTIFICATE EndPointCertificateMarketPlace TO FILE = 'C:\SSB\EndPointCertificateMarketPlace.cer';
GO

--3.5 Create certificate from the certificate backup file copied from the Target server
CREATE CERTIFICATE EndPointCertificateStage
FROM FILE = 'C:\SSB\EndPointCertificateStage.cer';
GO

--3.6 Create login from the certificate created in Step 3.5
CREATE LOGIN SSBLogin
FROM CERTIFICATE EndPointCertificateStage;
GO

--3.7 Grant the login, connect permissions on the end point.
GRANT CONNECT
    ON ENDPOINT::ServiceBrokerEndPoint
    TO SSBLogin
GO

SELECT *
FROM sys.service_broker_endpoints
GO

--###
--4 Create a Route
--###
USE MarketPlace
GO

--4.1 Get the UID from Stage database on 192.168.20.30 to use on the Route
SELECT service_broker_guid
FROM sys.databases
WHERE NAME = 'Stage';

--4.2 Use the UID from 4.1
CREATE Route RouteToStageService
    WITH SERVICE_NAME = 'StageService'
        ,BROKER_INSTANCE = 'A88B9743-EAFF-42FA-9404-0D551D4B29DB' -- Guid From Stage
        ,ADDRESS = 'TCP://192.168.20.30:4022'
GO

Скрипты для 192.168.20.30 ЦельСервер

--###
--All actions related to Basic Service Broker Objects and Dialog Security 
--will be performed in Stage database of 192.168.20.30
--###
--1 Create the basic Service Broker Objects
--###
USE Stage
GO

ALTER DATABASE Stage
SET Enable_broker;
GO

--1.1 Create Message Types
CREATE Message Type SenderMessageType validation = NONE;
GO

CREATE Message Type ReceiverMessageType validation = NONE;
GO

--1.2 Create Contract on the above message types
CREATE Contract PointOfSaleContract (
    SenderMessageType SENT BY INITIATOR
    ,ReceiverMessageType SENT BY TARGET
    );
GO

--1.3 Create an Target queue
CREATE QUEUE TargetQueue
    WITH STATUS = ON;
GO

--1.4  Create a Service on the queue and the contract
CREATE Service StageService ON QUEUE TargetQueue (PointOfSaleContract);
GO

--###
--2 Set up Dialog Security
--###
--2.1 Create a master key in the local database i.e. the database we are going to use for our application.
CREATE Master KEY ENCRYPTION BY Password = '45Gme*3^&fwu'
GO

--2.2 Create a user certificate
CREATE Certificate CertificateUserStage
    WITH SUBJECT = 'CertificateUserStage'
        ,START_DATE = '2018-01-01'
        ,EXPIRY_DATE = '2020-12-31' ACTIVE
FOR BEGIN_DIALOG = ON;
GO
--2.3 Take a backup of the user certificate created and install it into the remote instance
--Copy the certificate to MarketPlace Server Machine
BACKUP CERTIFICATE CertificateUserStage TO FILE = 'C:\SSB\CertificateUserStage.cer';
GO

--2.4 Create a user with the same name as the user who has access rights on the other Database
CREATE User UserMarketPlace WITHOUT LOGIN
GO

--2.5 Create a user certificate from the user certificate backup file copied from the other server, 
--with authorization to the user created in Step 4
CREATE CERTIFICATE CertificateUserMarketPlace AUTHORIZATION UserMarketPlace
FROM FILE = 'C:\SSB\CertificateUserMarketPlace.cer';
GO

--2.6 Grant connect permissions to the user
GRANT CONNECT
    TO UserMarketPlace;
GO

--2.7 Grant send permissions to the user on the local service
GRANT SEND
    ON SERVICE::StageService
    TO UserMarketPlace;
GO

--2.8 Create a Remote Service Binding with the user created.
CREATE REMOTE SERVICE BINDING ServiceBindingMarketPlace TO SERVICE 'MarketPlaceService'
    WITH USER = UserMarketPlace
GO

--###
--3 Set up Transport Security
--All actions related to Transport Security
--will be performed in Master database of 192.168.20.30
--###
USE master
GO

--3.1 Create a master key for master database.
CREATE Master KEY ENCRYPTION BY Password = '45Gme*3^&fwu';
GO

--3.2 Create certificate and End Point that support certificate based authentication 
CREATE Certificate EndPointCertificateStage
    WITH Subject = 'EndPointCertificateStage'
        ,START_DATE = '2018-01-01'
        ,EXPIRY_DATE = '2020-12-31' ACTIVE
FOR BEGIN_DIALOG = ON;
GO

--3.3 Create End Point that support certificate based authentication
CREATE ENDPOINT ServiceBrokerEndPoint STATE = STARTED AS TCP (LISTENER_PORT = 4022)
FOR SERVICE_BROKER(AUTHENTICATION = CERTIFICATE EndPointCertificateStage, ENCRYPTION = SUPPORTED);
GO

--3.4 Take a backup of the certificate created and install it into the remote instance.
--Copy the certificate to MarketPlace
BACKUP CERTIFICATE EndPointCertificateStage TO FILE = 'C:\SSB\EndPointCertificateStage.cer';
GO

--3.5 Create certificate from the certificate backup file copied from the other server
CREATE Certificate EndPointCertificateMarketPlace
FROM FILE = 'C:\SSB\EndPointCertificateMarketPlace.cer';
GO

--3.6 Create login from the certificate created in Step 3.5
CREATE LOGIN SSBLogin
FROM CERTIFICATE EndPointCertificateMarketPlace;
GO

--3.7 Grant the login, connect permissions on the end point.
GRANT CONNECT
    ON ENDPOINT::ServiceBrokerEndPoint
    TO SSBLogin
GO

SELECT *
FROM sys.service_broker_endpoints
GO

--###
--4 Create a Route
--###
USE Stage
GO

--4.1 Get the UID from MarketPlace database on 192.168.20.44 to use on the Route
SELECT service_broker_guid
FROM sys.databases
WHERE NAME = 'Stage';

--4.2 Use the UID from 4.1
CREATE Route RouteToMarketPlaceService
    WITH SERVICE_NAME = 'MarketPlaceService'
        ,BROKER_INSTANCE = 'A18B5078-EB73-42D4-ACF9-4AF6549921A0' -- From MarketPlace
        ,ADDRESS = 'TCP://192.168.20.44:4022'
GO

Теперь, когда я запускаю это на сервере инициатора, сообщения зависают:

USE MarketPlace
GO

SELECT conversation_handle, to_service_name, enqueue_time, cast(message_body AS XML)
FROM sys.transmission_queue;

DECLARE @ConversationHandle uniqueidentifier;
BEGIN TRANSACTION
  BEGIN DIALOG @ConversationHandle
  FROM SERVICE MarketPlaceService
  TO SERVICE 'StageService'
  ON CONTRACT PointOfSaleContract
  WITH ENCRYPTION = OFF;
  SEND
  ON CONVERSATION @ConversationHandle
  MESSAGE TYPE SenderMessageType
  ('<test>Test 001</test>')
COMMIT

SELECT conversation_handle, to_service_name, enqueue_time, cast(message_body AS XML)
FROM sys.transmission_queue;

SELECT conversation_handle, is_initiator, state_desc, far_service
FROM MarketPlace.sys.conversation_endpoints;

enter image description here

Я не вижу свое сообщение на моем целевом сервере:

--###
--6 Sent Messages from MarketPlace
--###
USE Stage
GO

SELECT cast(message_body AS XML)
FROM TargetQueue;
GO

Если вы читали до здесь.Спасибо за внимание.

1 Ответ

0 голосов
/ 05 июня 2018

С «Обзор SQL Server 2005 Express Edition» :

SQL Server Express может использовать компонент Service Broker только в сочетании с другими выпусками SQL Server 2005.Если SQL Server Express получает сообщение посредника от другого экземпляра Express, и если другое издание SQL Server 2005 не обработало сообщение, то сообщение отбрасывается.Таким образом, сообщение может исходить из экземпляра Express и заканчиваться в одном, но в этом случае оно должно быть направлено через экземпляр без экспресса.Вы можете проверить событие трассировки отбрасывания сообщений, которое доступно из Профилировщика, или использовать хранимые процедуры трассировки для отслеживания этого типа возникновения.Сообщение об ошибке, связанное с удаленным сообщением, включает в себя следующее: «Это сообщение было удалено из-за лицензионных ограничений».

Я знаю, что это гораздо более старая версия, но я не смог найти столь же подробное утверждение для 2016 года. Однако, как и "Издания и поддерживаемые функции SQL Server 2016" все ещеперечисляет ограничения, касающиеся компонента Service Broker («Нет (только для клиента)»). Я полагаю, что он все еще действителен для 2016 года.

Я пробовал это не так давно с очень похожей настройкой (также 2016 Express)и не нашел способа заставить его работать напрямую.

В качестве обходного пути я нашел использование связанных серверов.Я отправляю код BEGIN DIALOG CONVERSATION ... SEND ON CONVERSATION ... на удаленный сервер по ссылке и выполняю его там с использованием sp_executesql (внутренне Message Broker прекрасно работает в Express Editions, он просто не может обмениваться сообщениями с другими серверами Express Edition).При этом я столкнулся с ошибкой (по-видимому) с DTC, которая изначально мешала удаленному вызову.Вместо этого он сказал мне, что код DTC недоступен на удаленном сервере.Однако это можно исправить, установив для параметра remote proc transaction promotion значение false.

EXEC master.dbo.sp_serveroption @server = N'<the server link>', @optname = N'remote proc transaction promotion', @optvalue = N'true';

В течение некоторого времени все работало хорошо.Но некоторые из последних обновлений для SQL Server могли что-то сломать.По крайней мере, у меня возникают странные проблемы с настройкой моего Service Broker, аналогичные вашей, и они, похоже, начались в тот самый день, когда был обновлен SQL Server.Но так как это не так уж важно, я еще не нашел времени, чтобы изучить это более подробно и найти решение.Поэтому я не могу дать вам подсказку по пути к этому прямо сейчас.(Рассматриваемые обновления, по-видимому, относятся к маю этого года. Извините, но сейчас у меня нет номеров КБ.)

Другой вариант, если вы используете это только для разработки, может быть«обновить» до Developer Edition.Это утверждает, что было полнофункциональным (равным AFAIK Enterprise Edition). Вот ссылка для версии 2017 года.Но я полагаю, что вокруг 2016 года тоже, если вы настаиваете на том, чтобы остаться в 2016 году.

...