Service Broker完成实例之间的会话详细解读
首先了解service broker是什么东西:
Service Broker 为 SQL Server 提供队列和可靠的消息传递。Service Broker 既可用于使用单个 SQL Server 实例的应用程序,也可用于在多个实例间分发工作的应用程序。(在单个 SQL Server 实例内,Service Broker 提供了一个功能强大的异步编程模型。数据库应用程序通常使用异步编程来缩短交互式响应时间,并增加应用程序总吞吐量)
broker具备的基本要素:message type,contract,queue,service(少数还需要存储,路由,证书,账号等支持才可以完成整个传输)
关于实例间传输时候密钥的理解:
假设有A,B,C三人,这三个人每个人都有自己的证书,并且将自己的密钥备份出公钥部分,这样的话其他两个人都会有自己的公钥,而私钥却不能够导出,只能够自己拥有。当需要传输消息的时候,A---->B:此时此刻,A有自己的私钥与B的公钥,同理B也有自己的私钥与A的公钥,当A传输信息给B的时候,先将信息通过B的公钥加密,加密后传送给B,而此时此刻,加密的信息只有B的私钥才可以解码,所以是绝对安全的。同理,当B--->A的时候,也是同样的道理
关于队列的理解:
队列就是有头有尾,从尾部插入,从头部读出,期间的顺序是不可以调动的,只能够按照顺序区读取。两方的队列queue都具有收发功能,并且可以很快的处理,因为在传输过程中有一个队列transmission_queue来存储传输过程的信息。
关于证书账户理解:
所谓的证书虽然可以认证,但是是必须要绑定一个用户的,就是证书在创建之初必须绑定赋予一个用户(with no login),绑定用户才可以给予相关的权限。
1:创建目标数据库
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 = ) FOR SERVICE_BROKER (AUTHENTICATION = WINDOWS ); 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'';
GO
CREATE USER TargetUser WITHOUT LOGIN;
GO
CREATE CERTIFICATE InstTargetCertificate
AUTHORIZATION TargetUser WITH SUBJECT = 'Target Certificate', EXPIRY_DATE = N'12/31/2010'; BACKUP CERTIFICATE InstTargetCertificate TO FILE =N'C:\storedcerts\$ampleSSBCerts\InstTargetCertificate.cer';
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
创建约定也是必须的
CREATE QUEUE InstTargetQueue; CREATE SERVICE [//TgtDB/2InstSample/TargetService] AUTHORIZATION TargetUser ON QUEUE InstTargetQueue ([//BothDB/2InstSample/SimpleContract]); GO
创建目标队列以及服务,这个也是必须的,毋庸置疑啊。
2:创建发起方数据库
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 = ) FOR SERVICE_BROKER (AUTHENTICATION = WINDOWS ); GO
同理先创建一个端点
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'';
GO
CREATE USER InitiatorUser WITHOUT LOGIN;
GO
(发起方数据库,主密钥以及用户)
CREATE CERTIFICATE InstInitiatorCertificate AUTHORIZATION InitiatorUser WITH SUBJECT = N'Initiator Certificate', EXPIRY_DATE = N'12/31/2010';
BACKUP CERTIFICATE InstInitiatorCertificate TO FILE = N'C:\storedcerts\$ampleSSBCerts\InstInitiatorCertificate.cer'; 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
CREATE QUEUE InstInitiatorQueue;
CREATE SERVICE [//InstDB/2InstSample/InitiatorService] AUTHORIZATION InitiatorUser ON QUEUE InstInitiatorQueue;
GO
(创建消息类型,约定,队列以及数据库service)
CREATE USER TargetUser WITHOUT LOGIN;
CREATE CERTIFICATE InstTargetCertificate AUTHORIZATION TargetUser FROM FILE = N'C:\storedcerts\$ampleSSBCerts\InstTargetCertificate.cer' GO
(对目标对象的引用,此处这个证书的路径就是我们第一次备份出来的那个证书,我们将他拷贝出来到现在的主机上面路径,这样我们就可以拥有目标数据库的公钥,可以加密传输给另一台主机的消息,注意这里创建用户的名字是和我们要使用的证书公钥绑定的用户的名字是一致的,这样才可以进行加解密传输)
DECLARE @Cmd NVARCHAR();
SET @Cmd = N'USE InstInitiatorDB; CREATE ROUTE InstTargetRoute WITH SERVICE_NAME = N''//TgtDB/2InstSample/TargetService'', ADDRESS = N''TCP://MyTargetComputer: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
(创建路由,此处我们要注意的就是红色部分,我们可以使用主机名字或者主机IP都是可以的)
3:完成目标会话对象
USE InstTargetDB GO
CREATE USER InitiatorUser WITHOUT LOGIN;
CREATE CERTIFICATE InstInitiatorCertificate AUTHORIZATION InitiatorUser FROM FILE = N'C:\storedcerts\$ampleSSBCerts\InstInitiatorCertificate.cer';
GO
(创建引用,这个你懂得)
DECLARE @Cmd NVARCHAR();
SET @Cmd = N'USE InstTargetDB; CREATE ROUTE InstInitiatorRoute WITH SERVICE_NAME = N''//InstDB/2InstSample/InitiatorService'', ADDRESS = N''TCP://MyInitiatorComputer: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
(创建路由协议,与发起方创建的是一样一样的)
4:启动会话
USE InstInitiatorDB; GO
DECLARE @InitDlgHandle UNIQUEIDENTIFIER;
DECLARE @RequestMsg NVARCHAR();
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 = N'Message for Target service.';
SEND ON CONVERSATION @InitDlgHandle MESSAGE TYPE [//BothDB/2InstSample/RequestMessage] (@RequestMsg);
SELECT @RequestMsg AS SentRequestMsg;
COMMIT TRANSACTION;
GO
(直接运行就可以)
5:接受请求并且发送答复
USE InstTargetDB;
GO
DECLARE @RecvReqDlgHandle UNIQUEIDENTIFIER;
DECLARE @RecvReqMsg NVARCHAR();
DECLARE @RecvReqMsgName sysname;
BEGIN TRANSACTION;
WAITFOR ( RECEIVE TOP() @RecvReqDlgHandle = conversation_handle, @RecvReqMsg = message_body, @RecvReqMsgName = message_type_name FROM InstTargetQueue ), TIMEOUT ;
SELECT @RecvReqMsg AS ReceivedRequestMsg;
IF @RecvReqMsgName = N'//BothDB/2InstSample/RequestMessage'
BEGIN
DECLARE @ReplyMsg NVARCHAR();
SELECT @ReplyMsg = N'Message for Initiator service.';
SEND ON CONVERSATION @RecvReqDlgHandle MESSAGE TYPE [//BothDB/2InstSample/ReplyMessage] (@ReplyMsg);
END CONVERSATION @RecvReqDlgHandle;
END
SELECT @ReplyMsg AS SentReplyMsg;
COMMIT TRANSACTION;
GO
USE InstInitiatorDB;
GO
DECLARE @RecvReplyMsg NVARCHAR();
DECLARE @RecvReplyDlgHandle UNIQUEIDENTIFIER;
BEGIN TRANSACTION;
WAITFOR ( RECEIVE TOP() @RecvReplyDlgHandle = conversation_handle, @RecvReplyMsg = message_body FROM InstInitiatorQueue ), TIMEOUT ;
END CONVERSATION @RecvReplyDlgHandle;
-- Display recieved request.
Service Broker完成实例之间的会话详细解读的更多相关文章
- SQL Server Service Broker创建单个数据库会话
概述 SQL Server Service Broker 用来创建用于交换消息的会话.消息在目标和发起方这两个端点之间进行交换.消息用于传输数据和触发消息收到时的处理过程.目标和发起方既可以在同一数据 ...
- SQL Server Service Broker创建单个数据库会话(消息队列)
概述 SQL Server Service Broker 用来创建用于交换消息的会话.消息在目标和发起方这两个端点之间进行交换.消息用于传输数据和触发消息收到时的处理过程.目标和发起方既可以在同一数据 ...
- SQL Server Service Broker(简称SSB)资料
SQL server Service Broker (下面简称SSB) 是SQL server 里面比较独特的一个功能.它可帮助开发人员构建异步的松散耦合应用程序.SSB的一些功能和好处包括有: 数据 ...
- 未启用当前数据库的 SQL Server Service Broker,因此查询通知不受支持。如果希望使用通知,请为此数据库启用 Service Broker
昨晚遇到的这个问题,也知道Notifications service依赖底层的Service broker的.本以为只需要执行以下脚本对数据库启用Service broker即可. alter dat ...
- SQL问题:未启用当前数据库的 SQL Server Service Broker
数据库分离后,附加回到数据库,然后在程序中打开调用数据库的页面,出现如下问题:“未启用当前数据库的 SQL Server Service Broker,因此查询通知不受支持.如果希望使用通知,请为此数 ...
- 基于SQL Server 2008 Service Broker构建企业级消息系统
注:这篇文章是为InfoQ 中文站而写,文章的地址是:http://www.infoq.com/cn/articles/enterprisemessage-sqlserver-servicebroke ...
- Service Broker 概述
ServiceBroker(简称SSB)是基于数据库引擎提供的一个强大的异步编程模型,通过ServiceBroker,开发人员无需编写复杂的通信和消息程序,即可在数据库实例之间完成高效可靠的异步通信. ...
- Service Broker 消息队列的方式实现数据同步
SQL Server 2008中SQL应用系列--目录索引 导读:本文主要涉及Service Broker的基本概念及建立一个Service Broker应用程序的基本步骤. 一.前言: Servic ...
- Service Broker应用(2):不同server间的数据传输,包含集群
不同Server之间的数据传输,包含DB使用AlwaysOn 配置脚本: SQL Server Service Broker 跨集群通信 具体的TSQL 脚本语句如下.注意的是TSQL语句是在发送方还 ...
随机推荐
- python-sort()/sorted()比较
Sorting Lists sorted(iterable,key=None,reverse=False),does not mutate list, must assign result to a ...
- [转] Mysql命令基础
[From] http://c.biancheng.net/cpp/u/mysql_ml/ 连接Mysql数据库 mysql命令格式: mysql -h主机地址 -u用户名 -p用户密码 1) 连接到 ...
- Oracle列转行函数Listagg以及pivot查询示例
简单的Oracle列转行函数Listagg示例: CREATE TABLE tbl_test (catalog VARCHAR(1),product VARCHAR(2),amount NUMBER) ...
- python数据类型,格式话输出
一.程序交互 name = input(“你的名字是:”) #用户输入,输入的任何东西都存储成str(字符串类型)的形式 二.注释的重要性 以后动辄几千行代码的时候,回过头再去看的时候,发现自己都看不 ...
- 用jenkins编译WPF程序并传输到服务器
环境准备: 1.ide visual studio2017 Enterprise,Ide可以https://visualstudio.microsoft.com/zh-hans/downloads ...
- 2.5 Go错误处理
defer import "fmt" func testDefer(){ defer fmt.Println() defer fmt.Println() fmt.Println() ...
- ssh设置超时时间
修改server端的etc/ssh/sshd_config ClientAliveInterval 60 #server每隔60秒发送一次请求给client,然后client响应,从而保持连接 Cli ...
- pg存储过程和sql语句块
展E宝项目使用的是postgresql数据库,批量发送红包需求,需要采用存储过程来初始化红包记录数据. 创建存储过程语句有固定的架子,如下 CREATE OR REPLACE FUNCTION pub ...
- Java基础17-成员变量、return关键字和多参方法
1.成员变量 在类中声明的变量为成员变量 //Dog类 class Dog{ String name;//成员变量 } public class Test1{ public static void m ...
- TOJ 4523 Transportation
Description Given N stations, you want to carry goods from station 1 to station N. Among these stati ...