问题
I have two services, Manager and Collector.
- Manager is subscribed to Queue
COLLECTED_USER
with routingKeyuser.collected
and invokes aUserCollected
handler. - Collector is subscribed to Queue
COLLECT_USER
with routingKeyuser.collect
and invokes aCollectUser
handler.
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
#.created
user.#
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.collect
message and invokes aCollectUser
handler - Collector's
CollectUser
handler does work, then publishes a message with routingKeyuser.collected
- Manager gets the
user.collected
message and invokes theUserCollected
handler
What actually happens:
- Manager publishes message with routingKey
user.collect
(correct) - Collector gets the
user.collect
message and invokes aCollectUser
handler (correct) - Manager also gets the
user.collect
message and invokes theUserCollected
handler with the wrong data. (wrong) - Collector's
CollectUser
handler does work, then publishes a message with routingKeyuser.collected
(correct) - Manager gets the
user.collected
message and invokes theUserCollected
handler (correct)
My Question
Why does the Manager get the user.collect
message, given:
- It's listening on the
COLLECTED_USER
queue not theCOLLECT_USER
queue, and - The Collector, which is listening on the
COLLECT_USER
queue, 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