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语句是在发送方还 ...
随机推荐
- C++_IO与文件5-文件的输入与输出
大多数计算机程序都使用了文件.文件本身是存储在某种设备上的一系列字节. 通常,操作系统管理文件,跟踪它们的位置.大小.创建时间等. 除非在操作系统级别上编程,否则通常不必担心这些事情. 真正需要的是将 ...
- springboot(一):入门
什么是springboot Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不 ...
- [转] Scala 2.10.0 新特性之字符串插值
[From] https://unmi.cc/scala-2-10-0-feature-string-interpolation/ Scala 2.10.0 新特性之字符串插值 2013-01-20 ...
- Oracle分组函数之CUBE魅力
Oracle的CUBE与ROLLUP功能很相似,也是在数据统计分析领域的一把好手. 关于ROLLUP的查询统计功能请参考文章<Oracle分组函数之ROLLUP魅力>(http://www ...
- JENKINS安装及新建用户,权限配置
JENKINS安装及新建用户,权限配置 1. 下载安装 jenkins 官网地址https://jenkins.io/index.html 下载地址https://jenkins.io/downloa ...
- Python中.ini文件使用
.ini文件 一般用来配置常量或者数据库链接语句等,是纯文本格式,所以可以用纯文本编辑器来编辑其内容. ;文件格式如下 ;注释用分号开头,setion 节 [setion] key = value s ...
- Linux Jenkins
部署与运行: Jenkins 依赖于 Tomcat 才能跑起来,把 Jenkins 的 jenkins.war 文件放到 Tomcat 的安装目录的 webapps 目录下,配置好端口,正常访问 lo ...
- scala 列表的子集判断
val list1=List.range(0,5) val list2=List.range(0,2) val list3=List(0,6) list1.contains(2) list1.cont ...
- (转)CentOS/Linux 解决 SSH 连接慢
CentOS/Linux 解决 SSH 连接慢 原文:http://blog.csdn.net/doiido/article/details/43793391 现在连接linux服务器一般都是使用SS ...
- JAVA 中 if和while的区别
while和if本身就用法不同,一个是循环语句,一个是判断语句. if 只做判断,判断一次之后,便不会再回来了while 的话,循环,直到结果为false,才跳出来 链表的结构,要一直读下去,直到读完 ...