有没有办法在Azure Service Bus中使用代理消息传递来定位特定主题订阅者?

时间:2017-01-10 18:18:10

标签: azure azureservicebus azure-servicebus-topics

首先是我的具体问题

假设我有一个主题的3个订阅者,但我只想定位一个特定的订阅者;可以这样做吗?

我想要完成的事情

收听主题的订阅者将处理消息,其中可能包括数据库访问(并且数据库可能暂时关闭)。当出现问题时,我希望能够在以后重新处理。

我知道我们可以使用Defer()来处理,但是它需要您保存消息ID。显然,如果数据库已关闭,我无法保存,因此如果我想要保留,我必须保存到另一个数据存储区。

如果那是"其他数据存储"是服务总线,那么我似乎必须为每个订阅者创建主题,这似乎有点难以管理。我的计划是将失败的请求发送到主题的死信队列。计划任务将定期到达每个主题的DLQ消息并尝试处理。如果它再次失败,我想重新提交消息并增加一个" AttemptedTries"计数器,它是消息本身的一部分。我喜欢它,如果我只针对相关订阅者,以便没有问题的主题订阅者不必处理(如果此功能不可用,我可能会添加过滤器或其他内容完成类似的)。

尝试> = maxattempts后,我将消息发送到通用"墓地" (不是特定主题)程序员可以决定如何处理消息。

这是处理它的好方法吗? ASB是否内置了一些内容?

3 个答案:

答案 0 :(得分:2)

您无法向特定订阅者发送消息,但您可以对其进行排序"定位它"用标题/值标记特定订阅者过滤消息。

现在您的方案 - 我 HIGHLY 建议不要将消息传递用作存储。空队列是一个快乐的队列。绝对不要为此目的使用DLQ。它有一个指定的角色,应该用于此。

我建议考虑推迟你的消息,并使用原子操作(ASB交易),如果你不想处理消息,你可以简单地生成一条新消息并将其排队以备将来处理序列号。这还将消除额外的计划任务中的需要以及处理DLQ时不必要的复杂性。

答案 1 :(得分:1)

我没有按照你描述的方式看到使用DLQ有什么问题。事实上,这是(部分)DLQ的原因:

  

死信队列的目的是保存无法传递给任何接收方的消息,或者仅保存无法处理的消息。然后可以从DLQ中删除消息并进行检查。应用程序可以在操作员的帮助下纠正问题并重新提交消息,记录发生错误的事实,和/或采取纠正措施。

https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-dead-letter-queues

关于过滤器:ASB提供各种订阅过滤器(SQL过滤器是最灵活的),因此您可以使用它们将消息(基于元数据等)与订户进行匹配。

如果您使用过滤器,请考虑使用单个错误队列(您称之为墓地)所有失败的消息。 IMO可能更容易从一个地方监控,检查和重新处理事情,而不是处理数以万计的DLQ。在这种情况下,失败的消息需要标记为订阅名称(失败的消息),以便在重新发送时,只有那个消息会尝试处理。

答案 2 :(得分:0)

为了添加混音,我将添加我发现的内容。您可以通过" To" BrokeredMessage的财产。

订户将需要一个过滤器(不知道为什么这不是自动的);你可以使用CorrelationFilter,例如

var filter = new CorrelationFilter {To="mySubscriber"};

或者,就我而言,我一直在寻找"直接发送给我的所有邮件或所有订阅者。我通过SqlFilter完成了这个,

 new SqlFilter($"sys.To IS NULL OR sys.To = '{_subscriptionName}'")

注意使用" sys"因为" To"是BrokeredMessage的财产。