不同Server之间的数据传输,包含DB使用AlwaysOn

配置脚本:

SQL Server Service Broker 跨集群通信

具体的TSQL 脚本语句如下。注意的是TSQL语句是在发送方还是接收方运行。对每个step,要先运行左边的, 然后运行右边的。 一共15个step。

发送方集群

侦听地址:10.17.30.46

接收方集群

侦听地址:172.20.168.235

STEP1. 创建Service Broker端点,默认 TCP 端口号 4022(主本服务器上执行)

注意:执行前请检查当前服务器中,该端点名称是否是正在使用的端点,如果是请重新命名

USE master;

GO

IF EXISTS (SELECT * FROM sys.endpoints

WHERE name = N'InstInitiatorEndpoint')

DROP ENDPOINT InstInitiatorEndpoint;

GO

CREATE ENDPOINT InstInitiatorEndpoint

STATE = STARTED

AS TCP ( LISTENER_PORT = 4022 )

FOR SERVICE_BROKER (AUTHENTICATION = WINDOWS );

GO

USE master;

GO

IF EXISTS (SELECT * FROM master.sys.endpoints

WHERE name = N'InstTargetEndpoint')

DROP ENDPOINT InstTargetEndpoint;

GO

CREATE ENDPOINT InstTargetEndpoint

STATE = STARTED

AS TCP ( LISTENER_PORT = 4022 )

FOR SERVICE_BROKER (AUTHENTICATION = WINDOWS );

GO

STEP2. 创建数据库、创建用于支持加密和远程连接的主密钥和用户。(主本服务器上执行)

注意:如果数据已存在,请重新命名。执行前请检查!!!

USE master;

GO

IF EXISTS (SELECT * FROM sys.databases

WHERE name = N'InstInitiatorDB')

DROP DATABASE InstInitiatorDB;

GO

CREATE DATABASE InstInitiatorDB;

GO

USE InstInitiatorDB;

GO

CREATE MASTER KEY

ENCRYPTION BY PASSWORD = N'MikeA3070814!';

GO

CREATE USER InitiatorUser WITHOUT LOGIN;

GO

USE master;

GO

IF EXISTS (SELECT * FROM sys.databases

WHERE name = N'InstTargetDB')

DROP DATABASE InstTargetDB;

GO

CREATE DATABASE InstTargetDB;

GO

USE InstTargetDB;

GO

CREATE MASTER KEY

ENCRYPTION BY PASSWORD = N'MikeA3070814!';

GO

CREATE USER TargetUser WITHOUT LOGIN;

GO

STEP3. 创建用于加密消息的证书。需要copy这个证书到双方能够访问的文件夹(主本服务器上执行)

USE InstInitiatorDB;

GO

CREATE CERTIFICATE InstInitiatorCertificate

AUTHORIZATION InitiatorUser

WITH SUBJECT = N'Initiator Certificate',

EXPIRY_DATE = N'12/31/2090';

BACKUP CERTIFICATE InstInitiatorCertificate

TO FILE =

N'\\172.20.168.56\Document\SSB\mike\InstInitiatorCertificate2.cer';

GO

USE InstTargetDB;

GO

CREATE CERTIFICATE InstTargetCertificate

AUTHORIZATION TargetUser

WITH SUBJECT = 'Target Certificate',

EXPIRY_DATE = N'12/31/2090';

BACKUP CERTIFICATE InstTargetCertificate

TO FILE =

N'\\172.20.168.56\Document\SSB\mike\InstTargetCertificate2.cer';

GO

STEP4. 为会话创建消息类型和约定 。发起方和目标方指定的消息、约定的名称和他们属性必须相同。(主本服务器上执行)

USE InstInitiatorDB;

GO

