Spring Boot (seven): RabbitMQ Detailed

A, RabbitMQ Profile

RabbitMQ i.e. a message queue, and is mainly used to achieve asynchronous decoupling applications, but also can play a message buffer, a message distribution effect.

Messaging middleware using the Internet more and more companies, messaging middleware main role is to decouple the middleware standard usage is most producers to produce messages to the queue, consumers pick up the message from the queue and processed, producers do not care who the consumer is, consumers do not care who the message in the production, so as to achieve the purpose of decoupling. In distributed systems, message queues will be used in many other aspects, such as: support, RPC calls of distributed transactions, and so on.

RabbitMQ is a messaging middleware implement AMQP (Advanced Message Queuing), and originated in the financial system to store and forward messages in a distributed system, in terms of ease of use, scalability, high availability, and so doing well. RabbitMQ is mainly to achieve two-way decoupling between the system and implementation. When a producer to produce large amounts of data, consumers can not consume fast, you need a middle layer Save the data.

The AMQP, i.e. advanced message queuing protocol, Advanced Message Queuing Protocol, is an open standard application-layer protocol for message-oriented middleware design. Message middleware mainly for decoupling between the components, sender of the message without knowing the user's presence information, and vice versa. The main features of AMQP oriented message queue, routing (including point and publish / subscribe), reliable and secure.

RabbitMQ AMQP is an open source implementation, server written in Erlang language, supports a variety of clients, such as Python, Ruby, .NET, Java, JMS, C, PHP, ActionScript, XMPP, STOMP, and support for AJAX. In a distributed system for store and forward messages, ease of use, scalability, high availability doing well.

Second, related concepts

Usually we talk about queue service, there will be three concepts: message's queue, who received the message, RabbitMQ on this basic concept, do a layer of abstraction between the message and the queue who joined the exchange switch , so that there is no message queue and are directly linked, in turn, the programming message to the message by the switch, the switch then to the queue message according to the scheduling policy.

  • P stands for the left side of the producers, that is, RabbitMQ messaging program.
  • Intermediate instant RabbitMQ, which includes switches and queue.
  • C represents the right of the consumer, which is the program to get the message from the RabbitMQ.

So, one of the more important concepts, there are four, namely: virtual hosts, switches, queues and bindings.

  • Web Hosting: Web Hosting holds a set of switches, queues and bindings. Why do we need multiple virtual hosts it? Very simple, RabbitMQ them, users can only access control granularity in virtual host. Therefore, if the need to prohibit access group A group B switches, queue, binding, it must create a virtual host for the A and B respectively, each RabbitMQ server has a default virtual host "/."
  • Switches: Exchange for forwarding messages, but it does not do store, if there is no queue bind to the Exchange, then it will lose direct messages sent by the Producer over. There is a more important concept here: routing keys. Message to the switch when the switch forwards to the corresponding queue, whether the queue to which to forward, it is necessary according to the route key.
  • Binding: the switch is required and bound to queue, which as shown above, many to many relationship.

Third, the switch (Exchange)

The main function of the switch is to receive the message and forwarded to bind the queue, the switch does not store the message after ack mode is enabled, the switch can not find the queue returns an error. Switches There are four types: Direct, Topic, Headers, Fanout

  • Direct: direct type of behavior is "matched first and then delivery", i.e. set at a routing_key binding when routing_key matching message, the switch will only be delivered to the binding queue.
  • Topic: according to the rules of forwarding messages (most flexible)
  • Headers: Set header attribute parameter type switch (not basic)
  • Fanout: forward the message to all the binding queue

1, Direct Exchange is RabbitMQ default switch model is the simplest model, based on key match to find the full text of the queue.

The first X - Q1 there is a binding key, the name is orange; X - Q2 have two binding key, the name for the black and green. When routing keys and the message corresponding to the binding key, then the message to know to which queue.

Ps: Why X Q2 to have a black, green, 2 Ge binding key it, a not on line yet? - This is mainly because there may Q3, and Q3 only information accepting black, and Q2 receive information not only black, but also to receive information of green.

2、Topic Exchange

Topic Exchange forwards the message is mainly based on wildcards. In this switch, the switch will be bound to the queue, and routing define a pattern, then, is necessary between such wildcard routing mode and route matching key switch can forward the message.

In this mode switch:

(1) routing key must be a string of characters separated by a period, for example agreements.us, agreements.eu.stockholm or the like.

