Springboot (Integration): RABBITMQ integration

Source: Internet
Author: User
Tags ack bind message queue switches rabbitmq

RabbitMQ is a message queue, which is mainly used to implement asynchronous and decoupled applications, but also can serve as message buffering and message distribution.

Message middleware in the use of Internet companies more and more, just saw news Ali will ROCKETMQ donated to Apache, of course, today's protagonist is still talking about RABBITMQ. The most important role of message middleware is decoupling, the most standard use of middleware is the producer of the production of messages to the queue, consumers take messages from the queue and processing, producers do not care who is to consume, consumers do not care who in the production of the message, thereby achieving the purpose of decoupling. In distributed systems, Message Queuing is also used in many other ways, such as: Support for distributed transactions, RPC calls, and so on.

Used to be activemq, in the actual production use also appeared some small problems, after the network consulted a lot of information, decided to try to use RABBITMQ to replace the ACTIVEMQ,RABBITMQ high availability, high performance, flexibility and other features attracted us, Some data were consulted to sort out this article. RABBITMQ Introduction

RABBITMQ is one of the messaging middleware implementations of the AMQP (Advanced Message Queuing Protocol) that originated in the financial system and is used to store and forward messages in distributed systems, with good performance in terms of ease of use, scalability, and high availability. RABBITMQ is mainly implemented to realize the bidirectional decoupling between the systems. When producers produce large amounts of data, consumers cannot consume quickly, and a middle tier is needed. Save this data.

AMQP, Advanced message Queuing Protocol, is an open standard for application-layer protocols designed for message-oriented middleware. Message middleware is mainly used for decoupling between components, the sender of the message does not need to know the existence of the message consumer, and vice versa. The main features of AMQP are message-oriented, queue, routing (including point-to-point and publish/subscribe), reliability, and security.

RABBITMQ is an open-source AMQP implementation that is written in Erlang and supported by a variety of clients such as Python, Ruby,. NET, Java, JMS, C, PHP, ActionScript, XMPP, stomp, etc., and support Ajax. It is used to store and forward messages in distributed system, which is very good in ease of use, extensibility, high availability and so on. Related Concepts

Usually we talk about the queue service, there are three concepts: the sender, the queue, the receiver, RabbitMQ on this basic concept, more than a layer of abstraction, between the sender and the queue, joined the switch (Exchange). In this way, the sender and the queue are not directly connected, and instead become the sender of the message to the exchanger, the switch according to the scheduling policy and then the message to the queue.


The left P represents the producer, the program that sends messages to the RabbitMQ. The middle is the RabbitMQ, which includes the switches and queues. The right side C represents the consumer, that is, the program to get the message to RabbitMQ.

Then, there are 4 more important concepts, namely: virtual host, switch, queue, and binding. Virtual Host: A virtual host holds a set of switches, queues, and bindings. Why do you need multiple virtual hosts? Very simple, RABBITMQ, the user can only be in the granularity of the virtual host permissions control. Therefore, if you need to prohibit group A from accessing the switch/queue/bindings for Group B, you must create a virtual host for A and b respectively. Each of the RABBITMQ servers has a default virtual host "/". Switch: Exchange is used to forward messages, but it does not store, and if there is no Queue bind to Exchange, it discards the messages sent by Producer directly.
Here is a more important concept: The routing key . When the message is to the switch, the interaction is forwarded to the corresponding queue, and then to which queue it is forwarded depends on the routing key. Bindings: That is, the switch needs to be bound to the queue, which, as shown in the figure above, is a many-to-many relationship. switch (Exchange)

The function of the switch is to receive the message and forward it to the bound queue, the switch does not store the message, and when ACK mode is enabled, the switch cannot find the queue and returns an error. There are four types of switches: Direct, topic, Headers and fanout direct:direct types behave as "match first, then deliver." That is, when the binding is set to a Routing_key, the routing_key of the message matches, the switch is delivered to the bound queue. Topic: Forwarding messages by rules (most flexible) Headers: Set header attribute parameter type Switch fanout: Forward message to all bound queues

Direct Exchange
Direct Exchange is the RABBITMQ default switch mode and the simplest mode to find queues based on key full-text matching.


The first x-q1 has a binding key named Orange, and X-Q2 has 2 binding keys named Black and green. When the routing key in the message corresponds to the binding key, you know which queue the message goes to.

Ps: Why X to Q2 to have black,green,2 a binding key, one not on the line. -This is mainly because there may be Q3, and Q3 only accepts Black's message, and Q2 not only accepts Black's message, but also accepts Green's message.

Topic Exchange

Topic Exchange forwarding messages are primarily based on wildcard characters. Under this switch, the queue and switch bindings define a route pattern, so the wildcard must match the routing pattern and the routing key before the switch can forward the message.

