Service Broker完成实例之间的会话详细解读

首先了解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 = 4022 ) FOR SERVICE_BROKER (AUTHENTICATION = WINDOWS ); GO

(首先要创建一个endpoint,作为后面安放证书,此端点的默认端口号就是4022,我们也设置为4022)

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 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

(创建证书,并且将证书绑定给新建的用户TargetUser,我们创建完证书后就将证书备份到某个地址::::在这里声明一下,此处的证书并不是完整的证书,我们备份出来的只是公钥部分,私钥部分是不能够备份出来的,因为加解密的过程是别人拿公钥加密发给本人,本人通过私钥区解锁,这样才可以保证数据传输的安全性,)

        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 = 4022 ) 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(4000); 

 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(4000); 

       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(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 = 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(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‘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



6:接收答复并且结束会话

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. 
        S
时间: 2024-10-10 06:36:10

Service Broker完成实例之间的会话详细解读的相关文章

caffe 实例笔记 2 LeNet详细解读及实现

1 温习 1.1 关于caffe的名称: caffe = convolutional architecture for fast feature embedding 1.2 caffe.proto Protocol Buffers顾名思义这是一种协议接口,这是了解caffe功能之后,需要了解的第一件事情.有很多相关博客.简单看一下其结构: package xx;#xx将作为名称空间 message helloworld #定义类 { #定义 filed required int32 xx = 1

未启用当前数据库的 SQL Server Service Broker,因此查询通知不受支持。如果希望使用通知,请为此数据库启用 Service Broker

昨晚遇到的这个问题,也知道Notifications service依赖底层的Service broker的.本以为只需要执行以下脚本对数据库启用Service broker即可. alter database DBNAME set enable_broker 但是,执行后,脚本一直处于执行状态,不以为然,正好在忙其它事情就没有查看运行结果,结果到今早一看,居然运行还没有结束.虽然是在一个生产数据库上执行的,数据库也只有30G的样子,但也不至于执行一个晚上也未结束,只好终止执行,使用 SELEC

当前数据库未启用Service broker

数据库分离(备份)后,附加(还原)回到数据库,然后在程序中打开调用数据库的页面,出现如下问题:“未启用当前数据库的 SQL Server Service Broker,因此查询通知不受支持.如果希望使用通知,请为此数据库启用 Service Broker ”. 解决方案:(可直接执行第二步)在使用的数据库下,依次执行如下语句:第一步:SELECT is_broker_enabled FROM sys.databases WHERE name = '数据库名称' 执行发现:查看is_broker-

sql server Service Broker 相关查询

-- 查看传输队列中的消息 --如果尝试从队列中移除时,列将表明哪里出现了问题 select * from sys.transmission_queue -- 查看Service Broker 激活的存储过程 select * from sys.dm_broker_activated_tasks -- 查看数据库中的每个会话端点.会话端点代表Service Broker 会话的每一端. -- 会话端点视图state列显示会话的状态 select * from sys.conversation_e

SqlServer service broker 分布式系统(赵松涛)深入浅出 2005 数据库编程

1.创建测试数据库 create database ServerbrokerTest on primary( name=ServerbrokerTest_data, filename='C:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\DATA\ServerbrokerTest_data.mdf', size=5, maxsize=unlimited, filegrowth=1 ) Log on ( name=stude

BizTalk 开发系列(四十) BizTalk WCF-SQL Adapter读取SQL Service Broker消息

SQL Service Broker 是在SQL Server 2005中新增的功能.Service Broker 为 SQL Server 提供队列和可靠的消息传递,可以可用来建立以异步消息为基础的应用.当然从题目大家可能也看出来了.我们本文主要不是为了讲SQL Service Broker(SSB),而是讲一下如何使用BizTalk WCF-SQL Adapter来访问SSB的数据. SQL Service Broker(SSB) 为要便于大家更好的接下来的示例,我们还是概况的讲一下SSB的

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

项目代码和数据库部署在不同的Windows Server 2008 R2 Server中,错误日志显示如下: "未启用当前数据库的 SQL Server Service Broker,因此查询通知不受支持.如果希望使用通知,请为此数据库启用 Service Broker." SQL Server Service Broker介绍: SQL Server Service Broker 为消息和队列应用程序提供 SQL Server 数据库引擎本机支持.这使开发人员可以轻松地创建使用数据库

Service Broker needs to access the master key in the database ‘BRM_TEST’. Error code:32. The master key has to exist and the service master key encryption is required.

Service Broker needs to access the master key in the database ‘BRM_TEST’. Error code:32. The master key has to exist and the service master key encryption is required. 日志错误:Service Broker needs to access the master key in the database 'BRM_TEST'. Err

The SQL Server Service Broker for the current database is not enabled

把一个数据恢复至另一个服务器上,出现了一个异常: The SQL Server Service Broker for the current database is not enabled, and as a result query notifications are not supported.  Please enable the Service Broker for this database if you wish to use notifications. 截图如下: 解决方法: 参