Entering RabbitMQ (1)

preface

RabbitMq as the current mainstream MQ(Message Queue) more fire one, many beginners will not use MQ or do some specific business in MQ. This article is good enough to let xiao Bai understand how MQ is used.

The installation

The environment

  • SpringBoot 2.3.1. RELEASE
  • Rabbit MQ

The installation start

Here I directly use Docker installation is more convenient

docker pull rabbitmq
docker run -d --name rabbit -e RABBITMQ_DEFAULT_USER=root -e RABBITMQ_DEFAULT_PASS=123456 -p 15672:15672 -p 5672:5672 rabbitmq
Copy the code

You need to enter the container once to access the RabbitMQ background

docker exec -it rabbitmq_id /bin/bash
rabbitmq-plugins enable rabbitmq_management
exit
Copy the code
<dependency>
    <groupId>com.rabbitmq</groupId>
    <artifactId>amqp-client</artifactId>
</dependency>Or (I'll use the second because I'm too lazy to write @value)<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
Copy the code
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=root
spring.rabbitmq.password=123456
Copy the code
/ * * *@author Kakki
 * @version 1.0
 * @createThe 2021-06-18 now * /
@Configuration
@AutoConfigureAfter
public class RabbitMqConfig {

    @Autowired
    private RabbitProperties rabbitProperties;

    @Bean
    public CachingConnectionFactory cachingConnectionFactory(a) {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost(rabbitProperties.getHost());
        connectionFactory.setPort(rabbitProperties.getPort());
        connectionFactory.setUsername(rabbitProperties.getUsername());
        connectionFactory.setPassword(rabbitProperties.getPassword());
        connectionFactory.setAutomaticRecoveryEnabled(true);
        connectionFactory.setTopologyRecoveryEnabled(true);
        return newCachingConnectionFactory(connectionFactory); }}@AutoConfigureAfter(RabbitMqConfig.class)
@Configuration
public class QueueAutoConfig implements InitializingBean {

    @Autowired
    private AmqpAdmin amqpAdmin;

    @Override
    public void afterPropertiesSet(a) throws Exception {
        Arrays.stream(QueueInfo.values()).forEach(v->{
            Queue queue = new Queue(v.getQueue());
            amqpAdmin.declareQueue(queue);
            CustomExchange exchange = newCustomExchange(v.getExchange(), v.getExchangeType()); amqpAdmin.declareExchange(exchange); Binding binding = BindingBuilder.bind(queue).to(exchange).with(v.getRoutingKey()).noargs(); amqpAdmin.declareBinding(binding); }); }}@AllArgsConstructor
@Getter
public enum QueueInfo {
    FIRST(
            "FIRST_QUEUE"."FIRST_EXCHANGE"."FIRST_ROUTING_KEY"."fanout"
    );

    private final String queue;
    private final String exchange;
    private final String routingKey;
    private final String exchangeType;

}
Copy the code

How do you send and receive messages

Send a message

/** * unit tests */
@Test
public void sendMq(a) {
    String s = "Hello Kakki";
    rabbitTemplate.convertAndSend(QueueInfo.FIRST.getQueue(), s);
    while(true);
}
Copy the code

Receive a message

/ * * *@author Kakki
 * @version 1.0
 * @createThe 2021-06-18 "* /
@Component
@Slf4j
public class MqCustomer {
    @RabbitListener(queues = {"FIRST_QUEUE"})
    public void handler(Message message) { // Message can also be received directly using String
        log.info("[News comes]:{}".newString(message.getBody(), StandardCharsets.UTF_8)); }}Copy the code

Look at the parameters when you use them

  • We’re using the convertAndSend() method, which takes a lot of arguments, and you can see that if our argument is a RoutingKey we can send it directly to the listening queue. Why? The argument above is a routingKey. We’ll talk about that later.

Use different switch types to send messages