In this switch mode: The routing key must be a string of characters separated by a period (.), such as agreements.us, or Agreements.eu.stockholm. The route pattern must contain an asterisk (*), which is used primarily to match a word in the location specified by the routing key, for example, a route pattern like this: agreements. B.*, then only the routing key is matched: the first word is agreements, and the fourth Word is B. The pound sign (#) is equivalent to one or more words, such as a matching pattern is agreements.eu.berlin.#, then the routing key starting with Agreements.eu.berlin is OK.

The exact code is sent at the same time, the first parameter represents the switch, the second parameter represents routing key, and the third parameter is a message. As follows:

Rabbittemplate.convertandsend ("Testtopicexchange", "Key1.a.c.key2", "This is  rabbitmq!");

Topic is similar to direct, except that "mode" is supported on the match, and in the Routing_key form of "dot", two wildcard characters can be used: * denotes a word. #表示零个或多个词.

Headers Exchange

Headers is also based on rule matching, and headers is a type of custom matching rule that uses routing_key in a fixed manner compared to direct and topic.
When a queue is bound to a switch, a set of key-value pairs is set, and the message includes a set of key-value pairs (the headers attribute) that are delivered to the corresponding queue when the pair of key-value pairs, or all of them, match.

fanout Exchange

Fanout Exchange message Broadcast mode, regardless of the routing key or route pattern, sends the message to all queues bound to it, and if configured Routing_key is ignored. Springboot Integrated RABBITMQ

Springboot Integrated RABBITMQ is very simple, if only a simple use configuration is very small, Springboot provides various support for the SPRING-BOOT-STARTER-AMQP project to the message. Simple to use

1, the configuration Pom package, mainly add SPRING-BOOT-STARTER-AMQP support

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

2. Configuration files

Configure the installation address, port, and account information for the RABBITMQ

SPRING.APPLICATION.NAME=SPIRNG-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
    the public queue queue () {
        return new queue ("Hello");
    }

}

3. Sender

Rabbittemplate is the default implementation provided by Springboot

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);
    }

}

4. Recipient

@Component
@RabbitListener (queues = "Hello") public
class Helloreceiver {

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

}

5. Testing

@RunWith (springrunner.class)
@SpringBootTest public
class Rabbitmqhellotest {

    @Autowired
    private Hellosender Hellosender;

    @Test public
    void Hello () throws Exception {
        hellosender.send ();
    }

}

Note that the queue name of the sender and receiver must be the same, or you cannot receive many-to-many uses

What happens to a sender, n receivers or N senders and n receivers?

One-to-many sends
The above code is a small modification, the receiver registered two receiver,receiver1 and Receiver2, the sender to join the parameter count, the receiver to print the received parameters, the following is the test code, send 100 messages, to observe the performance of two receiving end

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

The results are as follows:

Receiver 1:spirng boot Neo queue ****** one
receiver 2:spirng boot neo queue ******
receiver 2:spirng boot NE o queue ******
receiver 1:spirng boot neo queue ******
receiver 2:spirng boot neo queue ******
rece Iver 1:spirng boot Neo queue ******
receiver 1:spirng boot neo queue ******
receiver 2:spirng boot Neo qu Eue ******-
receiver 2:spirng boot neo queue ******
receiver 1:spirng boot neo queue ****** 20

The following conclusions are obtained based on the results returned

A sender, n a receiver, is tested to send messages evenly to n receivers

Many-to-many sends

Copies a sender, adds tags, and alternately sends each other in 100 loops

@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:spirng boot Neo queue ******
receiver 2:spirng boot neo queue ******
receiver 1:spirng boot NE o queue ******
receiver 2:spirng boot neo queue ******
receiver 1:spirng boot neo queue ****** rece
Iver 2:spirng boot Neo queue ******
receiver 1:spirng boot neo queue ****** all
receiver 2:spirng boot Neo qu  Eue ******
receiver 1:spirng boot neo queue ******
receiver 2:spirng boot neo queue ******
receiver 1:SPIRNG boot Neo queue ******
Receiver 2:spirng boot neo queue ****** 25

Conclusion: As with a one-to-many, the receiving side will still receive the message in an even higher usage

Support for Objects

Springboot and perfect support objects are sent and received without the need for extra configuration.

Sender public
void Send (user user) {
    System.out.println ("Sender object:" + user.tostring ());
    This.rabbitTemplate.convertAndSend ("Object", user);
}

...

Recipient
@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 '}

Topic Exchange

Topic is the most flexible way in rabbitmq, which can bind different queues according to Routing_key Freedom.

First configure the topic rule, where two queues are used 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 to match two queues simultaneously, queuemessage only matches "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 to topic. #和topic. Message two receiver can receive messages, send Send2 only topic. #可以匹配所有只有Receiver2监听到消息

fanout Exchange

Fanout is the familiar broadcast mode or subscription mode that sends messages to the fanout switch, and all queues that bind the switch receive this message.

Fanout Related Configurations

 @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.bi
    nd (amessage) to (Fanoutexchange); } @Bean Binding Bindingexchangeb (Queue bmessage, Fanoutexchange fanoutexchange) {return bindingbuilder.b
    IND (Bmessage) to (Fanoutexchange); } @Bean Binding Bindingexchangec (Queue cmessage, Fanoutexchange fanoutexchange) {return bindingbuilder.b
    IND (Cmessage) to (Fanoutexchange); }

}

Here, a, B, c three queues are used to bind to the fanout switch, and any character written by the Routing_key of the sending side is 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 

The results show that the queues that are bound to the fanout switch receive messages

All the above examples, the code is referenced here

RabbitMQ Use reference

Rabbitmq:spring integrated RabbitMQ with its concept, message persistence, ACK mechanism

Author: a Pure Smile
Source: http://www.ityouknow.com/
All rights reserved, welcome to keep the original link to reprint:)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.