(2) routing mode must contain an asterisk (*), the main route for a key word matching the specified location, for example, a routing pattern is this:. Agreements..b *, then it can only match routing key It is like this: the first word is the agreements, the fourth word is b. No. Well, it says the equivalent of one or more words, such as a matching pattern is agreements.eu.berlin. #, Then to the beginning of the routing keys agreements.eu.berlin are possible.

When the specific code is sent as the first parameter represents a switch, the second parameter represents a routing key, i.e., the third parameter message. as follows:

rabbitTemplate.convertAndSend("testTopicExchange","key1.a.c.key2", " this is  RabbitMQ!");

and direct similar topic, but supported on the mating "mode", the "dotted" in routing_key form, two wildcards can be used:

*表示一个词
#表示零个或多个词

3、Header Exchange 

headers are matched according to the rules, and compared to the direct use of topic fixedly routing_key, headers matching rule type is a custom in the queue switch binding, it will also set a key-value rule, the message comprising a set of key-value pair (headers attributes), such as a pair of key-value pairs, or all of the match, the message is delivered to the corresponding queue.

4、 Fanout Exchange 

Fanout Exchange message broadcasting mode, regardless of routing or routing mode key, the message sent will bind to it all the queues, if configured routing_key will be ignored.

Four, springboot integrated RabbitMQ

Spring Boot integration RabbitMQ is very simple, if you simply use very little configuration, Spring Boot provides a spring-boot-starter-amqp project support for a variety of messages. 

1, pom.xml

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

2, the configuration of RabbitMQ installation address, port, and account information

spring.application.name=Spring-boot-rabbitmq
spring.rabbitmq.host=192.168.0.86
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
spring.rabbitmq.password=123456

3, queue configuration

@Configuration
public class RabbitConfig {

    @Bean
    public Queue Queue() {
        return new Queue("hello");
    }
}

4, the sender

rabbitTemplate is the default implementation provided by Spring Boot

@component
public class HelloSender {
	@Autowired
	private AmqpTemplate rabbitTemplate;

	public void send() {
		String context = "hello " + new Date();
		System.out.println("Sender : " + context);
		this.rabbitTemplate.convertAndSend("hello", context);
	}
}

5, the recipient

@Component
@RabbitListener(queues = "hello")
public class HelloReceiver {

    @RabbitHandler
    public void process(String hello) {
        System.out.println("Receiver  : " + hello);
    }
}

6, the test

@RunWith(SpringRunner.class)
@SpringBootTest
public class RabbitMqHelloTest {

	@Autowired
	private HelloSender helloSender;

	@Test
	public void hello() throws Exception {
		helloSender.send();
	}
}

The sender and receiver of the queue name must be consistent, otherwise not receive

Fifth, many-to-use

A sender, N N number of recipients or senders and recipients N What happens then?

1, sent many

The above code of small transformation, the receiving end of two registered Receiver, Receiver1 and Receiver2, the argument count is added sending end, the receiving side prints the received parameters, the following are the test code, message sending one hundred, two observed performing the receiving side effect

@Test
public void oneToMany() throws Exception {
	for (int i=0;i<100;i++){
		neoSender.send(i);
	}
}

The results are as follows:

Receiver 1: Spring boot neo queue ****** 11
Receiver 2: Spring boot neo queue ****** 12
Receiver 2: Spring boot neo queue ****** 14
Receiver 1: Spring boot neo queue ****** 13
Receiver 2: Spring boot neo queue ****** 15
Receiver 1: Spring boot neo queue ****** 16
Receiver 1: Spring boot neo queue ****** 18
Receiver 2: Spring boot neo queue ****** 17
Receiver 2: Spring boot neo queue ****** 19
Receiver 1: Spring boot neo queue ****** 20

The following conclusions based on the results returned

A sender, N recipients, will be tested even send messages to recipients of the N

2, sending many to many

Copy a sender marks added at one hundred cycles to each other are alternately transmitted

@Test
public void manyToMany() throws Exception {
	for (int i=0;i<100;i++){
		neoSender.send(i);
		neoSender2.send(i);
	}
}

The results are as follows:

