In our cloud environment, when a new instance is deployed, we run integration tests. However, it gets tricky because the new code is injecting messages in the queue for the service being deployed, while existing instances (previous version) are still running. We have a blue/green deployment.
Would it be possible for RabbitMQ to have many listeners listening on a queue BUT only for a specific version?
For example, all running servers would read messages for the version 2017.10.20 (previous version) or older versions, but they would not read messages that are for newer versions.
This way I could deploy a new service and none of the other droplets would read its test messages.
The new service being deployed has the same functionality as of the existing services. It both produces and consumes the same message types as the currently running services.
Looks like you have a mix of test and production messages in the same queue. If that's right, I think you should separate those.
The solution could be - you deploy your new services that publish/subscribe to integration test
set of queues that are different from production ones. When you are happy with integration tests you switch your instances to pub/sub into production queues (by sending them a command message with a new route/queue name for example) or just make those test queues new production ones, and retire the old set of services along with their queues.
For example: you have version 3.1 as current, it pubs/subs on queues/routes like my_command_a_3.1
, my_command_b_3.1
etc. Then you deploy a new 3.2 version of the environment to run in parallel with 3.1 version. All services operate on queues / routes my_command_a_3.2
and my_command_b_3.2
. Then when you are happy with 3.2 version you retire your 3.1 version along with its queues. You will need to drain those queues first (switching producers off first, waiting for queues to drain, and the switching off consumers)
The closest direct answer to your question I can think of: you can make your consumer nack a message if consumer does not support the message's version (you will need to put version on the message itself), asking broker to requeue it. Then at some point it will be processed by the new version consumer (at some point round robin algorithm will deliver that new message to the new consumer) . That's dirty in my opinion because it creates additional useless work on the broker side and for any message, you don't know when it will actually be processed and how many times it will be requeued.