introduce

RabbitMQ is a Message Queue developed by Erlang based on the Advanced Message Queue (AMQP) protocol. It is a communication method between applications. Message queues are widely used in distributed system development.

RabbitMQ official address: http://www.rabbitmq.com/

RabbitMQ provides six modes: simple, Work, Publish/Subscribe, Routing, Topics, and RPC (remote, not MQ; No introduction);

The installation

For convenience, it is recommended that you use docker installation mode, docker installation related commands are as follows:

  • Download mirror
Docker pull the rabbitmq: 3.7.7 - management

Copy the code
  • Create the instance and start it
docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 -v ~/docker/rabbitmq/data:/var/lib/rabbitmq --hostname myRabbit -e RABBITMQ_DEFAULT_VHOST=my_vhost -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin The rabbitmq: 3.7.7 - management

Copy the code

Related components

Insert a picture description here
  • Producer: Is the producer of the message
  • Consumer: A handler of messages
  • Exchange: A bridge between producers and queues. Messages sent by producers are sent to queues through the exchange
  • Queue: A place where messages are stored, waiting to be retrieved by consumers
  • Hosts: All queues and switches are hung on hosts, and a broker can create multiple independent hosts
  • Broker (server) : Switches, queues, and masters make up the broker, which acts as a bridge between producers and consumers

Five pattern invocation examples

Introduction of depend on

   <dependencies>

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter</artifactId>

        </dependency>



        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-test</artifactId>

            <scope>test</scope>

        </dependency>



        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-amqp</artifactId>

        </dependency>

    </dependencies>

Copy the code

Write the configuration file application.yml

spring:

  rabbitmq:

    host: 127.0. 01.

    port: 5672

Virtual-host: my_vhost # This is a host created by myself, please fill in your own, be careful not to include /

    username: lezai

    password: lezai

    publisher-returns: true

    publisher-confirm-type: simple

Copy the code

Simple message pattern

Simple messages use the default switch, and the routing_key is the same as the queue name consumed

  • The producer creates the MQ configuration file
@Configuration

public class RabbitMQConfig {

    public static final String QUEUE_TEST_SIMPLE_MODE = "queue_test_simple_mode";

// Declare a queue

    @Bean("queueTestSimpleMode")

    public Queue queueTestSimpleMode(a){

        return QueueBuilder.durable(QUEUE_TEST_SIMPLE_MODE).build();

    }

}

Copy the code
  • Write code to send simple messages on the producer side
@SpringBootTest

class RabbitmqProductApplicationTests {

    @Autowired

    private RabbitTemplate rabbitTemplate;

    @Test

    public void testSimpleMode(a) {

        rabbitTemplate.convertAndSend("",RabbitMQConfig.QUEUE_TEST_SIMPLE_MODE,"Test simple mode");

    }

Copy the code
  • When we look at the admin console, we see the queue we created, and there is already a message waiting to be consumed in the queue

  • Create consumers

@Component

public class RabbitMQListener {

    @RabbitListener(queues = "queue_test_simple_mode")

    public void onMessage(Message message, Channel channel) throws Exception {

        System.out.println("Received a message:" + new String(message.getBody()));

    }

}

Copy the code

Work queue mode

This is the same as the simple pattern, where multiple consumers are created to listen to queues, and MQ polls to push messages to multiple listeners

@Component

public class RabbitMQListener {

    @RabbitListener(queues = "queue_test_simple_mode")

    public void onMessage(Message message, Channel channel) throws Exception {

        System.out.println("Received a message:" + new String(message.getBody()));

    }

        @RabbitListener(queues = "queue_test_simple_mode")

    public void onMessage2(Message message, Channel channel) throws Exception {

        System.out.println("Received a message:" + new String(message.getBody()));

    }

}

Copy the code

Publish/Subscribe Publish and Subscribe mode

Publish subscribe uses broadcast mode, all queues bound to this type of switch will receive messages switch type “fanoutExchange”

  • Producer profile
@Configuration

public class RabbitMQConfig {

    public static final String QUEUE_TEST_FANOUT_MODE_1 = "queue_test_fanout_mode_1";

    public static final String QUEUE_TEST_FANOUT_MODE_2 = "queue_test_fanout_mode_2";

    public static final String EXCHANGE_TEST_FANOUT_MODE = "exchange_test_fanout_mode";



    // Declare a queue

    @Bean("queueTestFANOUTMode1")

    public Queue queueTestFANOUTMode1(a) {

        return QueueBuilder.durable(QUEUE_TEST_FANOUT_MODE_1).build();

    }

    // Declare a queue

    @Bean("queueTestFANOUTMode2")

    public Queue queueTestFANOUTMode2(a) {

        return QueueBuilder.durable(QUEUE_TEST_FANOUT_MODE_2).build();

    }

    // Declare a switch

    @Bean("exchangeTestFANOUTMode")

    public Exchange exchangeTestFANOUTMode(a) {

        return ExchangeBuilder.fanoutExchange(EXCHANGE_TEST_FANOUT_MODE).durable(true).build();

    }



    // The routingKey is empty in the bind switch and queue subscription mode

    @Bean

    public Binding itemQueueExchange1(@Qualifier("queueTestFANOUTMode1") Queue queue,

                                     @Qualifier("exchangeTestFANOUTMode") Exchange exchange)
{

        return BindingBuilder.bind(queue).to(exchange).with("").noargs();

    }

