We're using a simple setup to use Rebus to subscribe to a queue. We need to ensure that if the RabbitMQ queue is not available (eg the service is down) that we can detect that and retry later. We also need to deal with the chance that RabbitMQ will go down after our a successful connection (its possible that the subscribe mechanism can deal with this?
Here is our sample setup;
var activator = new BuiltinHandlerActivator();
_bus = Configure
.With(activator)
.Transport(t => t.UseRabbitMq(configuration["ConnectionStrings:RabbitMQ"], "QueueName"))
.Routing(r => r.TypeBased().Map<Message>("QueueName"))
.Options(b => b.SimpleRetryStrategy("QueueName_Error"))
.Start();
activator.Register(() => messageHandler);
_bus.Subscribe<Message>().Wait();
Note we're using .net core.
Rebus refuses to start up if it cannot successfully connect to RabbitMQ. The reason is, that it needs to initialize its own input queue before it starts receiving messages.
One could argue that Rebus should simply start up and wait for the connection to be established successfully, and THEN do its initialization, but this would risk hiding a configuration error, e.g. if you deploy an application that connected to the wrong hostname.
Therefore, the broker needs to be there when your application starts up. You are then encouraged to let any errors during startup bubble out, e.g. so that whichever hosting mechanism, you're using to run your process, will detect that.
Once started, Rebus will maintain a pool of RabbitMQ connections (
IModel
s), detecting and throwing out closed or faulty connections. Other than that, Rebus relies on RabbitMQ's driver to recover from connection errors, so if you're running RabbitMQ in high availability mode, you can configure Rebus with multiple RabbitMQ connection strings (separated by;
), and then it will automatically fail over to an available node, if there is an error.Last thing: As long as you're processing messages, you're safe: Rebus will send all outgoing messages sent & published from Rebus handlers before acknowledging the incoming message. Therefore, an at least once delivery guarantee can be had throughout.
The only thing to look out for, is the initial send! That is, when you're sending the first message (e.g. from within a web request handler, or wherever that could be), you need to be sure that you have an alternative way of storing the message data, if Rebus cannot connect to any RabbitMQ nodes at all.
If Rebus cannot send the initial message, you will get an exception, and then it's up to you to do something sensible about it. A low-key pragmatic solution (at least in many first versions of systems, probably also in many production systems later on ) is to simply log the error to a file, along with the data you intended to send in the message.
I hope this clears up any questions you might have if not, please ask some more.