Azure Service Bus - 循环到多个服务的主题

时间:2017-03-26 00:33:11

标签: c# azure azureservicebus azure-servicebus-topics

以下是该方案:

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再次。基本上,每条消息应循环到订阅每条消息的每个负载均衡服务,按连接的每个服务进行分组。如果不创建多个主题,这可能吗?

即使它不是循环说法,我也会尽最大努力在多个服务之间实现负载均衡。这可能吗?

2 个答案:

答案 0 :(得分:6)

1。主题

主题是一种发布/分发机制,它将按订阅(订阅者)发送一次消息。

  

主题订阅类似于接收发送到主题的消息副本的虚拟队列。从订阅接收消息的方式与从队列接收消息的方式相同......

     

订阅支持本节前面关于队列描述的相同模式:竞争消费者,时间解耦,负载均衡和负载平衡。

来源: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");
}

B中。收听现有订阅

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)

答案 1 :(得分:1)

  

我想尽最大努力在多个服务之间实现负载均衡。这可能吗?

根据您的描述,您似乎正在尝试在任何给定服务的多个实例之间进行负载平衡,而不是单个服务。您可以通过ASB支持的竞争消费者模式获得开箱即用的功能。不是你需要工作的东西。

  

我正在尝试解决的问题是,我只希望每个服务中有一个消费者在一个主题上消费消息。这可能与ASB有关吗?

是的,这是可能的。如果您有一个共享主题,每个服务订阅(不是实例)并且包含始终评估为true的规则SqlFilter1 = 1)。然后每个订阅者将获得该消息的副本。从本质上讲,您将向所有服务广播消息。感谢竞争消费者,每个服务只有一个实例会收到该消息。

要定位特定服务,您需要创建一个附加规则,用于过滤掉属性(标准属性或自定义属性)上的消息。例如,它可以是服务名称。

如果您不想专注于微服务的中间件,可以查看为您执行此操作的框架。此类框架通常也倾向于提供其他功能。例如,查看NServiceBus或MassTransit。

完全免责声明 - 我正在开发NServiceBus及其ASB传输。