Detect and handle unresponsive RabbitMQ in .NET application

362 Views Asked by At

We recently had an outage where one of our APIs became unresponsive due to our rabbit cluster being given artificially high load. We where running out of threads in mono (.NET) and requests to the API failed. Although this is unlikely to happen again we would like to put some protection in against this. Ideally we would have calls to bus.Publish() timeout after a set amount of time but we can't workout how.

We then came across the blocked connections notification feature of RabbitMQ and thought this might help. However we can't figure out how to get at the connection object that is in the IServiceBus. So far we have tried

_serviceBus = serviceBus;
        var connection =
            ((MassTransit.Transports.RabbitMq.RabbitMqEndpointAddress) _serviceBus.Endpoint.Address)
                .ConnectionFactory.CreateConnection();  
        connection.ConnectionBlocked += Connection_ConnectionBlocked;
        connection.ConnectionUnblocked += Connection_ConnectionUnblocked;

But when we do this we get a BrokerUnreachableException which I don't understand.

My questions are, is this the right approach to detect timeouts and fail (we have a backup mechanism to collect the data in the message and repost later) and if this is correct, how do we make it work?

1

There are 1 best solutions below

0
On

I think you can manage this by combining System.Timer or Observable.Timer to schedule checks, and the check, which use request-response. Consumer for the request should be inside the same process. You can specify a cancellation token with reasonable timeout for the Request call and it you get a timeout - your messaging infrastructure is down or too busy, or your endpoint is too busy.