SQL Server Service Broker 为 SQL Server 数据库引擎 和 Azure SQL 托管实例中的消息传递和队列提供本机支持。 开发人员可轻松创建通过 数据库引擎 组件在不同数据库之间通信的复杂应用程序,也可构建分发式应用程序和可靠的应用程序。
何时使用 Service Broker
使用 Service Broker 组件实现本机数据库内异步消息处理功能。 使用 Service Broker 的应用程序开发人员无需编写复杂的内部通信和消息,即可跨多个数据库分发数据工作负荷。 由 Service Broker 处理对话上下文中的通信路径,因此 Service Broker 可减少开发和测试工作。 同时还提高了性能。 例如,支持网站的前端数据库可以记录信息,并发送处理密集型任务以便在后端数据库中进行排队。 Service Broker 确保在事务上下文中管理所有任务,以确保可靠性和技术一致性。
概述
Service Broker 是一种消息传递框架,可用于创建本机数据库内面向服务的应用程序。 与经典查询处理功能不同,这些功能不断从表读取数据并在查询生命周期中进行处理,面向服务的应用程序具有交换消息的数据库服务。 每个服务都有一个消息队列,消息会放入队列中等待处理。
可以使用 Transact-SQL RECEIVE 命令或每当消息到达队列时调用的激活过程来提取队列中的消息。
创建服务
注释
目标服务必须公开一个或多个 协定。 如果创建的服务没有协定,则无法接收消息。 发送的消息将显示为成功发送,但消息会留在发起者的 sys.transmission_queue
/*
In this example, the initiator must then use ON CONTRACT [DEFAULT] and a MESSAGE TYPE [DEFAULT]. [DEFAULT] is a delimited identifier for the built‑in contract and isn't a T‑SQL keyword, so it must be bracketed or quoted.
*/
CREATE QUEUE dbo.ExpenseQueue;
GO
CREATE SERVICE ExpensesService
ON QUEUE dbo.ExpenseQueue ([DEFAULT]);
发送消息
使用 SEND Transact-SQL 语句在服务之间的对话上发送消息。 对话是通过 BEGIN DIALOG Transact-SQL 语句在服务之间建立的信道。
-- Begin a dialog
DECLARE @dialog_handle AS UNIQUEIDENTIFIER;
BEGIN DIALOG @dialog_handle
FROM SERVICE ExpensesClient
TO SERVICE N'ExpensesService'
ON CONTRACT [DEFAULT];
-- Send a message
SEND ON CONVERSATION (@dialog_handle)
MESSAGE TYPE [DEFAULT] (N'<Expense ExpenseId="1" Amount="123.45" Currency="USD"/>');
消息被发送到 ExpensesService 并放置在 dbo.ExpenseQueue。 由于没有与此队列关联的激活过程,因此消息将保留在队列中,直到有人读取它。
处理消息
可使用标准 SELECT 查询选择放置在队列中的消息。 该 SELECT 语句不会修改队列并删除消息。 要读取和拉取队列中的消息,可使用 RECEIVE Transact-SQL 语句。
RECEIVE TOP (1)
conversation_handle,
message_type_name,
TRY_CAST (message_body AS NVARCHAR (MAX)) AS message_body_text
FROM dbo.ExpenseQueue;
GO
处理队列中的所有消息之后,应使用 END CONVERSATION Transact-SQL 语句关闭对话。
-- Drain any remaining target conversations for the from the queue
DECLARE @conversation_hdl AS UNIQUEIDENTIFIER;
WHILE EXISTS (SELECT 1 FROM dbo.ExpenseQueue)
BEGIN
RECEIVE TOP (1) @conversation_hdl = conversation_handle FROM dbo.ExpenseQueue;
END CONVERSATION @conversation_hdl;
END
GO
Service Broker 文档
有关 Service Broker 的详细信息,请参阅:
- 和
CREATEALTERDROP - Transact-SQL 语句
- Service Broker 目录视图 (Transact-SQL)
- 与 Service Broker 有关的动态管理视图 (Transact-SQL)
- ssbdiagnose 实用工具 (Service Broker)
还可以参考 以前发布的 Service Broker 概念文档以及开发和管理任务。
Service Broker 新增功能
Service Broker 和 Azure SQL 托管实例
Azure SQL 托管实例实例之间的跨实例 Service Broker 消息交换和 SQL Server 与 Azure SQL 管理实例之间的消息交换目前为公共预览版:
-
CREATE ROUTE:指定的端口必须是 4022。 请参阅 CREATE ROUTE(Transact-SQL)。 -
ALTER ROUTE:指定的端口必须是 4022。 请参阅 ALTER ROUTE(Transact-SQL)。
支持传输安全性,但不支持对话安全性。
- 不支持
CREATE REMOTE SERVICE BINDING。
Service Broker 默认处于启用状态,不能禁用。 不支持以下 ALTER DATABASE 选项:
ENABLE_BROKERDISABLE_BROKER
SQL Server 2019 (15.x) 中未引入任何重大更改。 SQL Server 2012 (11.x)中引入了以下更改。
可以将消息发送到多个目标服务(多播)
扩展了 SEND 语句的语法,通过支持多个会话句柄来实现多播功能。
队列将公开此消息排队时间
队列有一个新列, message_enqueue_time用于显示消息在队列中的时长。
可以禁用有害消息处理
CREATE QUEUE 和 ALTER QUEUE 语句现在可以通过添加子句POISON_MESSAGE_HANDLING (STATUS = ON | OFF)来启用或禁用有害消息处理。 目录视图 sys.service_queues 现在有一列 is_poison_message_handling_enabled ,用于指示病毒消息是启用或禁用的。
Service Broker 中的可用性组支持
有关详细信息,请参阅 Service Broker 与 AlwaysOn 可用性组 (SQL Server)。