Receiver 1: Spring boot neo queue ****** 20
Receiver 2: Spring boot neo queue ****** 20
Receiver 1: Spring boot neo queue ****** 21
Receiver 2: Spring boot neo queue ****** 21
Receiver 1: Spring boot neo queue ****** 22
Receiver 2: Spring boot neo queue ****** 22
Receiver 1: Spring boot neo queue ****** 23
Receiver 2: Spring boot neo queue ****** 23
Receiver 1: Spring boot neo queue ****** 24
Receiver 2: Spring boot neo queue ****** 24
Receiver 1: Spring boot neo queue ****** 25
Receiver 2: Spring boot neo queue ****** 25

Conclusions: and, like many, the receiver will still be uniform message is received.

Sixth, the advanced use

1, the object support

Send and receive perfect support object springboot, no additional configuration.

//发送者
public void send(User user) {
	System.out.println("Sender object: " + user.toString());
	this.rabbitTemplate.convertAndSend("object", user);
}

...

//接收者
@RabbitHandler
public void process(User user) {
    System.out.println("Receiver object : " + user);
}

The results are as follows:

Sender object: User{name='neo', pass='123456'}
Receiver object : User{name='neo', pass='123456'}

2、Topic  Exchange

RabbitMQ topic is the most flexible way, you can bind different queues free routing_key

First topic rule configuration, where two queues to test

@Configuration
public class TopicRabbitConfig {

    final static String message = "topic.message";
    final static String messages = "topic.messages";

    @Bean
    public Queue queueMessage() {
        return new Queue(TopicRabbitConfig.message);
    }

    @Bean
    public Queue queueMessages() {
        return new Queue(TopicRabbitConfig.messages);
    }

    @Bean
    TopicExchange exchange() {
        return new TopicExchange("exchange");
    }

    @Bean
    Binding bindingExchangeMessage(Queue queueMessage, TopicExchange exchange) {
        return BindingBuilder.bind(queueMessage).to(exchange).with("topic.message");
    }

    @Bean
    Binding bindingExchangeMessages(Queue queueMessages, TopicExchange exchange) {
        return BindingBuilder.bind(queueMessages).to(exchange).with("topic.#");
    }
}

Use queueMessages match both queues, queueMessage only match "topic.message" queue

public void send1() {
	String context = "hi, i am message 1";
	System.out.println("Sender : " + context);
	this.rabbitTemplate.convertAndSend("exchange", "topic.message", context);
}

public void send2() {
	String context = "hi, i am messages 2";
	System.out.println("Sender : " + context);
	this.rabbitTemplate.convertAndSend("exchange", "topic.messages", context);
}

Send send1 will match the topic. # Topic.message and two Receiver can receive messages sent send2 only topic. # Matches all listen to eliminate only Receiver2

3、 Fanout  Exchange

Fanout is the familiar broadcast mode or subscription model, send a message to Fanout switch, this switch all queues bound to have received the message.

Fanout configuration

@Configuration
public class FanoutRabbitConfig {

    @Bean
    public Queue AMessage() {
        return new Queue("fanout.A");
    }

    @Bean
    public Queue BMessage() {
        return new Queue("fanout.B");
    }

    @Bean
    public Queue CMessage() {
        return new Queue("fanout.C");
    }

    @Bean
    FanoutExchange fanoutExchange() {
        return new FanoutExchange("fanoutExchange");
    }

    @Bean
    Binding bindingExchangeA(Queue AMessage,FanoutExchange fanoutExchange) {
        return BindingBuilder.bind(AMessage).to(fanoutExchange);
    }

    @Bean
    Binding bindingExchangeB(Queue BMessage, FanoutExchange fanoutExchange) {
        return BindingBuilder.bind(BMessage).to(fanoutExchange);
    }

    @Bean
    Binding bindingExchangeC(Queue CMessage, FanoutExchange fanoutExchange) {
        return BindingBuilder.bind(CMessage).to(fanoutExchange);
    }
}

As used herein, the A, B, C to three queues bound Fanout switch above, the transmitting side routing_key write any characters are ignored:

public void send() {
	String context = "hi, fanout msg ";
	System.out.println("Sender : " + context);
	this.rabbitTemplate.convertAndSend("fanoutExchange","", context);
}

The results are as follows:

Sender : hi, fanout msg 
...
fanout Receiver B: hi, fanout msg 
fanout Receiver A  : hi, fanout msg 
fanout Receiver C: hi, fanout msg 

The results described above bound to the fanout switch receives a message queue

 

For more information, please pay attention to "small plain warm" public No.

 

Published 110 original articles · won praise 8 · views 6899

Guess you like

Origin blog.csdn.net/guorui_java/article/details/104261716