有没有一种方法可以通过Azure Service Bus中的代理消息将特定主题订阅者作为目标?

有没有一种方法可以通过Azure Service Bus中的代理消息将特定主题订阅者作为目标?,azure,azureservicebus,azure-servicebus-topics,Azure,Azureservicebus,Azure Servicebus Topics,首先是我的具体问题 假设我有3个主题订阅者,但我只想针对一个特定订阅者;这能做到吗 我正在努力实现的目标 收听主题的订阅者将处理消息,其中可能包括数据库访问(数据库可能暂时关闭)。当事情出错时,我希望能够在以后重新处理 我知道我们可以稍后使用Defer()进行处理,但是它需要您保存消息id。很明显,如果数据库关闭,我无法保存在那里,因此如果我想持久化,我必须保存到另一个数据存储 如果“其他数据存储”是服务总线,那么似乎我必须为我的每个订阅者创建主题,这似乎有点难以管理。我的计划是将失败的请求发送

首先是我的具体问题

假设我有3个主题订阅者,但我只想针对一个特定订阅者;这能做到吗

我正在努力实现的目标

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

我知道我们可以稍后使用Defer()进行处理,但是它需要您保存消息id。很明显,如果数据库关闭,我无法保存在那里,因此如果我想持久化,我必须保存到另一个数据存储

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

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


这是处理问题的好方法吗?ASB是否有一些内置功能?

您不能向特定订阅者发送消息,但您可以通过在消息上加盖特定订阅者筛选依据的标题/值来排序“目标”

现在谈谈您的情况-我强烈建议不要将消息用作存储。空队列是愉快的队列。而且也绝对不要为此目的使用DLQ。它有一个指定的角色,应该用于该角色


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

您不能向特定订阅者发送消息,但您可以通过在消息上加盖特定订阅者筛选依据的标题/值来排序“目标”

现在谈谈您的情况-我强烈建议不要将消息用作存储。空队列是愉快的队列。而且也绝对不要为此目的使用DLQ。它有一个指定的角色,应该用于该角色


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

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

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

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


如果你使用过滤器,考虑使用一个错误队列(你称之为墓地),在那里所有失败的消息都会消失。在我看来,从一个地方监控、检查和重新处理事情可能比处理无数的DLQ更简单。在这种情况下,失败的消息需要用订阅名称(失败的消息)等标记,以便在重新发送时,只有该消息会尝试处理

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

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

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


如果你使用过滤器,考虑使用一个错误队列(你称之为墓地),在那里所有失败的消息都会消失。在我看来,从一个地方监控、检查和重新处理事情可能比处理无数的DLQ更简单。在这种情况下,失败的消息需要用订阅名称(失败的消息)等标记,以便在重新发送时,只有该消息会尝试处理

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

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

var filter = new CorrelationFilter {To="mySubscriber"};
或者,在我的例子中,我在寻找“将所有直接发送给我或所有订阅者的消息发送给我。我通过SqlFilter实现了这一点

 new SqlFilter($"sys.To IS NULL OR sys.To = '{_subscriptionName}'")
注意使用“sys”,因为“To”是BrokeredMessage的属性。

要添加到m