Rebus 与 Azure 服务总线、竞争消费者和多租户

Rebus with Azure Service Bus, Competing consumers and multi-tenancy

我一直在尝试为 Azure 服务总线设置 Rebus,但我发现很难找到适合我的用例的示例,或者自己构建解决方案。

我有多个实例生成 Message1,每个实例都为特定客户端运行,但是它们都生成消息实例 class Message1。这些消息需要发送给 ASB。接下来,每个租户都有很多竞争消费者。换句话说,对于每个租户,Message1 有多个消费者,但只有一个消费者可以处理此消息。这使我能够并行处理计算繁重的工作。

通常,我会在 ASB 中为每个客户创建 1 个队列,从而保证来自不同客户的消息永远不会混淆,或被执行多次。然而,Rebus 创建主题,因此支持多个订阅。就我的理解而言,这意味着所有订阅者都会收到这些消息(因此导致重复)。当然,可以过滤这些消息。但是我没有找到任何明确的例子。这也感觉有点不安全;这些按租户的数据流需要分开,我怎么强调都不为过。

到目前为止我设法做了什么:

总而言之,我的问题是:如何设置同一条消息不能传递两次的场景,同时确保来自一个租户的消息仅由为该租户工作的消费者处理。

使用 Rebus,基本上有两种路由消息的方式:

  1. 通过发送 他们:await bus.Send(message)
  2. 通过发布 他们:await bus.Publish(message)

当您发送您的消息时,Rebus 假定消息必须发送到单个队列。 我觉得这就是你想要的。

当您发布您的消息时,Rebus 会创建一个主题(根据已发布消息的类型命名)并将其发布到该主题。订阅该主题的人都会在 her/his 输入队列中获得该消息的副本。

开箱即用,Rebus 会鼓励您将您希望发送的每种消息类型映射到特定队列,这意味着这样的配置:

Configure.With(...)
    .Transport(t => ...
    .Routing(r => r.TypeBased().Map<SomeMessage>("some-queue"))
    .Start();

将使您能够做到这一点:

await bus.Send(new SomeMessage());

然后消息会直接发送到队列"some-queue".

这听起来不像您想为每个租户创建主题 – 它们不能用于实施 "competing consumers",因为主题的目的是将每条消息的单独副本分发给每个租户订户。

但是,

队列 旨在按照您想要的方式分配工作——您只需要确保将每条消息发送到正确的队列即可。

如果您想了解更多信息,请查看 the wiki page about routing