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语句是在发送方还 ...
随机推荐
- JAVA数据结构--选择排序
选择排序(Selection sort)是一种简单直观的排序算法.它的工作原理如下.首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然 ...
- setlocal enabledelayedexpansion 解释
看字面的意思是:设置本地为延迟扩展.其实也就是:延迟变量,全称"延迟环境变量扩展", 在cmd执行命令前会对脚本进行预处理,其中有一个过程是变量识别过程,在这个过程中,如果有两个% ...
- HTML嵌套php
1. <?php echo 'if you want to serve XHTML or XML documents, do it like this'; ?> 2. <scri ...
- [转] 运维小技巧:使用ss命令代替 netstat,和netstat说再见
[From] https://blog.csdn.net/fenglailea/article/details/51810977 ss是Socket Statistics的缩写. 顾名思义,ss命令可 ...
- js数组去重 javascript版
//js数组去重 //思路: // 1.放入第一个元素 // 2.放入第n个元素,和第n个之前的元素就行比较,如果有重复,则跳过.没有重复就加入数组中 // 3.返回新的去重后数组 Array.pro ...
- C++ GUI Qt4编程(04)-2.1findDialog
finddialog.h /* * 未实现findNextSignal和findPreviousSignal */ #ifndef FINDDIALOG_H #define FINDDIALOG_H ...
- PIE SDK矢量透明度、标注控制
1. 功能简介 透明度和标注是矢量图层的相关属性:图层透明值是0-100间的整数,标注是显示在地图上的文字信息,它是出图中不可或缺的重要元素.标注的样式丰富,并且放置位置灵活. 2. 功能实现说明 2 ...
- Java面试题搜集
这里是一些Java面试题,从"程序员小灰"公众号转载过来,备用. 项目介绍 明确项目是做什么的 明确项目的价值.(为什么做这个项目,它解决了用户什么痛点,它带来什么价值?) 明确项 ...
- bootstrap的datepicker使用(1.将默认的英文设置为中文2.选择日月年的时候记录之前的操作)
参考网页 bootstrap datepicker 属性设置 以及方法和事件 1.如何将bootstrap的datepicker默认的英文设置为中文 第一步,新建一个js文件(bootstrap ...
- Task的一些用法总结
一.Task和多线程以及异常的捕获示例代码: static void Main(string[] args) { // 产生CancellationToken的类,该类允许使用Cancel方法终止线程 ...