介绍 SQL Server 2005 中的 Service Broker 分布式消息传递






4.83/5 (38投票s)
2005年9月28日
13分钟阅读

231766

2594
一篇关于在 SQL Server 2005 中使用 Service Broker 进行分布式消息传递的文章。
引言
Microsoft SQL Server 2005 引入了一个新的分布式消息传递框架,该框架支持异步编程。Service Broker 是一个用于构建异步、分布式数据库应用程序的新平台。在本文中,我将简要概述 Service Broker 平台中最重要方面的定义,并提供一个利用其某些功能的示例应用程序。
本文将有第二部分,目前正在开发中,将介绍 Service Broker 平台更高级的功能,并提供一个企业级示例解决方案。
Service Broker 提供什么
借助新的 Service Broker 平台,内部或外部 SQL Server 实例可以使用 Transact T-SQL 发送和接收保证的、异步的消息。消息可以从同一数据库、不同数据库,甚至远程 SQL Server 实例发送。
Service Broker 如何工作
Service Broker 通过一种新开发的名为 Dialog 的协议进行通信,该协议允许两个端点之间进行双向通信。Dialog 协议规定了可靠对话所需的逻辑步骤,并确保消息按发送顺序接收。下面来自 Microsoft SQL Server 2005 Books Online 的图示了 Dialog 协议如何在 Service Broker 平台中得到利用。
以下是 Service Broker 的另一个概述图,它展示了 Service Broker 的主要实体,如消息、合同和服务,这些将在下一节中进一步解释。但是,让我们看一下对话部分,这是一个高级协议,Service Broker 使用它来确保消息按顺序无丢失地接收。正如我们所见,对话协议不是传输协议,而是一个应用程序协议,用于维护消息的“仅一次按顺序”(Exactly-Once-In-Order,EOID)的传递。EOID 是一个概念,无论消息从传输通道以何种顺序接收,都要对其进行排序。
如上所示,Service Broker 端点是两个 Service Broker 之间的通信端点。它们支持 TCP/IP、HTTP、SOAP 等传输协议。
端点在每个 Service Broker 上创建,以允许不同 SQL Server 实例之间的远程通信。下一节将对以下各项进行进一步解释。
Service Broker 概念
消息
消息是 Server Broker 之间交换的实体。消息必须具有名称和数据类型。可选地,消息可以对其数据类型进行验证。消息是对话的一部分,它具有唯一的标识符以及唯一的序列号以强制执行消息排序。
请注意,Service Broker 发送的所有消息都是对话的一部分。
对话 - 交互
对话是两个 Service Broker 之间的交互,它定义了发起方服务、目标服务以及将用于其对话的合同。此外,它还定义了单个对话的加密选项和生存期。
应用程序作为对话的一部分交换消息。当 SQL Server 收到一个用于对话的消息时,SQL Server 会将消息放入该对话的队列中。应用程序从队列中接收消息并根据需要对其进行处理。作为处理的一部分,应用程序可能会向对话中的另一方发送消息。
对话组
对话组是一组相关的对话。让我们以航空票务系统为例。您可以想象,对话组就像一个需要一起办理登机手续的家庭。对于相互关联的消息也适用相同的概念,它们必须按顺序接收和处理。
SQL Server 2005 为对话组提供锁定,以提供“仅一次按顺序”(EOID)功能。这允许同一对话组的消息按顺序接收。因此,一次只有一个会话可以接收对话组的消息。由于一个对话组可以包含多个对话,因此应用程序可以使用对话组来识别与同一业务任务相关的消息,并一起处理这些消息。
端点
SQL Server 2005 使用端点与不同 SQL Server 实例上的 Service Broker 通信。端点允许 Service Broker 使用 HTTP、TCP 和 SOAP 等传输协议通过网络进行通信。必须使用 T-SQL DDL 为每个传输协议定义一个端点。
请注意,默认情况下,SQL Server 不包含任何端点,因此必须先创建才能启用通信。
此外,必须为 SQL Server 实例之间的安全启用通信才能允许这种通信。
Service Broker 安全
Service Broker 安全允许服务安全地通信,即使它们位于不同的计算机上。服务器实例可以位于不同的网络上,甚至可以通过 Internet 进行通信,并且仍然可以安全地通信。
Service Broker 安全依赖于远程数据库之间共享的证书,但其他信息不共享。
Service Broker 支持两种类型的安全
- 对话安全
加密单个对话消息,并验证对话参与者的身份。对话安全还提供远程授权和消息完整性检查。对话安全在两个服务之间建立经过身份验证和加密的通信。
- 传输安全
防止未经授权的数据库向本地实例中的数据库发送 Service Broker 消息。传输安全在两个数据库之间建立经过身份验证的网络连接。
Service Broker 内部
Service Broker 在每个数据库中包含以下六个主要实体。
- 消息类型
描述消息的名称、数据类型和验证,它可以是变体类型或由模式指定的 XML 数据。
- 合同
合同,正如其字面意思一样,是两个服务之间的合同,描述将包含哪些消息类型,以及谁有权发送它们。例如,您可以在合同中指定多种消息类型,并指定发送方或接收方是否允许发送。
- 队列
队列是服务之间传输消息的主要存储。此外,它可以与多个服务关联,并提供激活机制。激活机制允许在收到消息时调用存储过程来处理消息。这可以看作是消息的管道。必须将队列设置为激活状态才能发送和接收消息。请注意,您可以使用 SELECT 语句查询队列。
- 服务
服务由 Service Broker 用于将消息传递到数据库中的正确队列,路由消息,强制执行对话的合同,并确定新对话的远程安全。
- 路由
Service Broker 使用路由来确定消息的传递位置。这可用于 Service Broker 内部的分布式消息传递,允许远程甚至本地实例进行通信。创建路由时,您会指定它将路由到的服务、地址和协议。默认情况下,每个数据库都有一个 AutoCreatedLocal 路由,用于定义数据库的本地实例。
- 远程服务绑定
创建定义用于启动与远程服务对话的安全凭据的绑定。
下面的图显示了 (MyDB) 数据库的 Service Broker 及其六个主要实体。
从上图可以看出,对于每个数据库,我们都有一个包含六个主要项的树,您可以进行查看。对于管理部分,直到 SQL Server 2005 的 April CTP 版本,还没有用户界面来管理这些项,它们都是使用 T-SQL 创建和编辑的。
一个简单的 Service Broker 示例
以下示例演示了如何使用 T-SQL 和 Service Broker 平台在单个服务器实例中的两个数据库之间创建简单的消息传递。这些示例不包括路由、安全和远程服务绑定;它们将在另一篇文章中介绍。
创建消息类型
-- Create a Type for Send Message type
CREATE MESSAGE TYPE SendMessageType
VALIDATION = WELL_FORMED_XML;
-- Create a Type for Receive Message Type
CREATE MESSAGE TYPE ReceiveMessageType
VALIDATION = WELL_FORMED_XML;
上面的代码创建了一个验证类型为 WELL_FORMED_XML 的消息。这是 SQL Server 2005 中的内置类型。它只允许发送符合 XML 标准的消息。当然,您可以使用自己的 XML 模式进行验证。
创建合同
-- Create Contract to be used
CREATE CONTRACT [MainContract]
(
[SendMessageType] SENT BY INITIATOR,
[ReceiveMessageType] SENT BY TARGET
);
以下代码创建了两个服务之间的合同,它基本上说明了发起方(发送方)必须使用 SendMessageType,目标方必须使用 ReceiveMessageType。这只允许发送方使用 SendMessageType,而接收方使用 ReceiveMessageType。
创建队列
CREATE QUEUE QUEUE1
WITH STATUS=ON,
ACTIVATION (
PROCEDURE_NAME = OnReceiveMessage,
MAX_QUEUE_READERS = 5,
Execute AS 'dbuser') ;
您需要将 dbuser 替换为您自己的用户名。
创建的队列在存储过程上创建激活,该存储过程将在消息到达时处理消息。存储过程的名称是 OnReceiveMessage。队列读取器的最大数量为 5。此外,您必须指定它将作为安全上下文运行的用户。
创建服务
CREATE SERVICE SERVICE1
ON QUEUE [QUEUE1]
(
[MainContract]
);
以下代码创建了一个名为 Service1 的服务,使用 Queue1 监听消息,并且只接受适用于 MainContract 的消息。
开始对话
BEGIN DIALOG CONVERSATION @dialog_handle
FROM SERVICE [SERVICE1]
TO SERVICE 'SERVICE2'
ON CONTRACT [MainContract] ;
对话是通过 dialog_handle 创建的,dialog_handle 是每个对话的 GUID ID,它在启动对话时创建。我们指定了 From Service 和 To Service。此外,我们指定了要使用的合同。
发送和接收消息
发送消息
SEND ON CONVERSATION @dialog_handle
MESSAGE TYPE SendMessageType (@msg)
发送消息很容易。我们提供 dialog_handle 并指定要发送的消息类型,因为我们的合同中有多种消息类型。然后我们添加消息,这是一个本地 XML 变量。
接收消息
RECEIVE TOP(1) @msg = message_body,
@dialog_handle = conversation_handle
FROM QUEUE2
接收方通过选择 QUEUE2 的结果来接收消息。当然,您可以根据对话标识符句柄进行选择。但是,为了简单起见,我们选择第一条消息并为其分配一个消息。然后,我们可以根据应用程序的业务逻辑对消息执行任何操作。
结束对话
END CONVERSATION @dialog_handle
WITH cleanup
示例应用程序
示例应用程序是一系列 SQL 脚本,它们创建了在同一 SQL Server 实例上运行的两个数据库。
该应用程序包含每个数据库的脚本,用于创建所需的消息类型、合同、队列和服务。该应用程序的运行方式如下:
- 发送脚本从 db1 上的 Service Broker 向 db2 上的 Service Broker 发送消息。
- db2 上的 Service Broker 接收消息,一个存储过程获取消息并将消息数据和状态记录到日志表中。
- db2 上的 Service Broker 发送确认消息到 db1。
- db1 上的 Service Broker 记录消息和状态。
- 对话在双方结束。
示例应用程序相当简单,它不提供跨不同实例的路由功能、安全,甚至端点创建和通信。这些功能将在另一篇文章中提供,其中包含有关 Service Broker 安全和远程功能的更深入的详细信息。
Service Broker 技巧和窍门
- SQL Server 2005 包含一组模板,可用于几乎所有 T-SQL 结构中创建各种 SQL 查询。它还可以用于 Service Broker,以创建队列、服务等,以及其他 Service Broker 功能,请看下图。
您需要转到解决方案文件,右键单击并添加新项。这将使您能够将 Service Broker 功能的模板直接添加到您的应用程序中。
- 另一个技巧是创建数据库时,您可能需要它通过 Service Broker 与另一个数据库通信,您需要使用以下方式创建数据库:
create database localsb_db1 WITH TRUSTWORTHY ON;
此授权允许在同一 SQL Server 实例中的两个服务器数据库之间进行通信。如果您需要两个 Service Broker 进行通信,这是必须的。
何时使用 Service Broker
以下列表提供了 Service Broker 的典型用途;此列表来自 Microsoft SQL Server 2005 CTP 版本(2005 年 4 月)提供的 MS SQL Server 2005 在线书籍。
- 异步触发器
- 可靠的查询处理
- 数据采集
- 客户端应用程序的分布式服务器端处理
- 客户端应用程序的数据整合
- 大规模批量处理
异步触发器
许多使用触发器的应用程序,例如在线事务处理(OLTP)系统,都可以从 Service Broker 中受益。触发器排队一条消息,该消息请求 Service Broker 服务执行工作。触发器实际上不执行请求的工作。相反,实现服务的程序在单独的事务中执行工作。通过在单独的事务中执行此工作,可以立即提交原始事务。应用程序可以避免因在执行工作时保持原始事务打开而导致的系统减速。
可靠的查询处理
某些应用程序必须可靠地处理查询,不受计算机故障、停电或类似问题的干扰。需要可靠查询处理的应用程序可以通过将查询发送到 Service Broker 服务来提交查询。实现服务的应用程序读取消息,运行查询,并返回结果。这三项操作都在同一个事务中进行。如果发生故障,整个事务将回滚,消息将返回到队列。当计算机恢复时,应用程序将重新启动并再次处理消息。
数据采集
从大量源收集数据的应用程序可以利用 Service Broker 来可靠地收集数据。例如,拥有多个站点的零售应用程序可以使用 Service Broker 将事务信息发送到中央数据存储。由于 Service Broker 提供可靠的异步消息传递,因此即使站点暂时失去与中央数据存储的连接,每个站点也可以继续处理事务。Service Broker 安全有助于确保消息不会被错误地路由,并有助于保护传输中的数据。
客户端应用程序的分布式服务器端处理
访问多个 SQL Server 数据库以获取信息的应用程序是使用 Service Broker 的良好候选者。例如,用于订购书籍的 Web 应用程序可以在服务器端使用 Service Broker 来交换包含订购、客户、库存和信贷信息的不同数据库之间的信息。Service Broker 提供消息队列和可靠的消息传递,因此即使一个数据库不可用或负载很高,该应用程序也可以继续接受订单。在此场景中,Service Broker 作为分布式 OLTP 系统的框架。
客户端应用程序的数据整合
必须同时使用或显示来自多个数据库的信息的应用程序可以利用 Service Broker。例如,将来自多个位置的数据整合到一个屏幕上的客户服务应用程序可以使用 Service Broker 并行运行这些多个请求,而不是串行运行,从而显著缩短应用程序响应时间。客户服务应用程序并行发送请求到不同的服务。当服务响应请求时,客户服务应用程序收集响应并显示结果。
大规模批量处理
必须执行大规模批量处理的应用程序可以利用 Service Broker 提供的队列和并行处理功能,快速有效地处理大量工作。应用程序将要处理的数据存储在 Service Broker 队列中。程序会定期从队列读取并处理数据。应用程序可以利用 Service Broker 提供的可靠消息传递,在与请求源不同的计算机上执行批量处理。
接下来是什么?
我将很快提供另一篇文章,讨论安全、路由和服务端点等高级功能,并提供一个企业级示例应用程序。