    @Bean

    public Binding itemQueueExchange2(@Qualifier("queueTestFANOUTMode2") Queue queue,

                                     @Qualifier("exchangeTestFANOUTMode") Exchange exchange)
{

        return BindingBuilder.bind(queue).to(exchange).with("").noargs();

    }

}

Copy the code
  • Write code for producers to send messages
    @Test

    public void testFanoutMode(a) {

        rabbitTemplate.convertAndSend("exchange_test_fanout_mode".""."Test publish subscribe model");

    }

Copy the code
  • Looking at the admin console, there is a switch and a queue, and each queue has a message that we just created

  • The consumer side of the code, the consumer side is always listening to the queue, so the way is the same as before

@Component

public class RabbitMQListener {

    @RabbitListener(queues = "queue_test_fanout_mode_1")

    public void onMessage1(Message message, Channel channel) throws Exception {

        System.out.println("Received message from queue queue_test_FANout_mode_1:" + new String(message.getBody()));

    }

    @RabbitListener(queues = "queue_test_fanout_mode_2")

    public void onMessage2(Message message, Channel channel) throws Exception {

        System.out.println("Received message from queue queue_test_FANout_mode_2:" + new String(message.getBody()));

    }

}

Copy the code

Routing Routing mode

The routing mode uses a directional switch to forward messages. When a queue is bound to a directional switch, a Routingkey is provided. If a user carries a Routingkey on the switch that sends messages, the corresponding queue will be matched according to the Routingkey.

  • Producer profile writing
@Configuration

public class RabbitMQConfig {



    public static final String QUEUE_TEST_ROUTING_MODE_1 = "queue_test_routing_mode_1";

    public static final String QUEUE_TEST_ROUTING_MODE_2 = "queue_test_routing_mode_2";

    public static final String EXCHANGE_TEST_ROUTING_MODE = "exchange_test_routing_mode";

    

    // Declare a queue

    @Bean("queueTestROUTINGMode1")

    public Queue queueTestROUTINGMode1(a) {

        return QueueBuilder.durable(QUEUE_TEST_ROUTING_MODE_1).build();

    }

    // Declare a queue

    @Bean("queueTestROUTINGMode2")

    public Queue queueTestROUTINGMode2(a) {

        return QueueBuilder.durable(QUEUE_TEST_ROUTING_MODE_2).build();

    }

    // Declare a switch

    @Bean("exchangeTestROUTINGMode")

    public Exchange exchangeTestROUTINGMode(a) {

        return ExchangeBuilder.directExchange(EXCHANGE_TEST_ROUTING_MODE).durable(true).build();

    }



    // Bind switches to queues

    // The routingKey is specified as order, which means that only messages with a RoutingKey as order can be matched

    @Bean

    public Binding itemQueueExchange3(@Qualifier("queueTestROUTINGMode1") Queue queue,

 @qualifier ("exchangeTestROUTINGMode") Exchange Exchange){@qualifier ("exchangeTestROUTINGMode")

        return BindingBuilder.bind(queue).to(exchange).with("order").noargs(a)
;

    }

    

    @Bean

    public Binding itemQueueExchange4(@Qualifier("queueTestROUTINGMode2") Queue queue,

                                      @Qualifier("exchangeTestROUTINGMode") Exchange exchange)
{

        return BindingBuilder.bind(queue).to(exchange).with("member").noargs();

    }

}

Copy the code
  • Write code for producers to send messages

If the routingkey is set to order, the routingkey must be set to order in the queue_test_ROUTing_mode_1 queue. If the routingkey is set to order in the queue_test_ROUTing_mode_1 queue, the routingkey must be set to order.

   @Test

    public void testRoutingMode(a) {

        rabbitTemplate.convertAndSend("exchange_test_routing_mode"."order"."Test routing mode");

    }

Copy the code
  • Looking at the admin console, only queue_test_ROUTing_mode_1 has one message waiting to be consumed

  • Consumer code

    @RabbitListener(queues = "queue_test_routing_mode_1")

    public void onMessage3(Message message, Channel channel) throws Exception {

        System.out.println("Received message from queue queue_test_ROUTing_mode_1:" + new String(message.getBody()));

    }

    @RabbitListener(queues = "queue_test_routing_mode_2")

    public void onMessage4(Message message, Channel channel) throws Exception {

        System.out.println("Received message from queue queue_test_ROUTing_mode_2:" + new String(message.getBody()));

    }

Copy the code

Topics mode

Topics switches are the same as directional switches. The only difference is that when a Routingkey is parsed, the directional switch will find the corresponding queue based on the Routingkey in the message. This value is fixed. However, the topic pattern is also called the wildcard pattern, and the routingkey specified at binding time can exist as a wildcard. There are only two wildcard symbols:

# represents one or more words such as ABC.# will match either abc.d or abc.d.f

* stands for a word such as. ABC.* matches only messages from abc.a or abc.f,

The code logic is the same as the routing pattern, which will not be demonstrated. The complete example code has been uploaded to git library, welcome to request:

Complete code collection

https://gitee.com/yangleliu/code_learning.git

There will be a large number of interview materials and architect must-see books waiting for you to choose, including Java foundation, Java concurrency, micro services, middleware and more information waiting for you to take oh.