【问题标题】:Two-way SQL Service Broker双向 SQL 服务代理
【发布时间】:2018-07-03 10:37:10
【问题描述】:

我正在尝试将 SSB 用作多个分布式逻辑站的全双工消息传递基础设施。 多个站点可以驻留在同一进程上,也可以驻留在不同的机器上(没关系)。 这些站点需要通过不断地来回发送消息来相互通信和同步。 这些站作为 Windows 服务的一部分运行,因此,站的生命周期很长。 一个站发送的每个消息都可以指定给单个站或多个站或所有站(广播)。 仅当消息被指定给特定站点或广播消息时,消息才与特定站点相关。

SSB 的所有 Dialog/Convertation/Group 术语真的让我很困惑。

我不知道如何确定谁以及何时应该成为发起者/目标,因为根据我的情况,每个站都可以在需要时发送消息,并且应该一直接收相关消息。

由于许多站点可能同时向许多其他站点发送消息,因此出队时间应该尽可能快,并且性能必须是最佳的。

According to Microsoft,我应该使用包含许多消息的多次对话以获得最佳性能。 但我不知道何时以及如何创建单独的对话/对话,以及对话何时结束(如果有的话)。

有人可以对此有所了解,并为我的案件提供正确的方向吗?

谢谢。

【问题讨论】:

  • 恕我直言,SB 不是适合这里工作的工具,因为它本身不支持广播(发布/订阅模型);您需要在代码(T-SQL 或应用程序)中执行此操作。消费者(发起者)创建与实施服务(目标)的对话。对话由发起者和目标消息的单独队列实现。至少,在您的情况下,每个站都是一个 SB 服务,每个站可能既是发起者又是目标。预计会有什么样的消息量?
  • 对话是两种方式吗?还是对于任何两个参与者,任何一方都可以向另一方发送消息?
  • @DanGuzman 目前,根据我的测试,单站每秒最多可以发送76条消息。
  • @BenThul 我猜是后者,任何电台都可以在任何给定时间向任何其他电台发送消息,或发送给多个电台,或向所有电台广播消息。

标签: sql-server distributed-computing service-broker sqlperformance


【解决方案1】:

假设每个站点都有所有其他站点的清单(这可能需要一些人手!),这应该是可行的。

关于发起者/目标术语,发起对话的人就是发起者,而该消息的接收者就是目标。想象一下下面的真实世界对话。我将在发起者发送的任何消息前加上 [I],在目标发送的消息前加上 [T]

  • [I] 你好百货公司。告诉我你要买什么样的袜子。
  • [T] 我们出售红色、白色和蓝色的袜子。
  • [I]我要带两双红袜子。
  • [T] 好的

在这种情况下,只有一个目标,但在发起给定对话时可以考虑多个目标(在您的“多站”或“广播”场景中)。为了进一步进行上述类比,这类似于一次致电多家商店并询问他们所有的袜子库存。

凭直觉知道为什么您需要知道谁是发起者和目标,上面的对话可以分解为以下消息类型:InventoryRequest、InventoryResponse、PurchaceRequest、PurchaseResponse。如果您将所有这些都捆绑到一份合同中,那么您应该参加比赛。

【讨论】:

  • 所以你说第一个要发起对话的站应该调用BEGIN DIALOG?在这种情况下,每个站将在加载时调用 BEGIN DIALOG。既然每个站点都“永远”存在,并且不断与所有其他站点通信,那么它的对话是否应该与它永远存在?还是您会将“对话”视为更小的时间范围?
  • 视情况而定。我现在在哪里,我实施了“对话永远存在”计划,因为建立对话是有成本的。因此,作为一次性操作,我设置了对话并将对话句柄存储在一个表中。当应用程序需要一个时,它会从该表中获取它。也就是说,我的实现确实很奇怪。更标准的方法是您所说的。当您想要开始对话时,执行BEGIN DIALOG,交谈,然后一方发出END DIALOG,表示该主题已完成。
  • 好的。因此,我最终让每个站点在加载时创建一个新对话框,并创建一个线程不断监听该对话句柄以获取传入消息。我还创建了一个映射表,将每个电台的 id 映射到其对话句柄(在对话创建时插入)。然后,每当一个站点想要发送消息时,它可以通过在映射表中查找它们的 id 将其发送到特定站点或所有站点。
  • “不断倾听的线程”。您是否查看过 Service Broker 激活(内部或外部)?激活是 SB 设计的一部分,可防止“应用程序处于等待消息的紧密循环中”模式。
  • 内部激活绝对不适合我的场景,我也不确定外部激活是否适合。我有一个在多台分布式机器上运行的 Windows 服务。每个 Windows 服务都包含多个站(如上所述),每个站都侦听自己的队列。与在每个站中运行轮询线程相比,调用带有参数的 exe 文件作为外部激活,然后必须将激活事件路由到相关站\s,这对我来说似乎是一种过度杀伤。你觉得我错了吗?
猜你喜欢
  • 1970-01-01
  • 2011-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-02
  • 1970-01-01
  • 1970-01-01
  • 2021-07-06
相关资源
最近更新 更多