Service Broker应用(2):不同server间的数据传输,包含集群
不同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间的数据传输,包含集群的更多相关文章
- SQL Server上唯一的数据库集群:负载均衡、读写分离、容灾(数据零丢失、服务高可用)
SQL Server上唯一的数据库集群:负载均衡.读写分离.容灾(数据零丢失.服务高可用).审计.优化,全面解决数据库用户问题.一键安装,易用稳定,性价比高,下载链接:http://www.zheti ...
- SQL Server 2016 + AlwaysOn 无域集群
目录 AlwaysOn 搭建 WSFC 配置计算机的 DNS 后缀 安装故障转移集群 验证集群 创建集群 创建文件共享见证 配置 AlwaysOn 新建可用性组 创建侦听器 可读副本的负载均衡 主角色 ...
- SQL SERVER 2016 AlwaysOn 无域集群+负载均衡搭建与简测
之前和很多群友聊天发现对2016的无域和负载均衡满心期待,毕竟可以简单搭建而且可以不适用第三方负载均衡器,SQL自己可以负载了.windows2016已经可以下载使用了,那么这回终于可以揭开令人憧憬向 ...
- 将Sql Server迁移到Always on集群 - 账号的同步
Always on环境的建立,网上资料很多,主要是windows集群的建立以及Sql Server Always on的建立,略 容易忽略的是Sql server账号同步问题(Always on能实现 ...
- Arcgis Server 10.4.1 搭建集群环境
1.准备工作 Arcgis Server 10.4.1 以及许可一枚 共享存储(通过UNC路径访问,如"\\server1\arcgisserver\") 服务器两台(虚拟机也可 ...
- MongoDB 集群 config server 查询超时导致 mongos 集群写入失败
环境 OS:CentOS 7.x DB:MongoDB 3.6.12 集群模式:mongod-shard1 *3 + mongod-shard2 *3 + mongod-conf-shard *3 + ...
- spring-cloud:eureka server单机、双机、集群示例
1.运行环境 开发工具:intellij idea JDK版本:1.8 项目管理工具:Maven 4.0.0 2.GITHUB地址 https://github.com/nbfujx/springCl ...
- 基于SQL Server 2008 Service Broker构建企业级消息系统
注:这篇文章是为InfoQ 中文站而写,文章的地址是:http://www.infoq.com/cn/articles/enterprisemessage-sqlserver-servicebroke ...
- 在Windows Server 2008 R2 Server中,连接其他服务器的数据库遇到“未启用当前数据库的 SQL Server Service Broker,因此查询通知不受支持。如果希望使用通知,请为此数据库启用 Service Broker ”
项目代码和数据库部署在不同的Windows Server 2008 R2 Server中,错误日志显示如下: "未启用当前数据库的 SQL Server Service Broker,因此查 ...
随机推荐
- 移动端页面 弹出框滚动,底部body锁定,不滚动 / 微信网页禁止回弹效果
需求:页面有弹出层菜单,当弹出层菜单超出屏幕可视区域时,不能滚动.加上滚动后,底部body的滚动事件如何禁止,加上了overflow:hidden;还是不可用. 如下图:地区弹出框可以滚动,而底部的b ...
- Qt编程'""hello world
#include<QApplication>#include<QLabel>int main(int argc,char*argv[]){QApplicatin app(arg ...
- laravel select 传参
传值: $params['select'] = 'taobao_id,title,image,price,coupon_deduct,coupon_condition'; 接受参数 $result = ...
- 解决hibernate删除时的异常
由于关联关系是一对多和多对一的关系,于是在代码中需要删除多的一方的对象时出现了 deleted object would be re-saved by cascade (remove deleted ...
- 解决首次访问jenkins,输入默认密码之后,一直卡住问题
简介 安装系统:centos6.5 安装方式:在官网中下载jenkins.war,放到tomcat根目录下的webapps中,启动tomcat(还有一种yum在线安装的方式) 1.首次访问,出现如 ...
- 【转】Python 日期和时间
本文转自:http://www.runoob.com/python/python-date-time.html Python 程序能用很多方式处理日期和时间,转换日期格式是一个常见的功能. Pytho ...
- Linux启动盘-ultraiso
感觉windos和linux安装系统的启动盘不一样 其实我也不太懂. windos的时候我是用老毛桃 然后安装linux我就选择了ultraios作为启动盘 一: 先在百度下载 ultraios 二 ...
- JAVA GUI布局管理器
边界布局管理器: a.布局方式:是把整个容器划分为五个部分.东西南北中,南北要贯通,中间最大 (不仅是中间的范围最大,权利也最大)当周边不存在的时候中间会占领周边,当中间不存在的时候周边不能占据中间 ...
- springMVC拦截器和过滤器总结
拦截器: 用来对访问的url进行拦截处理 用处: 权限验证,乱码设置等 spring-mvc.xml文件中的配置: <beans xmlns="http://www.springfra ...
- 我需要在Web上完成一个图片上传的功能
我需要在Web上完成一个图片上传的功能. 这个页面需要能从手机中选择图片上传. 首先,这个页面是从微信上面触发的,所以修改了微信的的入口地址,增加了身份识别号作为传参. 跳转到页面的时候,页面先检查身 ...