/** * unit tests */
@Test
public void sendMq(a) {
    rabbitTemplate.convertAndSend(QueueInfo.FANOUT.getExchange(), StringUtils.EMPTY, "No fanout routingKey");
    rabbitTemplate.convertAndSend(QueueInfo.FANOUT.getExchange(), QueueInfo.FANOUT.getRoutingKey(), "No fanout routingKey");
    rabbitTemplate.convertAndSend(QueueInfo.DIRECT.getExchange(), QueueInfo.DIRECT.getRoutingKey(), "DIRECT routingKey");
    rabbitTemplate.convertAndSend(QueueInfo.TOPIC1.getExchange(), QueueInfo.TOPIC1.getRoutingKey(), String.format("TOPIC1 routingKey % s", QueueInfo.TOPIC1.getRoutingKey()));
    rabbitTemplate.convertAndSend(QueueInfo.TOPIC2.getExchange(), QueueInfo.TOPIC2.getRoutingKey(), String.format("TOPIC2 routingKey % s", QueueInfo.TOPIC2.getRoutingKey()));
    rabbitTemplate.convertAndSend(QueueInfo.TOPIC3.getExchange(), QueueInfo.TOPIC3.getRoutingKey(), String.format("TOPIC3 routingKey % s", QueueInfo.TOPIC3.getRoutingKey()));
    rabbitTemplate.convertAndSend(QueueInfo.TOPIC4.getExchange(), QueueInfo.TOPIC4.getRoutingKey(), String.format("TOPIC4 routingKey % s", QueueInfo.TOPIC4.getRoutingKey()));
    rabbitTemplate.convertAndSend(QueueInfo.HEADERS.getExchange(), QueueInfo.HEADERS.getRoutingKey(), String.format("HEADERS have routingKey % s", QueueInfo.HEADERS.getRoutingKey()));

    while (true);
}
/ * * *@author Kakki
 * @version 1.0
 * @createThe 2021-06-18 "* /
@Component
@Slf4j
public class MqCustomer {

    @RabbitListener(queues = {"FANOUT_QUEUE"})
    public void handlerF(Message message) {
        log.info("[News comes]:{}".new String(message.getBody(), StandardCharsets.UTF_8));
    }

    @RabbitListener(queues = {"DIRECT_QUEUE"})
    public void handlerD(Message message) {
        log.info("[News comes]:{}".new String(message.getBody(), StandardCharsets.UTF_8));
    }

    @RabbitListener(queues = {"TOPIC_QUEUE"})
    public void handlerT(Message message) {
        log.info("[News comes]:{}".new String(message.getBody(), StandardCharsets.UTF_8));
    }

    @RabbitListener(queues = {"HEADERS_QUEUE"})
    public void handlerH(Message message) {
        log.info("[News comes]:{}".newString(message.getBody(), StandardCharsets.UTF_8)); }}Copy the code
The 16:48:14 2021-06-30. 16460-638 the INFO [ntContainer# 0-1] com. Example. Demo. Config. MqCustomer: [news] : DIRECT routingKey 16:48:14 2021-06-30. 16460-638 the INFO] [ntContainer# 1-1 com. Example. Demo. Config. MqCustomer: [news] : the fanout routingKey 16:48:14 2021-06-30. 16460-638 the INFO] [ntContainer# 3-1 com. Example. Demo. Config. MqCustomer: HEADERS has routingKeyHEADERS_ROUTING_KEY 2021-06-30 16:48:14.638 INFO 16460 -- [ntContainer#2-1] com.example.demo.config.MqCustomer : [message comes]:TOPIC1 has routingKeyTOPIC_ROUTING_KEY.# 2021-06-30 16:48:14.638 INFO 16460 -- [ntContainer#1-1] com.example.demo.config.MqCustomer : [news] : the fanout routingKey 16:48:14. 2021-06-30 638 INFO 16460-2-1] [ntContainer# com. Example. Demo. Config. MqCustomer: [message is coming]:TOPIC2 has routingkeytopic_routing_key.aaab 2021-06-30 16:48:14.639 INFO 16460 -- [ntContainer#2-1] com.example.demo.config.MqCustomer : [message is coming]:TOPIC3 has routingkeytopic_routing_key.aaac.aaak 2021-06-30 16:48:14.639 INFO 16460 -- [ntContainer#2-1] Com. Example. Demo. Config. MqCustomer: [news] : there are routingKeyNO_KEY TOPIC4Copy the code
  • Therefore, messages sent to different types of switches may have different effects. How to configure these types of switches or how to select switches depends on the service scenario.
  • I have a mistake here, that is, when sending the Fanout switch, the type of fanout switch is not actually used to send, so why does it still arrive? I’ll leave you to think about that. We’ll talk more about that in the next chapter.

summary

In the case of MQ, of course, it is for business decoupling and peak shaving in high concurrency scenarios. There are many unexpected uses for being skilled with MQ. Of course this article is for beginners. Of course not. I would like to write down all I know, but I am afraid it will be too long and people will not like it (in fact, it is lazy), so I will say it in the next content about MQ!