Azure 服务总线 - 多个服务的循环主题
Azure Service Bus - Round Robin Topic to Multiple Services
场景如下:
Publisher #1 ═══╗ ╔═══ Round Robin ═══╦═══ Subscriber #1 (Service 1)
║ ║ ╚═══ Subscriber #2 (Service 1)
╠═══ Topic ═══╣
║ ║ ╔═══ Subscriber #3 (Service 2)
Publisher #2 ═══╝ ╚═══ Round Robin ═══╩═══ Subscriber #4 (Service 2)
我有一条消息需要由多个订阅者处理,但每个服务只有一个(每个服务将有多个实例 运行)。
消息 #1,需要由订阅者 #1 和 #3 处理。消息 #2,需要由订阅者 #2 和 #4 处理。消息 #3,订阅者 #1 和 #3 再次。基本上,每条消息都应该循环到订阅每条消息的每个负载平衡服务,按连接的每个服务分组。这是否可以不创建多个主题?
即使不是循环法,我也想尽最大努力在多个服务之间进行负载平衡。这可能吗?
1。主题
主题是一种 publishing/distribution 机制,每个订阅者(订阅者)将发送一次消息。
A topic subscription resembles a virtual queue that receives copies of the messages that are sent to the topic. Messages are received from a subscription identically to the way they are received from a queue...
Subscriptions support the same patterns described earlier in this section with regard to queues: competing consumer, temporal decoupling, load leveling, and load balancing.
来源:MSDN Article
您需要在竞争消费者(服务实例)之间重新使用主题订阅来实现您的场景。
Publisher #1 ═══╗ ╔═══ Subscription 1 ═══╦═══ Service 1-instance 1
║ ║ ╚═══ Service 1-instance 2
╠═══ Topic ═══╣
║ ║ ╔═══ Service 2-instance 1
Publisher #2 ═══╝ ╚═══ Subscription 2 ═══╩═══ Service 2-instance 2
一个。创建主题订阅
string connectionString = "<Secret>"
var namespaceManager =
NamespaceManager.CreateFromConnectionString(connectionString);
if (!namespaceManager.SubscriptionExists("TestTopic", "Inventory"))
{
namespaceManager.CreateSubscription("TestTopic", "Inventory");
}
乙。收听现有订阅
MessagingFactory factory = MessagingFactory.Create(uri, tokenProvider);
MessageReceiver receiver = factory.CreateMessageReceiver("TestTopic/subscriptions/Inventory");
2。队列
使用多个 Queues
也可能适合您的具体情况。每个 Queue
有多个竞争消费者(实例)将只向第一个请求并成功处理它的客户端传递一次消息。
设计则变成:
Publisher #1 ═══╗ ╔═══ Service 1 Queue ═══╦═══ Subscriber #1 (Service 1)
║ ║ ╚═══ Subscriber #2 (Service 1)
╠═══ASB═══╣
║ ║ ╔═══ Subscriber #3 (Service 2)
Publisher #2 ═══╝ ╚═══ Service 2 Queue ═══╩═══ Subscriber #4 (Service 2)
I'd like to use best effort to load balance across multiple services. Is this possible?
根据您的描述,您似乎是在尝试在任何给定服务的多个实例之间进行负载平衡,而不是在单个服务之间进行负载平衡。您可以通过 ASB 支持的竞争消费者模式开箱即用。并不是你需要工作的东西。
The problem I'm trying to solve, is I only want 1 consumer in each service consuming messages on a single topic. Is this possible with ASB?
是的,这是可能的。如果您有一个共享主题,每个服务(不是实例)都有订阅,并且包含一个始终计算为真的规则,SqlFilter
(1 = 1
)。然后每个订阅者都会得到该消息的副本。本质上,您将向所有服务广播消息。感谢竞争消费者,每个服务只有一个实例会收到该消息。
要针对特定服务,您需要创建一个附加规则来过滤掉 属性(标准 属性 或自定义服务)上的消息。例如,它可以是服务名称。
如果您不想专注于微服务的中间件,您可以看看为您做这件事的框架。这样的框架通常也倾向于提供额外的特性。例如,看看 NServiceBus 或 MassTransit。
完全免责声明 - 我正在研究 NServiceBus 及其 ASB 传输。
场景如下:
Publisher #1 ═══╗ ╔═══ Round Robin ═══╦═══ Subscriber #1 (Service 1)
║ ║ ╚═══ Subscriber #2 (Service 1)
╠═══ Topic ═══╣
║ ║ ╔═══ Subscriber #3 (Service 2)
Publisher #2 ═══╝ ╚═══ Round Robin ═══╩═══ Subscriber #4 (Service 2)
我有一条消息需要由多个订阅者处理,但每个服务只有一个(每个服务将有多个实例 运行)。
消息 #1,需要由订阅者 #1 和 #3 处理。消息 #2,需要由订阅者 #2 和 #4 处理。消息 #3,订阅者 #1 和 #3 再次。基本上,每条消息都应该循环到订阅每条消息的每个负载平衡服务,按连接的每个服务分组。这是否可以不创建多个主题?
即使不是循环法,我也想尽最大努力在多个服务之间进行负载平衡。这可能吗?
1。主题
主题是一种 publishing/distribution 机制,每个订阅者(订阅者)将发送一次消息。
A topic subscription resembles a virtual queue that receives copies of the messages that are sent to the topic. Messages are received from a subscription identically to the way they are received from a queue...
Subscriptions support the same patterns described earlier in this section with regard to queues: competing consumer, temporal decoupling, load leveling, and load balancing.
来源:MSDN Article
您需要在竞争消费者(服务实例)之间重新使用主题订阅来实现您的场景。
Publisher #1 ═══╗ ╔═══ Subscription 1 ═══╦═══ Service 1-instance 1
║ ║ ╚═══ Service 1-instance 2
╠═══ Topic ═══╣
║ ║ ╔═══ Service 2-instance 1
Publisher #2 ═══╝ ╚═══ Subscription 2 ═══╩═══ Service 2-instance 2
一个。创建主题订阅
string connectionString = "<Secret>"
var namespaceManager =
NamespaceManager.CreateFromConnectionString(connectionString);
if (!namespaceManager.SubscriptionExists("TestTopic", "Inventory"))
{
namespaceManager.CreateSubscription("TestTopic", "Inventory");
}
乙。收听现有订阅
MessagingFactory factory = MessagingFactory.Create(uri, tokenProvider);
MessageReceiver receiver = factory.CreateMessageReceiver("TestTopic/subscriptions/Inventory");
2。队列
使用多个 Queues
也可能适合您的具体情况。每个 Queue
有多个竞争消费者(实例)将只向第一个请求并成功处理它的客户端传递一次消息。
设计则变成:
Publisher #1 ═══╗ ╔═══ Service 1 Queue ═══╦═══ Subscriber #1 (Service 1)
║ ║ ╚═══ Subscriber #2 (Service 1)
╠═══ASB═══╣
║ ║ ╔═══ Subscriber #3 (Service 2)
Publisher #2 ═══╝ ╚═══ Service 2 Queue ═══╩═══ Subscriber #4 (Service 2)
I'd like to use best effort to load balance across multiple services. Is this possible?
根据您的描述,您似乎是在尝试在任何给定服务的多个实例之间进行负载平衡,而不是在单个服务之间进行负载平衡。您可以通过 ASB 支持的竞争消费者模式开箱即用。并不是你需要工作的东西。
The problem I'm trying to solve, is I only want 1 consumer in each service consuming messages on a single topic. Is this possible with ASB?
是的,这是可能的。如果您有一个共享主题,每个服务(不是实例)都有订阅,并且包含一个始终计算为真的规则,SqlFilter
(1 = 1
)。然后每个订阅者都会得到该消息的副本。本质上,您将向所有服务广播消息。感谢竞争消费者,每个服务只有一个实例会收到该消息。
要针对特定服务,您需要创建一个附加规则来过滤掉 属性(标准 属性 或自定义服务)上的消息。例如,它可以是服务名称。
如果您不想专注于微服务的中间件,您可以看看为您做这件事的框架。这样的框架通常也倾向于提供额外的特性。例如,看看 NServiceBus 或 MassTransit。
完全免责声明 - 我正在研究 NServiceBus 及其 ASB 传输。