【问题标题】:Does SQL Server Service Broker load balance when External Activator is used?使用 External Activator 时 SQL Server Service Broker 负载平衡吗?
【发布时间】:2013-09-03 23:15:23
【问题描述】:

假设我有一个全天负载很高的队列。队列中的每条消息都需要几秒钟的时间来处理。

如果我有 4 台机器都设置了外部激活器(全部配置为相同的队列/服务),那会工作吗?

如果它确实有效,它是否会进行负载平衡(将工作均匀地分布在工作机器上)?

【问题讨论】:

    标签: sql-server sql-server-2012 service-broker


    【解决方案1】:

    这最终归结为如何为多个待处理的WAITFOR (RECEIVE) 语句提供服务。假设您有 4 个应用程序实例正在运行,每个实例都在同一个队列上“侦听”,方法是发出 WAITFOR(RECEIVE)。队列中有一条消息可用,问题是:等待中的 WAITFOR(RECEIVE) 中的哪一个会得到消息

    答案让很多人感到惊讶,但这就是设计的原因:最近发布的 WAITFOR(RECEIVE) 将收到消息。不是最旧的,不是随机的,而是最新的。换句话说,听众的后进先出顺序。

    为什么?这种行为是有意的,其目的是让处理负载所需的侦听器尽可能少。您最初有 4 个进程正在侦听。一个人收到消息,处理它,然后它再次发出WAITFOR(RECEIVE),从而再次开始收听更多消息。下一条消息到达时,将确定性地提供给同一进程,因为它是最近发出的 WAITFOR(RECEIVE)。此侦听器将获取消息,对其进行处理,然后再次发出 WAITFOR(RECEIVE)。并且将再次确定性地收到下一条消息。以下是它的要点:如果这个单一的侦听器可以处理所有传入的流量,那么其他 3 个是多余的。一段时间后,它们等待的 WAITFOR(RECEIVE) 将超时,这些进程可以安全地离开(退出)。

    第二个进程只有在它到达(变得可用)而第一个侦听器正忙于处理另一条消息时才可能收到一条消息(即它没有发布新的 WAITFOR(RECEIVE))。 p>

    那么为什么这么好?还有另一个难题:Understanding When Activation Occurs。如果单独的处理线程不能再处理传入的流量,则会产生一个新的处理线程(内部或外部),直至配置的 MAX_QUEUE_READERS。

    所以你有它,在这两种行为之间,你会得到一个自我限制的最佳阅读器数量(进程、线程):

    • 当流量激增并且阅读器太少时,激活机制将产生一个新的处理线程。这会在 5 秒后触发,一个无处理线程设法“排空”队列(RECEIVE 返回空行集)
    • 当流量变慢并且激活的侦听器过多时,处理流量所需的最低要求保持活动状态,而剩余的则超时
    • 如果流量在一段时间内完全干涸,所有线程/进程可能会消失(0 等待等待 WAITFOR(RECEIVE))。当消息到达时,将激活处理线程来处理它。

    请记住,由于相关的消息锁定 (Conversation Group Locks),队列中可能有消息,但它们都不能被新线程处理(即它们都被锁定)。出于激活/等待目的,这种情况意味着队列是“空的”(没有消息可用于新处理器)。

    最后,要让这一切发生,应用程序必须正确运行:

    • 在收到通知时激活新线程(内部激活会这样做,外部激活器也会正确执行)
    • 处理线程应发出 WAITFOR(RECEIVE) 一个合理的超时并在语句超时时退出(它将返回一个空的结果集,而不是错误)。
    • 必须在激活时发出 RECEIVE。如果您不这样做,队列监视器将进入 NOTIFIED 状态并且不会再次激活任何内容。见Understanding Queue Monitors

    【讨论】:

      【解决方案2】:

      要利用内置负载平衡,您需要将服务部署到多个 sql server 实例。我怀疑这不是您的计划,因此您必须想出一个自定义方法,例如有一个内部激活过程,将您到达的消息转发到外部激活过程查看的四个队列之一。

      【讨论】:

      • 我想我会让每个工作进程保持与数据库的连接打开,并带有waitfor。这样他们就会进行自我负载平衡(当有很多消息时)。我只需要找到一种方法来禁用超时(或在超时发生时重新连接)。
      • 您仍然需要小心对话锁定 - 您可能需要在 4 个对话中分发您的消息
      猜你喜欢
      • 2013-06-10
      • 2019-03-21
      • 1970-01-01
      • 2011-06-22
      • 2020-09-09
      • 2020-06-13
      • 2012-09-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多