问题
I have two services, Manager and Collector.
- Manager is subscribed to Queue
COLLECTED_USERwith routingKeyuser.collectedand invokes aUserCollectedhandler. - Collector is subscribed to Queue
COLLECT_USERwith routingKeyuser.collectand invokes aCollectUserhandler.
There can be multiple collectors so I have set exclusive to false (see below for code).
There are also other services that listen for events like
user.created,user.updated,user.deleted
In addition there are services that listen for more general events like
#.createduser.#
and so on.
So I am using a topic exchange.
Setup
| exchange | type | routingKey | queueName |
| -------- | ----- | -------------- | ------------- |
| MY_APP | topic | user.collect | COLLECT_USER |
| MY_APP | topic | user.collected | COLLECTED_USER |
What should happen:
- Manager publishes message with routingKey
user.collect - Collector gets the
user.collectmessage and invokes aCollectUserhandler - Collector's
CollectUserhandler does work, then publishes a message with routingKeyuser.collected - Manager gets the
user.collectedmessage and invokes theUserCollectedhandler
What actually happens:
- Manager publishes message with routingKey
user.collect(correct) - Collector gets the
user.collectmessage and invokes aCollectUserhandler (correct) - Manager also gets the
user.collectmessage and invokes theUserCollectedhandler with the wrong data. (wrong) - Collector's
CollectUserhandler does work, then publishes a message with routingKeyuser.collected(correct) - Manager gets the
user.collectedmessage and invokes theUserCollectedhandler (correct)
My Question
Why does the Manager get the user.collect message, given:
- It's listening on the
COLLECTED_USERqueue not theCOLLECT_USERqueue, and - The Collector, which is listening on the
COLLECT_USERqueue, has already handled the message.
Implementation details
I create the subscribers and publishers as follows (trimmed for relevance)
Creating a Subscriber
given the AMQP url and params url, exchange, type, routingKey, queueName and handler
const connection = await amqp.connect(url)
const channel = await connection.createChannel()
channel.assertExchange(exchange, type, { durable: true })
const result = await channel.assertQueue(queueName, { exclusive: false })
channel.bindQueue(result.queue, exchange, routingKey)
channel.prefetch(1)
channel.consume(result.queue, handler)
Creating a Publisher
given the AMQP url and params url, exchange, and type
const connection = await amqp.connect(url)
const channel = await connection.createChannel()
await channel.assertExchange(exchange, type, { durable: true })
Publishing
given the channel and params exchange, routingKey, and message
await channel.publish(exchange, routingKey, message)
Note
This question is a follow-on from RabbitMQ — Why are my Routing Keys being ignored when using topic exchange .
回答1:
I finally worked out what my problem was. A dirty exchange. While experimenting with this I'd inadvertently added an exchange that was routing messages to the wrong queue, and this was causing my confusion.
To fix it I fired up the RabbitMQ admin GUI and deleted all of the queues and let my code create the ones it needed. There was no issue with the code as outlined above.
来源:https://stackoverflow.com/questions/52942842/rabbitmq-why-does-the-wrong-subscriber-get-a-published-message