Skip to content

Azure Service Bus transport

Mogens Heller Grabe edited this page Feb 1, 2022 · 10 revisions

The Azure Service Bus transport uses Azure Service Bus queues and topics to do its thing. It'll do its best to emulate the behavior that you get with the other Rebus transports, but since Azure Service Bus queues do not support real transactions, you might experience a slight change in behavior.

The biggest difference in behavior from the other Rebus transports, is that - if you're in a transaction (i.e. you're in a Rebus message handler, or you've created a ITransactionContext) - all outgoing messages are stored in memory and will not actually be sent until the transaction is committed. This is done to avoid having outgoing message "escape" the transaction in the event of a rollback.

This is probably not a problem for most scenarios, it's just something to keep in mind when you're working with it.

Long-running message handlers

Since Azure Service Bus' transactional receive works by taking a "peek lock" on the incoming message, it is important that all message handlers are capable of finishing their work well within the peek lock timeout.

Rebus sets the peek lock timeout to 5 minutes, which is currently the maximum supported timeout supported by Azure Service Bus. Rebus is nice enough to correctly abandon failed messages, causing them to be immediately returned to the queue should message handling fail.

If you need longer time to finish your work, you can enable Rebus' automatic peek lock renewal like this:

Configure.With(...)
    .Transport(t => t.UseAzureServiceBus(connectionString, "queue")
                     .AutomaticallyRenewPeekLock())
    .(...)

which will cause Rebus to create an async timer along with every received message, allowing the peek lock to be periodically renewed while you work on the message.

Caution: Long-running message handlers should generally be avoided because it will be hard to determine from the outside whether something is wrong or if everything is chugging along nicely. Therefore, if you can, prefer to break down your work into several smaller bits which can complete/fail/be retried individually.

How Rebus uses Azure Service Bus topics and queues

Rebus has a pretty rigid way of using Azure Service Bus' entities (i.e. topics, queues, and subscription), so if you want to do some very custom stuff (i.e. like filtering messages at the subcription level, receiving messages directly from topics or subscriptions, or some other weird stuff like that), then Rebus' official Azure Service Bus integration might not be your cup of tea.

If you're into a sensible, simple, and consistent approach, then I think you'll find Rebus' implementation pretty neat.

Here's how it works: Each Rebus instance capable of consuming messages does so by receiving them from its input queue. This is just how it works: Rebus will never receive anything from more than 1 queue.

However, when it subscribes to something, it does so by ensuring that the relevant topic exists, and then it creates a subscription beneath that topic, configured to forward recevied messages to the subscriber's input queue, effectively binding the topic to the queue.

Consider a case where two Rebus instances with queues "subscriber1", and "subscriber2" both subscribe to the "something_happened" topic. The following entities will be created:

    subscriber1                          subscriber1
 x─────────────────┐x      Forward To  ┌──────────────┐
│                  │ │ ◄───────────────┤              │
│                  │ │                 │              │◄────────────┐    something_happened
 x─────────────────┘x                  └──────────────┘             │  ┌──────┐
                                                                    │  │      │
                                                                    │──│      │
    subscriber2                          subscriber2                │  │      │
x──────────────────┐x      Forward To  ┌──────────────┐             │  └──────┘
│                  │ │ ◄───────────────┤              │◄────────────┘
│                  │ │                 │              │                    ▲
x──────────────────┘x                  └──────────────┘                    │
                                                                           │
        ▲                                      ▲                          topic
        │                                      │
        │                                      │
     queues                              subscriptions

When a publisher then publishes a messages to the "something_happened" topic, the subscriptions "subscribe1" and "subscriber2" will get to process it, and they will both be configured to forward the message to each their respective queue.

This is also very analoguous to how RabbitMQ topic exchanges work.

Clone this wiki locally