CREATE MESSAGE TYPE [//BothDB/2InstSample/RequestMessage]

VALIDATION = WELL_FORMED_XML;

CREATE MESSAGE TYPE [//BothDB/2InstSample/ReplyMessage]

VALIDATION = WELL_FORMED_XML;

GO

CREATE CONTRACT [//BothDB/2InstSample/SimpleContract]      ([//BothDB/2InstSample/RequestMessage]

SENT BY INITIATOR,

[//BothDB/2InstSample/ReplyMessage]

SENT BY TARGET

);

GO

USE InstTargetDB;

GO

CREATE MESSAGE TYPE [//BothDB/2InstSample/RequestMessage]

VALIDATION = WELL_FORMED_XML;

CREATE MESSAGE TYPE [//BothDB/2InstSample/ReplyMessage]

VALIDATION = WELL_FORMED_XML;

GO

CREATE CONTRACT [//BothDB/2InstSample/SimpleContract]

([//BothDB/2InstSample/RequestMessage]

SENT BY INITIATOR,       [//BothDB/2InstSample/ReplyMessage]

SENT BY TARGET

);

GO

STEP5. 创建队列和服务,注意服务和队列如何关联。发送给此服务的消息将保存到相应的队列中。(主本服务器上执行)

USE InstInitiatorDB;

GO

CREATE QUEUE InstInitiatorQueue;

CREATE SERVICE [//InstDB/2InstSample/InitiatorService]

AUTHORIZATION InitiatorUser

ON QUEUE InstInitiatorQueue ([//BothDB/2InstSample/SimpleContract]);

GO

USE InstTargetDB;

GO

CREATE QUEUE InstTargetQueue;

CREATE SERVICE [//TgtDB/2InstSample/TargetService]

AUTHORIZATION TargetUser

ON QUEUE InstTargetQueue       ([//BothDB/2InstSample/SimpleContract]);

GO

STEP6. 创建对目标对象的引用需要访问对方先前创建的证书。(主本服务器上执行)

USE InstInitiatorDB;

GO

CREATE USER TargetUser WITHOUT LOGIN;

CREATE CERTIFICATE InstTargetCertificate

AUTHORIZATION TargetUser

FROM FILE =

N'\\172.20.168.56\Document\SSB\mike\InstTargetCertificate2.cer'

GO

USE InstTargetDB

GO

CREATE USER InitiatorUser WITHOUT LOGIN;

CREATE CERTIFICATE InstInitiatorCertificate

AUTHORIZATION InitiatorUser

FROM FILE =

N'\\172.20.168.56\Document\SSB\mike\InstInitiatorCertificate2.cer';

GO

STEP7. 创建指向服务路由,并创建将User 与目标服务路由相关联的远程服务绑定。(主本服务器上执行)

注意:TCP地址是对方集群的侦听地址

DECLARE @Cmd NVARCHAR(4000);

SET @Cmd = N'USE InstInitiatorDB;

CREATE ROUTE InstTargetRoute

WITH SERVICE_NAME = N''//TgtDB/2InstSample/TargetService'',

ADDRESS = ''TCP://172.20.168.235:4022'';';

EXEC (@Cmd);

SET @Cmd = N'USE msdb

CREATE ROUTE InstInitiatorRoute

WITH SERVICE_NAME = N''//InstDB/2InstSample/InitiatorService'',

ADDRESS = N''LOCAL''';

EXEC (@Cmd);

GO

CREATE REMOTE SERVICE BINDING TargetBinding

TO SERVICE  N'//TgtDB/2InstSample/TargetService'

WITH USER = TargetUser;

GO

DECLARE @Cmd NVARCHAR(4000);

SET @Cmd = N'USE InstTargetDB;

CREATE ROUTE InstInitiatorRoute

WITH SERVICE_NAME = N''//InstDB/2InstSample/InitiatorService'',

ADDRESS = ''TCP://10.17.30.46:4022'';';

EXEC (@Cmd);

SET @Cmd = N'USE msdb

CREATE ROUTE InstTargetRoute

WITH SERVICE_NAME = N''//TgtDB/2InstSample/TargetService'',

ADDRESS = N''LOCAL''';

EXEC (@Cmd);

GO

GRANT SEND  ON SERVICE::[//TgtDB/2InstSample/TargetService]

TO InitiatorUser;

GO

CREATE REMOTE SERVICE BINDING InitiatorBinding

TO SERVICE N'//InstDB/2InstSample/InitiatorService'

WITH USER = InitiatorUser;

GO

STEP8. 数据库未加入集群时,测试SSB是否配置成功。目标队列收到发送的消息即成功,反之。(主本服务器上执行)

USE InstInitiatorDB;

GO

--启动会话并发送消息

DECLARE @InitDlgHandle UNIQUEIDENTIFIER;

DECLARE @RequestMsg NVARCHAR(100);

BEGIN TRANSACTION;

BEGIN DIALOG @InitDlgHandle

FROM SERVICE [//InstDB/2InstSample/InitiatorService]

TO SERVICE N'//TgtDB/2InstSample/TargetService'

ON CONTRACT [//BothDB/2InstSample/SimpleContract]

WITH

ENCRYPTION = ON;

SELECT @RequestMsg = '<RequestMsg>test1:测试数据库未加入集群时,SSB是否配置成功</RequestMsg>';

SEND ON CONVERSATION @InitDlgHandle

MESSAGE TYPE [//BothDB/2InstSample/RequestMessage]

(@RequestMsg);

SELECT @RequestMsg AS SentRequestMsg;

COMMIT TRANSACTION;

select conversation_handle,state_desc,* from sys.conversation_endpoints--查看当前数据库中开启的会话

select conversation_handle,cast(message_body as xml),* from [dbo].[InstTargetQueue]--查看队列中的消息

select transmission_status,cast(message_body as xml),* from sys.transmission_queue --查看当期数据库中待传送的消息

STEP9. 配置成功后,发送消息的数据库InstInitiatorDB和接收消息的数据库InstTargetDB都加入集群

加入集群的步骤,此处省略

加入集群的步骤,此处省略

STEP10. 在副本服务器的Master数据库上建立端点(副本服务器上执行)

注意:执行前请检查当前服务器中,该端点名称是否是正在使用的端点,如果是请重新命名

USE master;

GO

IF EXISTS (SELECT * FROM sys.endpoints

WHERE name = N'InstInitiatorEndpoint')

DROP ENDPOINT InstInitiatorEndpoint;

GO

CREATE ENDPOINT InstInitiatorEndpoint

STATE = STARTED

AS TCP ( LISTENER_PORT = 4022, LISTENER_IP = ALL  )

FOR SERVICE_BROKER (AUTHENTICATION = WINDOWS );

GO

USE master;

GO

IF EXISTS (SELECT * FROM master.sys.endpoints

WHERE name = N'InstTargetEndpoint')

DROP ENDPOINT InstTargetEndpoint;

GO

CREATE ENDPOINT InstTargetEndpoint

STATE = STARTED

AS TCP ( LISTENER_PORT = 4022,LISTENER_IP = ALL )

FOR SERVICE_BROKER (AUTHENTICATION = WINDOWS );

GO

STEP11. 在副本服务器的msdb数据库上建立路由(副本服务器上执行)

DECLARE @Cmd NVARCHAR(4000);

SET @Cmd = N'USE msdb

CREATE ROUTE InstInitiatorRoute

WITH SERVICE_NAME =       N''//InstDB/2InstSample/InitiatorService'',

ADDRESS = N''LOCAL''';

EXEC (@Cmd);

GO

DECLARE @Cmd NVARCHAR(4000);

SET @Cmd = N'USE msdb

CREATE ROUTE InstTargetRoute

WITH SERVICE_NAME =        N''//TgtDB/2InstSample/TargetService'',

ADDRESS = N''LOCAL''';

EXEC (@Cmd);

GO

STEP12. 备份发送方主本服务器的service master key(发送主本服务器上执行)

所有副本服务器必须使用统一的服务主密钥

USE master;

GO

BACKUP SERVICE MASTER KEY TO FILE = '\\172.20.168.56\Document\SSB\mike\serviceMasterKey_node1'

ENCRYPTION BY PASSWORD = 'PasswordA3070814'

STEP13. 把发送方主本服务器的service master key restore到所有的副本服务器上(副本服务器上执行)

USE master;

GO

RESTORE SERVICE MASTER KEY FROM FILE = '\\172.20.168.56\Document\SSB\mike\serviceMasterKey_node1'

DECRYPTION BY PASSWORD = 'PasswordA3070814'

USE master;

GO

RESTORE SERVICE MASTER KEY FROM FILE = '\\172.20.168.56\Document\SSB\mike\serviceMasterKey_node1'

DECRYPTION BY PASSWORD = 'PasswordA3070814'

STEP14. 配置成功,开启会话发送消息。先运行左边发送消息,再运行右边接收消息并发送答复的消息(通过侦听地址登陆执行)

USE InstInitiatorDB;

GO

--启动会话并发送消息

DECLARE @InitDlgHandle UNIQUEIDENTIFIER;

DECLARE @RequestMsg NVARCHAR(100);

BEGIN TRANSACTION;

BEGIN DIALOG @InitDlgHandle

FROM SERVICE [//InstDB/2InstSample/InitiatorService]

TO SERVICE N'//TgtDB/2InstSample/TargetService'

ON CONTRACT [//BothDB/2InstSample/SimpleContract]

WITH

ENCRYPTION = ON;

SELECT @RequestMsg = '<RequestMsg>test2:数据库加入集群,手动故障转移,消息发送成功</RequestMsg>';

SEND ON CONVERSATION @InitDlgHandle

MESSAGE TYPE [//BothDB/2InstSample/RequestMessage]

(@RequestMsg);

SELECT @RequestMsg AS SentRequestMsg;

COMMIT TRANSACTION;

GO

USE InstTargetDB;

GO

--接收消息并发送答复

DECLARE @RecvReqDlgHandle UNIQUEIDENTIFIER;

DECLARE @RecvReqMsg NVARCHAR(100);

DECLARE @RecvReqMsgName sysname;

BEGIN TRANSACTION;

WAITFOR

( RECEIVE TOP(1)

@RecvReqDlgHandle = conversation_handle,

@RecvReqMsg = message_body,

@RecvReqMsgName = message_type_name

FROM InstTargetQueue

), TIMEOUT 1000;

SELECT @RecvReqMsg AS ReceivedRequestMsg;

IF @RecvReqMsgName = N'//BothDB/2InstSample/RequestMessage'

BEGIN

DECLARE @ReplyMsg NVARCHAR(100);

SELECT @ReplyMsg =

N'<ReplyMsg>消息接收成功!</ReplyMsg>';

SEND ON CONVERSATION @RecvReqDlgHandle

MESSAGE TYPE [//BothDB/2InstSample/ReplyMessage]

(@ReplyMsg);

END CONVERSATION @RecvReqDlgHandle;

END

SELECT @ReplyMsg AS SentReplyMsg;

COMMIT TRANSACTION;

GO

STEP15. 接收答复并结束会话(侦听地址)

注意:队列上可以绑定存储过程,并自动触发存储过程,完成自动处理消息。

USE InstInitiatorDB;

GO

--接收答复并结束会话

DECLARE @RecvReplyMsg NVARCHAR(100);

DECLARE @RecvReplyDlgHandle UNIQUEIDENTIFIER;

BEGIN TRANSACTION;

WAITFOR

( RECEIVE TOP(1)

@RecvReplyDlgHandle = conversation_handle,

@RecvReplyMsg = message_body

FROM InstInitiatorQueue

), TIMEOUT 1000;

END CONVERSATION @RecvReplyDlgHandle;

-- Display recieved request.

SELECT @RecvReplyMsg AS ReceivedReplyMsg;

COMMIT TRANSACTION;

GO

常见的基本操作语句:

select conversation_handle,state_desc,* from sys.conversation_endpoints--查看当前数据库中开启的会话

select conversation_handle,cast(message_body as xml),* from [dbo].[InstInitiatorQueue]--查看队列中的消息

select transmission_status,cast(message_body as xml),* from sys.transmission_queue --查看当期数据库中待传送的消息

select transmission_status,message_body,* from sys.transmission_queue --查看当期数据库中待传送的消息

end conversation  '05D1BC83-F31E-E511-80B6-6EAE8B208F71' with cleanup --根据会话端点ID结束会话

--==批量结束会话脚本

declare @conversation uniqueidentifier

declare handle cursor for select conversation_handle from sys.conversation_endpoints--查看当前数据库中开启的会话

open handle

fetch next from handle into @conversation

while(@@fetch_status = 0)

begin

end conversation  @conversation with cleanup

fetch next from handle into @conversation

end

close handle

deallocate handle

--==

代码:

USE master;
GO
BACKUP SERVICE MASTER KEY TO FILE = '\\172.20.168.56\Document\SSB\mike\serviceMasterKey_node1'
ENCRYPTION BY PASSWORD = 'Password1' --step1
USE master;
GO
IF EXISTS (SELECT * FROM sys.endpoints
WHERE name = N'InstInitiatorEndpoint')
DROP ENDPOINT InstInitiatorEndpoint;
GO
CREATE ENDPOINT InstInitiatorEndpoint
STATE = STARTED
AS TCP ( LISTENER_PORT = 4022 )
FOR SERVICE_BROKER (AUTHENTICATION = WINDOWS );
GO
-------------------------------------------------
--step2
USE master;
GO
IF EXISTS (SELECT * FROM sys.databases
WHERE name = N'InstInitiatorDB')
DROP DATABASE InstInitiatorDB;
GO
CREATE DATABASE InstInitiatorDB;
GO
USE InstInitiatorDB;
GO CREATE MASTER KEY
ENCRYPTION BY PASSWORD = N'MyPassword01!';
GO
CREATE USER InitiatorUser WITHOUT LOGIN;
GO
---------------------------------------------------
--step3
USE InstInitiatorDB;
GO
CREATE CERTIFICATE InstInitiatorCertificate
AUTHORIZATION InitiatorUser
WITH SUBJECT = N'Initiator Certificate',
EXPIRY_DATE = N'12/31/2090'; BACKUP CERTIFICATE InstInitiatorCertificate
TO FILE =
N'\\172.20.168.56\Document\SSB\mike\InstInitiatorCertificate2.cer';
GO
-----------------------------------------------------
--step4
USE InstInitiatorDB;
GO
CREATE MESSAGE TYPE [//BothDB/2InstSample/RequestMessage]
VALIDATION = WELL_FORMED_XML;
CREATE MESSAGE TYPE [//BothDB/2InstSample/ReplyMessage]
VALIDATION = WELL_FORMED_XML;
GO
CREATE CONTRACT [//BothDB/2InstSample/SimpleContract]
([//BothDB/2InstSample/RequestMessage]
SENT BY INITIATOR,
[//BothDB/2InstSample/ReplyMessage]
SENT BY TARGET
);
GO
-------------------------------------------------------
--step5
USE InstInitiatorDB;
GO
CREATE QUEUE InstInitiatorQueue;
CREATE SERVICE [//InstDB/2InstSample/InitiatorService]
AUTHORIZATION InitiatorUser
ON QUEUE InstInitiatorQueue ([//BothDB/2InstSample/SimpleContract]); GO
-------------------------------------------------------
--step6
USE InstInitiatorDB;
GO
CREATE USER TargetUser WITHOUT LOGIN;
CREATE CERTIFICATE InstTargetCertificate
AUTHORIZATION TargetUser
FROM FILE =
N'\\172.20.168.56\Document\SSB\mike\InstTargetCertificate2.cer'
GO
----------------------------------------------------
--step7
DECLARE @Cmd NVARCHAR(4000);
SET @Cmd = N'USE InstInitiatorDB;
CREATE ROUTE InstTargetRoute
WITH SERVICE_NAME = N''//TgtDB/2InstSample/TargetService'',
ADDRESS = ''TCP://172.20.168.235:4022'';';
EXEC (@Cmd);
SET @Cmd = N'USE msdb
CREATE ROUTE InstInitiatorRoute
WITH SERVICE_NAME = N''//InstDB/2InstSample/InitiatorService'',
ADDRESS = N''LOCAL''';
EXEC (@Cmd);
GO CREATE REMOTE SERVICE BINDING TargetBinding
TO SERVICE N'//TgtDB/2InstSample/TargetService'
WITH USER = TargetUser; GO
------------------------------------------------------------
--step8
USE InstInitiatorDB;
GO
--启动会话并发送消息
DECLARE @InitDlgHandle UNIQUEIDENTIFIER;
DECLARE @RequestMsg NVARCHAR(100);
BEGIN TRANSACTION;
BEGIN DIALOG @InitDlgHandle
FROM SERVICE [//InstDB/2InstSample/InitiatorService]
TO SERVICE N'//TgtDB/2InstSample/TargetService'
ON CONTRACT [//BothDB/2InstSample/SimpleContract]
WITH
ENCRYPTION = ON;
SELECT @RequestMsg = '<RequestMsg>test2:数据库加入集群,手动故障转移,消息发送成功</RequestMsg>';
SEND ON CONVERSATION @InitDlgHandle
MESSAGE TYPE [//BothDB/2InstSample/RequestMessage]
(@RequestMsg);
SELECT @RequestMsg AS SentRequestMsg;
COMMIT TRANSACTION; GO
------------------------------------
select conversation_handle,state_desc,* from sys.conversation_endpoints--查看当前数据库中开启的会话
select conversation_handle,cast(message_body as xml),* from [dbo].[InstInitiatorQueue]--查看队列中的消息
select transmission_status,cast(message_body as xml),* from sys.transmission_queue --查看当期数据库中待传送的消息
select transmission_status,message_body,* from sys.transmission_queue --查看当期数据库中待传送的消息
end conversation '05D1BC83-F31E-E511-80B6-6EAE8B208F71' with cleanup --根据会话端点ID结束会话 --==批量结束会话脚本
declare @conversation uniqueidentifier
declare handle cursor for select conversation_handle from sys.conversation_endpoints--查看当前数据库中开启的会话
open handle
fetch next from handle into @conversation
while(@@fetch_status = 0)
begin
end conversation @conversation with cleanup
fetch next from handle into @conversation
end
close handle
deallocate handle
--===

发送方CQECDB2(主本)

--step1
USE master;
GO
IF EXISTS (SELECT * FROM master.sys.endpoints
WHERE name = N'InstTargetEndpoint')
DROP ENDPOINT InstTargetEndpoint;
GO
CREATE ENDPOINT InstTargetEndpoint
STATE = STARTED
AS TCP ( LISTENER_PORT = 4022 )
FOR SERVICE_BROKER (AUTHENTICATION = WINDOWS );
GO
-------------------------------------------------
--step2
USE master;
GO
IF EXISTS (SELECT * FROM sys.databases
WHERE name = N'InstTargetDB')
DROP DATABASE InstTargetDB;
GO
CREATE DATABASE InstTargetDB;
GO
USE InstTargetDB;
GO
CREATE MASTER KEY
ENCRYPTION BY PASSWORD = N'Mypassword01!';
GO
CREATE USER TargetUser WITHOUT LOGIN;
GO
-----------------------------------------------------
--step3
USE InstTargetDB;
GO
CREATE CERTIFICATE InstTargetCertificate
AUTHORIZATION TargetUser
WITH SUBJECT = 'Target Certificate',
EXPIRY_DATE = N'12/31/2090'; BACKUP CERTIFICATE InstTargetCertificate
TO FILE =
N'\\172.20.168.56\Document\SSB\mike\InstTargetCertificate2.cer';
GO ------------------------------------------------------
--step4
USE InstTargetDB;
GO
CREATE MESSAGE TYPE [//BothDB/2InstSample/RequestMessage]
VALIDATION = WELL_FORMED_XML;
CREATE MESSAGE TYPE [//BothDB/2InstSample/ReplyMessage]
VALIDATION = WELL_FORMED_XML;
GO
CREATE CONTRACT [//BothDB/2InstSample/SimpleContract]
([//BothDB/2InstSample/RequestMessage]
SENT BY INITIATOR,
[//BothDB/2InstSample/ReplyMessage]
SENT BY TARGET
);
GO
----------------------------------------------------
--step5
USE InstTargetDB;
GO
CREATE QUEUE InstTargetQueue;
CREATE SERVICE [//TgtDB/2InstSample/TargetService]
AUTHORIZATION TargetUser
ON QUEUE InstTargetQueue ([//BothDB/2InstSample/SimpleContract]);
GO
------------------------------------------------------
--step6
USE InstTargetDB
GO
CREATE USER InitiatorUser WITHOUT LOGIN;
CREATE CERTIFICATE InstInitiatorCertificate
AUTHORIZATION InitiatorUser
FROM FILE =
N'\\172.20.168.56\Document\SSB\mike\InstInitiatorCertificate2.cer';
GO -------------------------------------------------------
--step7
DECLARE @Cmd NVARCHAR(4000);
SET @Cmd = N'USE InstTargetDB;
CREATE ROUTE InstInitiatorRoute
WITH SERVICE_NAME = N''//InstDB/2InstSample/InitiatorService'',
ADDRESS = ''TCP://10.17.30.46:4022'';';
EXEC (@Cmd);
SET @Cmd = N'USE msdb
CREATE ROUTE InstTargetRoute
WITH SERVICE_NAME = N''//TgtDB/2InstSample/TargetService'',
ADDRESS = N''LOCAL''';
EXEC (@Cmd);
GO
GRANT SEND ON SERVICE::[//TgtDB/2InstSample/TargetService]
TO InitiatorUser;
GO CREATE REMOTE SERVICE BINDING InitiatorBinding
TO SERVICE N'//InstDB/2InstSample/InitiatorService'
WITH USER = InitiatorUser;
GO
------------------------------------------------------
--step8:
USE InstTargetDB;
GO
--接收请求并发送答复
DECLARE @RecvReqDlgHandle UNIQUEIDENTIFIER;
DECLARE @RecvReqMsg NVARCHAR(100);
DECLARE @RecvReqMsgName sysname;
BEGIN TRANSACTION;
WAITFOR
( RECEIVE TOP(1)
@RecvReqDlgHandle = conversation_handle,
@RecvReqMsg = message_body,
@RecvReqMsgName = message_type_name
FROM InstTargetQueue
), TIMEOUT 1000;
SELECT @RecvReqMsg AS ReceivedRequestMsg;
IF @RecvReqMsgName = N'//BothDB/2InstSample/RequestMessage'
BEGIN
DECLARE @ReplyMsg NVARCHAR(100);
SELECT @ReplyMsg =
N'<ReplyMsg>Message for Initiator service.</ReplyMsg>';
SEND ON CONVERSATION @RecvReqDlgHandle
MESSAGE TYPE [//BothDB/2InstSample/ReplyMessage]
(@ReplyMsg);
END CONVERSATION @RecvReqDlgHandle;
END
SELECT @ReplyMsg AS SentReplyMsg;
COMMIT TRANSACTION;
GO
----------------------------------------------------- select conversation_handle,state_desc,* from sys.conversation_endpoints--查看当前数据库中开启的会话
select conversation_handle,cast(message_body as xml),* from [dbo].[InstTargetQueue]--查看队列中的消息
select transmission_status,cast(message_body as xml),* from sys.transmission_queue --查看当期数据库中待传送的消息 --==批量结束会话脚本
declare @conversation uniqueidentifier
declare handle cursor for select conversation_handle from sys.conversation_endpoints--查看当前数据库中开启的会话
open handle
fetch next from handle into @conversation
while(@@fetch_status = 0)
begin
end conversation @conversation with cleanup
fetch next from handle into @conversation
end
close handle
deallocate handle
--===

接收方scmdb16(主本)

--step1
USE master;
GO
IF EXISTS (SELECT * FROM sys.endpoints
WHERE name = N'InstInitiatorEndpoint')
DROP ENDPOINT InstInitiatorEndpoint;
GO
CREATE ENDPOINT InstInitiatorEndpoint
STATE = STARTED
AS TCP ( LISTENER_PORT = 4022, LISTENER_IP = ALL )
FOR SERVICE_BROKER (AUTHENTICATION = WINDOWS );
GO
----------------------------------------
--step2 建立msdb route DECLARE @Cmd NVARCHAR(4000);
SET @Cmd = N'USE msdb
CREATE ROUTE InstInitiatorRoute
WITH SERVICE_NAME =
N''//InstDB/2InstSample/InitiatorService'',
ADDRESS = N''LOCAL''';
EXEC (@Cmd);
GO
---------------------------------------------------
USE master;
GO
RESTORE SERVICE MASTER KEY FROM FILE = '\\172.20.168.56\Document\SSB\mike\serviceMasterKey_node1'
DECRYPTION BY PASSWORD = 'Password1' 消息 15320,级别 16,状态 12,第 1 行
对使用旧主密钥加密的 主密钥 'QWMS_Interface'进行解密时出错。可以使用 FORCE 选项忽略此错误并继续此操作,但使用该旧主密钥无法解密的数据将变得不可用。 --发送方第一次故障转移:
The session keys for this conversation could not be created or accessed. The database master key is required for this operation.
--故障转移回来,

发送方CQECDB3(副本)

USE master;
GO
IF EXISTS (SELECT * FROM master.sys.endpoints
WHERE name = N'InstTargetEndpoint')
DROP ENDPOINT InstTargetEndpoint;
GO
CREATE ENDPOINT InstTargetEndpoint
STATE = STARTED
AS TCP ( LISTENER_PORT = 4022,LISTENER_IP = ALL )
FOR SERVICE_BROKER (AUTHENTICATION = WINDOWS );
GO
-----------------------------------------
--step2 建立msdb route DECLARE @Cmd NVARCHAR(4000);
SET @Cmd = N'USE msdb
CREATE ROUTE InstTargetRoute
WITH SERVICE_NAME =
N''//TgtDB/2InstSample/TargetService'',
ADDRESS = N''LOCAL''';
EXEC (@Cmd);
GO
----------------------------------
USE master;
GO
RESTORE SERVICE MASTER KEY FROM FILE = '\\172.20.168.56\Document\SSB\mike\serviceMasterKey_node1'
DECRYPTION BY PASSWORD = 'Password1'
go 新旧主密钥完全相同。不需要重新加密数据。
--------------------------------------
select conversation_handle,state_desc,* from sys.conversation_endpoints--查看当前数据库中开启的会话
select conversation_handle,cast(message_body as xml),* from [dbo].[InstTargetQueue]--查看队列中的消息
select transmission_status,cast(message_body as xml),* from sys.transmission_queue --查看当期数据库中待传送的消息

接收方scmdb10(副本)

Service Broker应用(2):不同server间的数据传输,包含集群的更多相关文章

  1. SQL Server上唯一的数据库集群:负载均衡、读写分离、容灾(数据零丢失、服务高可用)

    SQL Server上唯一的数据库集群:负载均衡.读写分离.容灾(数据零丢失.服务高可用).审计.优化,全面解决数据库用户问题.一键安装,易用稳定,性价比高,下载链接:http://www.zheti ...

  2. SQL Server 2016 + AlwaysOn 无域集群

    目录 AlwaysOn 搭建 WSFC 配置计算机的 DNS 后缀 安装故障转移集群 验证集群 创建集群 创建文件共享见证 配置 AlwaysOn 新建可用性组 创建侦听器 可读副本的负载均衡 主角色 ...

  3. SQL SERVER 2016 AlwaysOn 无域集群+负载均衡搭建与简测

    之前和很多群友聊天发现对2016的无域和负载均衡满心期待,毕竟可以简单搭建而且可以不适用第三方负载均衡器,SQL自己可以负载了.windows2016已经可以下载使用了,那么这回终于可以揭开令人憧憬向 ...

  4. 将Sql Server迁移到Always on集群 - 账号的同步

    Always on环境的建立,网上资料很多,主要是windows集群的建立以及Sql Server Always on的建立,略 容易忽略的是Sql server账号同步问题(Always on能实现 ...

  5. Arcgis Server 10.4.1 搭建集群环境

    1.准备工作 Arcgis Server 10.4.1  以及许可一枚 共享存储(通过UNC路径访问,如"\\server1\arcgisserver\") 服务器两台(虚拟机也可 ...

  6. MongoDB 集群 config server 查询超时导致 mongos 集群写入失败

    环境 OS:CentOS 7.x DB:MongoDB 3.6.12 集群模式:mongod-shard1 *3 + mongod-shard2 *3 + mongod-conf-shard *3 + ...

  7. spring-cloud:eureka server单机、双机、集群示例

    1.运行环境 开发工具:intellij idea JDK版本:1.8 项目管理工具:Maven 4.0.0 2.GITHUB地址 https://github.com/nbfujx/springCl ...

  8. 基于SQL Server 2008 Service Broker构建企业级消息系统

    注:这篇文章是为InfoQ 中文站而写,文章的地址是:http://www.infoq.com/cn/articles/enterprisemessage-sqlserver-servicebroke ...

  9. 在Windows Server 2008 R2 Server中,连接其他服务器的数据库遇到“未启用当前数据库的 SQL Server Service Broker,因此查询通知不受支持。如果希望使用通知,请为此数据库启用 Service Broker ”

    项目代码和数据库部署在不同的Windows Server 2008 R2 Server中,错误日志显示如下: "未启用当前数据库的 SQL Server Service Broker,因此查 ...

随机推荐

  1. python走起之第十五话

    CSS Positioning(定位) 定位有时很棘手! 决定显示在前面的元素! 元素可以重叠! Positioning(定位) CSS定位属性允许你为一个元素定位.它也可以将一个元素放在另一个元素后 ...

  2. 详解 $_SERVER 函数中QUERY_STRING和REQUEST_URI区别(转)

    对于php$_SERVER这个全局变量 ,里面有很多的参数,慢慢的熟悉 1,http://localhost/aaa/ (打开aaa中的index.php)结果:$_SERVER['QUERY_STR ...

  3. 参考__CSS参考

    库 CsshakeAnimate.css

  4. Spring IOC/DI- 3 different types

    理论: IOC(Inversion of Control控制反转) DI(依赖注入) (Dependency Injection)   它不是一种技术而是一种思想.当初IOC理论的提出就是为了解决对象 ...

  5. 建站随手记:about server stack

    建站需要,随手记: Server Stack: ----------- 标准的mezzanine的Stack设置 前端:Nginx wsgi:gunicorn cms tool: mezzanine ...

  6. VC比例放大缩小

    CRect rect; ::GetWindowRect(m_hWnd, rect); ScreenToClient(rect); m_nDlgWidth = rect.right - rect.lef ...

  7. 关闭显示器API及命令

    window下命令powercfg /change "Home/Office Desk" /moniter-timeout-ac 1C#中实现[DllImportAttribute ...

  8. WDA导出文件XLS,WORD

    METHOD ONACTIONEXCEL . DATA: LO_NODE TYPE REF TO IF_WD_CONTEXT_NODE, "Node LO_ELEM TYPE REF TO ...

  9. 20169212《Linux内核原理与分析》第五周作业

    关于linux内核源码 两个很关键的目录,一个是arch(architecture),支持不同cpu体系架构的源代码,其中最重要的就是x86(一般把x86留下,其他的目录删掉),另一个是init(其中 ...

  10. PHP xml 转换为 array

    retrun json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), tru ...