1

我有一个由 8 个服务器组成的分布式应用程序,所有服务器都运行 .NET windows 服务。每个服务都会轮询数据库中可用的工作包。

由于其他原因,轮询机制很重要(现在太无聊了)。

我认为这种轮询机制最好在队列中实现,因为 .NET 服务都将定期轮询数据库,并且在负载下我不想要死锁。

我想我希望每个 .NET 服务都将消息放入输入队列。数据库服务器将一次弹出输入队列中的每条消息,对其进行处理,然后将回复消息放在另一个队列中。

我遇到的问题是 SQL Server Broker (SSB) 的大多数示例都在数据库服务之间,而不是从 .NET 客户端启动。我想知道 SQL Server Broker 是否只是这项工作的错误工具。我看到代理 T-SQL DML 可从 .NET 获得,但我认为这应该工作的方式似乎不适合 SSB。

我认为我需要一个带有 2 个队列(进出)和一个激活存储过程的单一 SSB 服务。

这似乎不是 SSB 的工作方式,我错过了什么吗?

4

1 回答 1

0

您得到的图片非常正确,但是该图片中缺少一些拼图:

  • SSB 主要是一种通信技术,旨在以完全事务的方式通过网络传递具有完全一次性语义 (EOIO) 的消息。它处理网络连接(身份验证、流量机密性和完整性)以及传输的确认和重试逻辑。
  • 内部激活是一项独特的技术,因为它消除了驻留服务轮询队列的要求。轮询永远无法达到轻负载下低延迟低资源消耗所需的动态平衡。轮询迫使高延迟(不频繁轮询以节省资源)或高资源利用率(需要频繁轮询以提供低延迟)。内部激活还具有自我调整能力,可以增加更多处理器以应对负载峰值(通过max_queue_readers) 同时仍然能够通过停用处理器来调低低负载下的处理。内部激活机制经常被忽视的优点之一是它完全包含在数据库中,即。它通过集群或数据库镜像故障转移进行故障转移,并在备份和复制附加操作中与数据库一起移动。还有一个外部激活机制,但总的来说,对于任何适合内部上下文的东西,我更喜欢内部激活机制(例如,不是和 HTTP 请求,必须在引擎进程之外处理......)
  • 对话组锁定同样是独一无二的,它是一种提供对相关消息处理的独占访问的方法。应用程序可以利用conversation_group_id作为业务逻辑键的优势,这几乎完全消除了死锁,即使在繁重的多线程下也是如此。

还有一个关于 Service Broker 的问题你弄错了:需要将响应放入单独的队列中。与您可能熟悉的大多数排队产品不同,SSB 原语不是消息,而是“对话”。会话是一个全双工的双向通信通道,你可以把它想象成一个 TCP 套接字。SSB 服务不需要“将响应放入队列”,而是可以简单地在接收到的消息的会话句柄上发送响应(很像在 TCP 套接字服务器中通过send同一个套接字上发出 a 来响应)获取请求,而不是通过打开新套接字并发送响应)。此外,SSB 将处理固有的消息相关性这样发送方将确切地知道响应属于它发送的哪个请求,因为响应将在发送请求的同一会话句柄上返回(很像在 TCP 套接字情况下,客户端在它发送请求的同一个套接字)。当涉及到相关对话组的关联锁定时,此对话句柄再次很重要,请参见上面的链接。

您可以通过 SQLCLR 将 .Net 逻辑嵌入到 Service Broker 处理中。几乎所有 SSB 应用程序至少在一端直接或间接地(例如通过触发器)具有非 SSB 服务,完全包含在数据库中的分布式应用程序几乎没有用处。

于 2012-10-16T11:28:04.240 回答