RabbitMQ - Send message to a particular consumer i

2020-07-20 03:35发布

This is the scenario - There are multiple app servers. Browser can connect via websocket to any app server.

The app servers (consumers) are all listening on a particular queue. As soon as a web socket connection is received, the particular app server binds the queue with a routing key {userId} to a direct exchange.

I want a message sent to the direct exchange with the routing key {userId} to be received by only the particular app server where the binding has occured.

Is a direct exchange the right exchange to use in this case? Or should some other type of exchange be used?

I'm using spring-amqp to create dynamic bindings when a websocket comes in

// create the RabbitMq queue and bind to it
String routingKey = MessageConstants.getRoutingKeyForUserRecommendationQueue(user);
Binding userRecommendationBinding = BindingBuilder.bind(userRecommendationsQueue).
    to(directExchange).with(routingKey);
amqpAdmin.declareBinding(userRecommendationBinding);

2条回答
孤傲高冷的网名
2楼-- · 2020-07-20 04:15

Send message to a particular consumer in a queue

this is not possible. any consumer connected to a queue has a chance of consuming any given message in the queue

I want a message sent to the direct exchange with the routing key {userId} to be received by only the particular app server where the binding has occured.

you can do this by creating exclusive / autoDelete queues for your consumer, with a binding that directs all messages for that consumer to that queue.

Is a direct exchange the right exchange to use in this case?

either a direct exchange or a topic exchange is fine. direct exchange is slightly easier to understand, but topic exchange is more flexible

查看更多
乱世女痞
3楼-- · 2020-07-20 04:17

Actually you go right way.

And yes: Direct Exchange with an appropriate binding should save you.

See more info in the RabbitMQ Tutorial: http://www.rabbitmq.com/tutorials/tutorial-four-java.html

Also take a look into Spring AMQP Samples on the matter: https://github.com/spring-projects/spring-amqp-samples/tree/master/rabbitmq-tutorials

UPDATE

Unfortunately that is not what is happening. The messages seem to go randomly to any consumer, and not just the consumer that created the binding.

M-m-m. That's possible, because we route only my the key, but after that the message is placed to the queue, which may have several consumers on different machines.

In this case yes: the dynamic binding doesn't help.

You should consider to create an unique new queue (auto-deleted is fine) and bind and listen exactly from that. The SimpleMessageListenerContainer supports addQueues() at runtime to start a new consumer for a new queue.

I think that should work for you.

You still shouldn't do anything on the producer side: the same exhchange and routingKey logic.

查看更多
登录 后发表回答