-
-
Notifications
You must be signed in to change notification settings - Fork 272
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Error when use @RabbitRPC in one controller and listten exchange and queue that same for all actions with diffirent routing keys #751
Comments
Same for me. In my project I have three @RabbitRPC() listeners in one file and I sometimes get listener working ok and some times errors with "invalid routing key". Here is my code and errors as example:
and here is log when I send the same message to queue: "ret: ...uuid... " - is the right processing of the listener. As you can see (I've modified matcher a little to see what its trying to match) there always different matcher for same routingKey. Is it by design? :) P.S. Also while I was looking for problem I saw project with same problem (https://github.com/pavlokobyliatskyi/demo-chat/), he just tell people to use old version :) but maybe some fix can be introduced to new versions? Interesting that not many people have this. |
The error message is in "connections.ts", looking at the v4 code in that place (line 535) instead of error there were just nack() so it was just grabbing message, check for routing key and putting it back for each of @RabbitRPC() call while it looking for perfect match?
and in v5 there are more complex check because now routingKey could be an array, but nack() function called with requeue option "false" so we get error and lost message.
https://github.com/golevelup/nestjs/blob/master/packages/rabbitmq/src/amqp/connection.ts I'm new to rabbit. What is the right way to handle messages from queue that has specific routingKey? Quick fix would be set requeue back to 'true' in nack(), but then we would have many errors in log... and maybe there should be some other logic? |
Seems like good practice is to make different queues for this messages, so I changed my code and got more queues, it works and for my small first app just to became familiar with rabbitMQ its ok :)
|
While creating separate queues for every aspect of the project might seem like a quick fix, it defeats the purpose of having routing keys in the first place. The whole idea behind using routing keys is to prevent the chaos that would arise from having too many queues, especially in large projects with 50-70 microservices. If every interaction requires a separate queue, the system becomes overly complex and hard to manage. In many cases, it’s much more efficient and organized to use different routing keys to read from the same queue, which allows for better scalability and maintainability. |
You're right, this is definitely sensible behavior. We're definitely open to contributions to improve the handling of routing keys |
Don't see API in rabbit MQ that could allow us to get/subscribe only to some routing keys in queue. So first consumer will receive the first message, if its not match needed routing key we should nack it with requeue. Each message could go to each consumer while searching for match. So for many routing keys and consumers we will create many useless data flow... Also here is quote from docs: So if needed consumer service is down now other consumers will infinitely get the message, nack it back and so on. So one queue for one consumer seems like bt design feature of rabbitMQ (or amqp). The one idea that comes to me to handle our request is to handle routing of the messge on nestjs side according to routing key. Some wrapper function that knows all functions in current app that are waiting for the message with specified routing key and will send message to that function only. |
thank you for sharing your thoughts, but unfortunately, you're mistaken in your understanding of how RabbitMQ works. The main idea behind using routing keys in RabbitMQ is precisely that different messages going into the same queue can be processed by different consumers depending on the matching routing keys. In RabbitMQ, consumers can listen to the same queue but only receive messages that match their specific routing key. This allows one queue to be efficiently used by multiple consumers, each processing only the messages relevant to them, which is the core concept of routing keys in the AMQP protocol. I opened this issue not because I want new functionality, but because there’s a bug in the current version of the nestjs-rabbitmq package that prevents routing keys from working correctly. In version 5, changes were made to the message handling logic, causing messages to be incorrectly processed and leading to errors. In version 4, everything worked as expected. What you’re suggesting—creating separate queues for each routing key—might be a workaround, but it goes against the principle of using routing keys and leads to unnecessary system complexity. My goal is to address the issue in the current implementation, not to introduce new functionality. |
@sur-ser If you have the time/willing to help us by contributing with a proper fix for this matter we would appreciate 🙏 |
Any news? After this commit it stopped working |
Seems like not everybody need it. For my small project I've decided to split to bigger number of queues. As far as I read amqp 0-9-1 specs there is only one mention of "message selectors" that could help us to not create endless loop of nack(), but no info how this should be implemented and seems like rabbitMQ does not have this in API. And we should use its API in current lib... So if this will be the real problem in my project, I guess we should implement logic on nestjs side but rabbitMQ still wil give us ALL messages from queue in FIFO order, we just search for functions by routing_key and if nothing found we should nack()
This would be good, but I can't find that type of functionality described nor in amqp protocol specs nor in rabbitMQ. All filtering with rouiting_key end up in exchange when we bind it to queue(s). The exchange is smart part that understant logic... the queue can only FIFO to consumer. |
I found a library that uses a single queue, it is specified when initializing the module with the queueName parameter |
Hello! I have manually modified to the previous behavior (pre #713), and now it does work as expected. |
when i use RabbitRPC in one controller with multiple actions like this
and create request like this
but if i keep one action it works fine or when i change que name and keep one routing key in queue it works fine
my exchange is topic
and in controller exchange and queue is same for all actions only routing key is diffirent
The text was updated successfully, but these errors were encountered: