springBoot integrates rabbitmq and tests five common models

Before, we recorded the native java code using rabbitmq. It is very simple, similar to the native jdbc code. The connection object is extracted as a tool class. The producer and consumer obtain the connection object through the tool class, and then obtain the channel object. Register the exchange or queue, etc., send and receive messages.
In enterprise development, we mostly use the spring framework to integrate other technologies. Springboot is more convenient to provide a variety of starters to quickly add dependencies, complete the integration, and use it out of the box.

  1. Add dependency
<dependency>
	  <groupId>org.springframework.boot</groupId>
	  <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
  1. Writing configuration
    Configuration information includes ip, port, virtual host, user name and password, and is consistent with the configuration information required by the native java code.
spring:
  application:
    name: spirngboot-rabbitmq
  rabbitmq:
    host: 192.168.20.128
    port: 5672
    virtual-host: /vh
    username: wuwl
    password: 123456
  1. Writing and testing
    This article focuses on the first five commonly used models, integrating rabbitmq on the basis of the spirngboot framework and testing it.
    Insert picture description here

(1) Hello World model

This is a simple direct connection model. The producer sends the message directly to the message queue, and the consumer gets it directly after binding the message queue, one to one.
spring-boot-starter-amqpA org.springframework.amqp.rabbit.core.RabbitTemplateclass is provided for us to facilitate our use rabbitmq, and it can be injected automatically.

Producer test class:

@SpringBootTest(classes = RabbitmqDemoApplication.class)
@RunWith(SpringRunner.class)
public class RabbitmqDemoApplicationTests {
    
    

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Test
    public void testHelloQueues(){
    
    
            rabbitTemplate.convertAndSend("hello","hello world");
    }
}

The producer sends a message to the queue named hello, but in the absence of a consumer, the producer has no meaning. In addition, convertAndSendthe first parameter of the method does not mean the message queue, but routingKey, we find the originally defined interface based on the source code and see the following:

/**
	 * Convert a Java object to an Amqp {@link Message} and send it to a default exchange
	 * with a specific routing key.
	 *
	 * @param routingKey the routing key
	 * @param message a message to send
	 * @throws AmqpException if there is a problem
	 */
	void convertAndSend(String routingKey, Object message) throws AmqpException;

The second parameter is the Objecttype, which means that any type of object can be passed. This method converts the object into a Amqpmessage and sends it to a default exchange, and routingKeyis the content of the first parameter, without mentioning the message queue information. However, we can analyze that, here routingKeyand queuesshould be the same name.

Consumer category:

@Component
@RabbitListener(queuesToDeclare = @Queue("hello"))
public class HelloQueuesConsumer {
    
    
    @RabbitHandler
    public void consume(String msg){
    
    
        System.out.println("消费消息:" + msg + " " + System.currentTimeMillis());
    }
}

The above code is equivalent to:

@Component
public class HelloQueuesConsumer {
    
    
    @RabbitListener(queuesToDeclare = @Queue("hello"))
    public void consume(String msg){
    
    
        System.out.println("消费消息:" + msg + " " + System.currentTimeMillis());
    }
}
  • @RabbitListener can be marked on the class, it needs to be used with @RabbitHandler annotation
  • @RabbitListener is marked on the class to indicate that when a message is received, it will be handed over to the @RabbitHandler method for processing, which method is used for processing, according to the parameter type after MessageConverter conversion

Start the test method directly, that is, the producer, you can see that the
Insert picture description hereconsumer has received the information in the message queue and printed it.

(2) Work queues model

Producer test method, the class is consistent with the first model

@Test
public void testWorkQueues(){
    
    
    for (int i = 0; i < 20; i++) {
    
    
        rabbitTemplate.convertAndSend("work","work index " + i);
    }
}

Consumer category:

@Component
public class WorkQueuesConsumer {
    
    

    @RabbitListener(queuesToDeclare = @Queue("work"))
    public void consume1(String msg){
    
    
        System.out.println("consumer1消费消息:" + msg);
    }

    @RabbitListener(queuesToDeclare = @Queue("work"))
    public void consume2(String msg){
    
    
        System.out.println("consumer2消费消息:" + msg);
    }
}

Start the producer test method:
Insert picture description hereConsumer 1 and Consumer 2 evenly distribute the message tasks in the queue. Even if the execution efficiency of the two is inconsistent, they are equally distributed.

(3) Publish/Subscribe model

Producer test method:

for (int i = 0; i < 20; i++) {
    
    
    rabbitTemplate.convertAndSend("amq.fanout","","fanout msg " + i);
}

Consumer category:

@Component
public class FanoutQueuesConsumer {
    
    
    @RabbitListener(bindings = {
    
    
            @QueueBinding(value = @Queue,
                    exchange = @Exchange(
                            value = "amq.fanout",
                            type = "fanout"))})
    public void consume1(String msg) {
    
    
        System.out.println("consumer1消费消息:" + msg);
    }

    @RabbitListener(bindings = {
    
    
            @QueueBinding(value = @Queue,
                    exchange = @Exchange(
                            value = "amq.fanout",
                            type = "fanout"))})
    public void consume2(String msg) {
    
    
        System.out.println("consumer2消费消息:" + msg);
    }
}

Note the switch information here

Start the producer test method:
Insert picture description hereOnly part of the print information is pasted here. Two consumers get the same message. The producer sends the message to the exchange, which is sent to all temporary message queues registered to the exchange, and then the consumer Get the messages in the queue.

(4) Routing model

Producer test method:

@Test
public void testDirectQueues(){
    
    
    rabbitTemplate.convertAndSend("amq.direct","info","routingKey is info");
    rabbitTemplate.convertAndSend("amq.direct","warn","routingKey is warn");
    rabbitTemplate.convertAndSend("amq.direct","error","routingKey is error");
}

Routing has also become a fanout model, and the corresponding switch type is direct

Consumer category:

@Component
public class DirectQueuesConsumer {
    
    
    @RabbitListener(bindings = {
    
    
            @QueueBinding(value = @Queue,
                    exchange = @Exchange(
                            value = "amq.direct",
                            type = "direct"),
                    key = {
    
    "info", "warn", "error"})})
    public void consume1(String msg) {
    
    
        System.out.println("consumer1消费消息:" + msg);
    }

    @RabbitListener(bindings = {
    
    
            @QueueBinding(value = @Queue,
                    exchange = @Exchange(
                            value = "amq.direct",
                            type = "direct"),
                    key = "error")})
    public void consume2(String msg) {
    
    
        System.out.println("consumer2消费消息:" + msg);
    }
}

Start the producer test class:
Insert picture description here
Consumer one is configured with three types of routingKey, so all three types of messages can be received, and consumer two can only receive messages of error type.

(5) Topic model

Producer test method:

@Test
public void testTopicQueues(){
    
    
    rabbitTemplate.convertAndSend("amq.topic","file.info","routingKey is info");
    rabbitTemplate.convertAndSend("amq.topic","file.warn","routingKey is warn");
    rabbitTemplate.convertAndSend("amq.topic","file.error","routingKey is error");
}

Consumer category:

@Component
public class TopicQueuesConsumer {
    
    
    @RabbitListener(bindings = {
    
    
            @QueueBinding(value = @Queue,
                    exchange = @Exchange(
                            value = "amq.topic",
                            type = "topic"),
                    key = {
    
    "#"})})
    public void consume1(String msg) {
    
    
        System.out.println("consumer1消费消息:" + msg);
    }

    @RabbitListener(bindings = {
    
    
            @QueueBinding(value = @Queue,
                    exchange = @Exchange(
                            value = "amq.topic",
                            type = "topic"),
                    key = "*.error")})
    public void consume2(String msg) {
    
    
        System.out.println("consumer2消费消息:" + msg);
    }
}

Start the producer test method:
Insert picture description hereConsumer 1 is configured routingKeyto #accept any type of message, which *represents a word, and Consumer 2 can accept messages with any word added .erroras routingKey.

Guess you like

Origin blog.csdn.net/qq_41885819/article/details/112933785