1

首先我的具体问题

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

我想要完成的事情

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

我知道我们可以使用 Defer() 稍后处理,但是它需要您保存消息 ID。显然,如果数据库已关闭,我无法保存在那里,所以如果我想持久保存,我必须保存到另一个数据存储区。

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

在尝试 >= maxattempts 之后,我会将消息发送到一个通用的“墓地”(不是特定于主题的),程序员可以在那里决定如何处理这些消息。

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

4

3 回答 3

2

您不能将消息发送给特定订阅者,但您可以通过使用特定订阅者过滤的标题/值标记您的消息来“定位它”。

现在到您的场景 - 我强烈建议不要将消息传递用作存储。空队列是快乐队列。并且绝对不要为此目的使用 DLQ。它具有指定的角色,应该用于此目的。

我建议查看您的消息的延迟,并使用原子操作(ASB 事务),如果您不想处理消息序列号,您可以简单地生成一条新消息并将其排入队列以供将来处理。这也将消除处理 DLQ 时对额外计划任务的需求和不必要的复杂性。

于 2017-01-10T18:32:26.293 回答
1

我认为按照您描述的方式使用 DLQ 没有任何问题。事实上,这就是 DLQ 的(部分)用途:

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

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

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

如果您使用过滤器,请考虑使用单个错误队列(您称其为墓地),所有失败的消息都在其中。IMO 从一个地方监控、检查和重新处理事物可能更简单,而不是处理大量的 DLQ。在这种情况下,失败的消息需要用订阅名称(失败的消息)之类的东西来标记,这样当它被重新发送时,只有那个会尝试处理。

于 2017-01-10T19:06:17.550 回答
1

为了添加到组合中,我将添加我发现的内容。您可以通过 BrokeredMessage 的“收件人”属性寻址特定订阅者。

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

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

或者,在我的情况下,我正在寻找“向我发送直接发送给我或所有订阅者的所有消息。我通过 SqlFilter 完成了这个,

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

请注意“sys”的使用,因为“To”是 BrokeredMessage 的属性。

于 2017-01-10T21:24:39.927 回答