mysql service broker_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.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQL Server 2005 的一个主要成就是可以实现可靠、可扩展且功能完善的数据库应用程序。与 .NET Framework 2.0 公共语言运行库 (CLR) 的集成使开发人员可以将重要的业务逻辑与存储过程合并,而 T-SQL 和 XML 中的新增功能扩展了数据操作的可用范围以及开发人员可用的存储功能。另一个重要功能是 SQL Server Service Broker,它为数据库应用程序增加了可靠、可扩展、分布式异步功能。 为什么要编写异步排队操作? 在开发 SQL Server 2005 时,我们与成功开发过大型可扩展数据库应用程序的人员进行了交谈。结果发现他们几乎所有的应用程序中都有一个或多个操作是以异步排队方式执行的。股票交易系统中的结算活动是排队的,这样可以在后台进行结算,在前端处理其他交易。订单输入系统中的发货信息放在一个排队中,稍后将由另一台服务器(通常位于其他位置)上运行的发货系统读取。旅行预订系统在客户填写完路线后再进行实际的预订,并在预订完成后发送确认电子邮件。在所有这些示例中,许多工作都是通过异步方式完成的,从而提高了系统的响应速度,因此用户无须等待工作完成就可以收到响应。 在大多数大型系统中,经过仔细分析后都可以发现,许多处理都可以通过异步方式完成。虽然应用程序中的排队任务无须立即完成,但系统必须确保这些任务能够可靠地完成Service Broker 使异步排队任务的执行可靠并且易于实现。 使应用程序中的部分任务异步执行的另一个优势是这些任务的处理工作可以在资源可用时完成。如果订单输入系统中的发货任务可以从队列中执行,发货系统就无需具有处理峰值订单负载的能力。在许多订单输入系统中,峰值订单率可能是平均订单率的两倍或三倍。由于订单输入系统必须具有处理峰值负载的能力,因此大量处理能力在很大一部分时间内都处于闲置状态。如果在出现峰值时对异步任务进行排队并在空闲时执行,将显著提高系统的利用率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值