简体   繁体   中英

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

I have been trying to setup Rebus for Azure Service Bus, but I find it hard to find examples that fit my use case, or to construct a solution by myself.

I have multiple instances producing Message1 , each instance runs for a specific client, however they all produce instances of the message class Message1 . These messages need to be sent to ASB. Next, I have a lot of competing consumers for each tenant. In other words, for each tenant there are multiple consumers of Message1 but only one consumer can handle this message. This enables me to parallelize computationally heavy work.

Normally, I would create 1 queue in ASB per customer, therefore guaranteeing that messages from different customers will never get mixed up, or get executed more than once. Rebus however creates topics, therefore enabling multiple subscriptions. As far as my understanding goes, this means that all subscribers will get these messages (therefore causing duplication). Of course, one could filter on these messages. But I did not find any clear examples of this. Also this feels a bit unsafe; I cannot stress enough that these per-tenant data flows need to be separated.

What I managed to do up until now:

  • Create separate topics per tenant
  • Create separate (error-)queues per tenant, however, I am not sure how Rebus uses these queues, since messages are published on topics

In summary, my question is: how do I set up a scenario where the same message cannot be delivered twice, while also ensuring messages from one tenant will only be handled by consumers working for that tenant.

With Rebus, there's basically TWO WAYS of routing messages:

  1. by sending them: await bus.Send(message)
  2. by publishing them: await bus.Publish(message)

When you send your message, Rebus assumes that the message must be sent to a single queue. It sounds to me like this is what you want.

When you publish your message, Rebus creates a topic (naming it from the type of the published message) and publishes it to that topic. Whoever subscribed to that topic gets a copy of the message in her/his input queue.

Out of the box, Rebus will encourage you to map each message type, that you wish to SEND , to a specific queue, meaning that a configuration like this:

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

will enable you to do this:

await bus.Send(new SomeMessage());

and then the message will be sent directly to the queue "some-queue".

It does not sound to me like you want to create topics for each of your tenants – they cannot be used to implement "competing consumers", as the purpose of topics is to distribute separate copies of each message to each subscriber.

Queues , however, are meant for distributing work the way you want – you just need to ensure that each message gets sent to the right queue.

If you want to read more, check out the wiki page about routing .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM