The publish and subscribe model is shown in the figure below:
You can see that in the subscription model, there is an exchange role, and the process changes slightly:
-
Publisher: the producer, that is, the program that sends the message, but it is no longer sent to the queue, but to X (switch)
-
Exchange: switch, X in figure. On the one hand, it receives messages sent by producers. On the other hand, you know how to process messages, such as delivering to a special queue, delivering to all queues, or discarding messages. How to operate depends on the type of exchange. There are three types of exchange:
-
Fanout: broadcast and deliver messages to all queues bound to the switch
-
Direct: direct, which sends messages to queues that match the specified routing key
-
Topic: wildcard, which gives the message to the queue conforming to the routing pattern
-
-
Consumer: the consumer, as before, subscribes to the queue without change
-
Queue: as before, the message queue receives messages and caches messages.
Exchange (switch) is only responsible for forwarding messages and does not have the ability to store messages. Therefore, if there is no queue bound to exchange or no queue that meets the routing rules, the messages will be lost!
Fanout, English translation is fan out. I think it is more appropriate to call broadcast in MQ.
In broadcast mode, the message sending process is as follows:
-
1) There can be multiple queues
-
2) Each queue is bound to an Exchange (switch)
-
3) The message sent by the producer can only be sent to the switch. The switch determines which queue to send, but the producer cannot decide
-
4) The switch sends messages to all queues that have been bound
-
5) Consumers who subscribe to the queue can get the message
1. Declare queues and switches
Spring provides an Exchange interface to represent all different types of switches:
Create a class in consumer to declare queues and switches:
import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.BindingBuilder; import org.springframework.amqp.core.FanoutExchange; import org.springframework.amqp.core.Queue; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class FanoutConfig { /** * Claim switch * @return Fanout Type switch */ @Bean public FanoutExchange fanoutExchange(){ return new FanoutExchange("fanout.exchange"); } /** * 1st queue */ @Bean public Queue fanoutQueue1(){ return new Queue("fanout.queue1"); } /** * Bind queue and switch */ @Bean public Binding bindingQueue1(Queue fanoutQueue1, FanoutExchange fanoutExchange){ return BindingBuilder.bind(fanoutQueue1).to(fanoutExchange); } /** * 2nd queue */ @Bean public Queue fanoutQueue2(){ return new Queue("fanout.queue2"); } /** * Bind queue and switch */ @Bean public Binding bindingQueue2(Queue fanoutQueue2, FanoutExchange fanoutExchange){ return BindingBuilder.bind(fanoutQueue2).to(fanoutExchange); } }
2. Message sending
@Test public void testFanoutExchange() { // Queue name String exchangeName = "fanout.exchange"; // news String message = "hello, everyone!"; rabbitTemplate.convertAndSend(exchangeName, "", message); }
3. Message reception
Add two methods to the springrabbit listener of the consumer service as consumers:
@RabbitListener(queues = "fanout.queue1") public void listenFanoutQueue1(String msg) { System.out.println("Consumer 1 received Fanout Message:[" + msg + "]"); } @RabbitListener(queues = "fanout.queue2") public void listenFanoutQueue2(String msg) { System.out.println("Consumer 2 received Fanout Message:[" + msg + "]"); }
4. Summary
What is the role of the switch?
-
Receive messages from publisher
-
Route messages according to rules to the queue to which they are bound
-
Unable to cache message, routing failed, message lost
-
FanoutExchange routes messages to each bound queue
What are the beans that declare queues, switches, and binding relationships?
-
Queue
-
FanoutExchange
-
Binding