假设我有一个全天负载很高的队列。队列中的每条消息都需要几秒钟的时间来处理。
如果我有 4 台机器都设置了外部激活器(全部配置为相同的队列/服务),那会工作吗?
如果它确实有效,它会负载平衡(将工作均匀地分布在工作机器上)吗?
假设我有一个全天负载很高的队列。队列中的每条消息都需要几秒钟的时间来处理。
如果我有 4 台机器都设置了外部激活器(全部配置为相同的队列/服务),那会工作吗?
如果它确实有效,它会负载平衡(将工作均匀地分布在工作机器上)吗?
归根结底,这归结为如何为多个未决WAITFOR (RECEIVE)
语句提供服务。假设您有 4 个正在运行的应用程序实例,每个实例都在同一个队列上“侦听”,方法是发出WAITFOR(RECEIVE)
. 队列中有一条消息可用,问题是:等待中的 WAITFOR(RECEIVE) 中的哪一个会收到该消息?
答案让很多人感到惊讶,但这就是它的设计:最近发布的 WAITFOR(RECEIVE) 将收到消息。不是最旧的,不是随机的,而是最新的。换句话说,听众的后进先出顺序。
为什么?这种行为是有意的,其目的是让处理负载所需的侦听器数量尽可能少。您最初有 4 个进程正在侦听。一个人收到消息,处理它,然后它再次发出WAITFOR(RECEIVE)
,从而开始再次收听更多消息。下一条消息到达时,将确定性地提供给同一进程,因为它是最近发出的 WAITFOR(RECEIVE)。此侦听器将获取消息,对其进行处理,然后再次发出 WAITFOR(RECEIVE)。并且将再次确定性地收到下一条消息。这是它的要点:如果这个单一的监听器可以处理所有传入的流量,那么其他 3 个是冗余的。一段时间后,他们等待的 WAITFOR(RECEIVE) 将超时,这些进程可以安全地离开(退出)。
只有当第一个侦听器正忙于处理另一条消息(即它没有发布新的 WAITFOR(RECEIVE))时,第二个进程才可能收到一条消息(变得可用)。
那么为什么这样好呢?还有另一个难题:了解激活发生的时间。如果单独的处理线程不能再处理传入的流量,则会产生一个新的处理线程(内部或外部),直至配置的 MAX_QUEUE_READERS。
所以你有它,在这两种行为之间,你得到一个自我限制的最佳读者数量(进程,线程):
请记住,由于相关的消息锁定(对话组锁定),队列中可能有消息,但它们都不能被新线程处理(即它们都被锁定)。出于激活/等待目的,这种情况意味着队列是“空的”(没有消息可用于新处理器)。
最后,要让这一切发生,应用程序必须正确运行:
要利用内置负载平衡,您需要将服务部署到多个 sql server 实例。我怀疑这不是您的计划,因此您必须想出一个自定义方法,例如有一个内部激活过程,将您到达的消息转发到外部激活过程查看的四个队列之一。