Lately I’ve been messing around with RabbitMQ quite a lot. Basically it is a tool, that can make messaging between services reliable. Key word in the latter is “can”, because it doesn’t have to. As default you probably have transient messages on non-durable queue. Well, it’s allright if you only use it to make consuming those messages “neat”, but most of the time you want to use queue to make your messages persistent. But it’s not as easy as I thought it would be.
Firstly, you need to change all the settings for your queues in all the services that are using it. You can’t just make it durable from within rabbitmq itself, because it would throw an error, that incoming message is for non-durable queue and this particular message belongs to durable one with the same name.
Secondly, durable queue is not the only thing that is needed for messages to be persistent. You have to set them to be persistent, because by default they are transient and if queue service gets to be restarted, transient messages won’t be recovered.
Third and in my opinion toughest thing to be dealt with:
Let’s say that you remembered about making your queue durable and all your messages persistent. What will happen if some corrupted message gets sent to consumer? It will make an infinite loop of errors, because every time restart happens it won’t make the problem disappear. So you need to make sure you have a handler for messages that can’t be acknowledged by consumer.
That’s how I got to know about “Dead letter queue”. After you implement it basically the problem boils down to make your queue aware of this mischievous situation, so it can send corrupted message to the dead letter queue, that exists (afaik) only for debugging purposes. That way your queue gets “unlocked”, and your consumer services are working as a charm. So, if somehow my past self gets to read this blog, just google this one, when you will be thinking about how to make it all working after queue restarts 😉