RabbitMQ working model and use in java

I wrote an article about the installation of RabbitMQ in the linux environment before. This article shares the working model of RabbitMQ and its use in java.

Rabbit official website: http://www.rabbitmq.com/

Features of RabbitMQ:

  • Reliability: Provides a message confirmation mechanism
  • Flexible routing: provide switches internally, and flexibly route to queues through switches
  • Message cluster: support cluster deployment
  • Availability: Mirrored queues can be used to ensure availability
  • Cross-language, cross-platform: provide clients in multiple languages ​​and support other languages
  • Plug-in mechanism: support adding plug-ins
  • management interface

Protocol used by RabbitMQ:

AMQP protocol (Advancde Message Queuing Protocol), an application layer standard advanced message queuing protocol that provides unified messaging services, is a development standard for application layer protocols, designed for message-oriented middleware. Clients and small middleware based on this protocol can transmit messages, and are not limited by conditions such as client/middleware products and different development languages. Cross language, cross system, cross platform.

 

Working model of RabbitMQ:

 

Introduction to RabbitMQ terminology:

Message producer : it is used to send messages

Routing key: The switch puts the message into the corresponding binding queue according to the routing key

Switch: The switch is the bridge between the producer and the queue

Binding keyword: Binding to the switch. As mentioned above, the switch will send the message to the corresponding binding queue according to the routing keyword. How to execute it? That is, it will match the routing keyword with the binding keyword, and send it if the match is successful.

Queue: The queue is the carrier of the message

Host: the RabbitMQ server

Virtual machine: A RabbitMQ server can create multiple virtual machines, and a virtual machine can have multiple switches and multiple queues

connection: It is the socket link of RabbitMQ, which encapsulates the logic related to the socket protocol

Channel: Channel is the most important interface for us to deal with RabbitMQ. Most of our business operations are completed in the Channel interface, including defining Queue, defining Exchange, binding Queue and Exchange, publishing messages, etc.

Message consumer: used to consume messages

RabbitMQ basic use:

This article uses SpringBoot directly for development.

Message consumer:

Project structure:

Add pom dependencies

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

Add connection configuration application.properties

spring.application.name=spring-boot-rabbitmq
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest

Create a configuration class: RabbitConfig

Three types of switches and four queues are created here. Switch types are covered later.

package com.zbb.rabbitmq_consumer.config;

import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 配置类,需要使用configuration注解
 */
@Configuration
public class RabbitConfig {
    //定义三个交换机

    /**
     * 直连交换机
     * @return
     */
    @Bean
    public DirectExchange directExchange(){
        return new DirectExchange("DIRECT_EXCHANGE");
    }

    /**
     * 主题交换机
     * @return
     */
    @Bean
    public TopicExchange topicExchange(){
        return new TopicExchange("TOPIC_EXCHANGE");
    }

    /**
     * 广播交换机
     * @return
     */
    @Bean
    public FanoutExchange fanoutExchange(){
        return new FanoutExchange("FANOUT_EXCHANGE");
    }
    //定义四个队列
    @Bean
    public Queue firsQueue(){
        return new Queue("FIST_QUEUE");
    }

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

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

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

    //定义四个绑定关系
    @Bean
    public Binding bindFirst(@Qualifier("firsQueue") Queue queue,
                             @Qualifier("directExchange") DirectExchange directExchange){
        return BindingBuilder.bind(queue).to(directExchange).with("zbb.test");
    }

    @Bean
    public Binding bindSecond(@Qualifier("secondQueue") Queue queue,
                              @Qualifier("topicExchange") TopicExchange topicExchange) {
        return BindingBuilder.bind(queue).to(topicExchange).with("*.zbb.*");
    }

    @Bean
    public Binding bindThird(@Qualifier("thirdQueue") Queue queue,
                             @Qualifier("fanoutExchange") FanoutExchange fanoutExchange) {
        return BindingBuilder.bind(queue).to(fanoutExchange);
    }

    @Bean
    public Binding bindFourth(@Qualifier("fourthQueue") Queue queue,
                              @Qualifier("fanoutExchange") FanoutExchange fanoutExchange) {
        return BindingBuilder.bind(queue).to(fanoutExchange);
    }

}

Create four consumers, each listening to four queues

1、FirstConsumer
package com.zbb.rabbitmq_consumer.consumer;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
@RabbitListener(queues = "FIST_QUEUE")
public class FirstConsumer {
    @RabbitHandler
    public void process(String msg) {
        System.out.println("消费者一收到消息:"+msg);
    }
}
2、SecondConsumer
package com.zbb.rabbitmq_consumer.consumer;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
@RabbitListener(queues = "SECOND_QUEUE")
public class SecondConsumer {
    @RabbitHandler
    public void process(String msg) {
        System.out.println("消费者二收到消息:"+msg);
    }
}
3、ThirdConsumer
package com.zbb.rabbitmq_consumer.consumer;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
@RabbitListener(queues = "THIRD_QUEUE")
public class ThirdConsumer {
    @RabbitHandler
    public void process(String msg) {
        System.out.println("消费者三收到消息:"+msg);
    }
}
4、FourthConsumer
package com.zbb.rabbitmq_consumer.consumer;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
@RabbitListener(queues = "FOURTH_QUEUE")
public class FourthConsumer {
    @RabbitHandler
    public void process(String msg) {
        System.out.println("消费者四收到消息:"+msg);
    }
}
 

Message producer:

引入pom依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
创建生产者类,给三个交换机发送消息
package com.zbb.rabbitmq_producer.producer;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MyProducer {

    @Autowired
    RabbitTemplate rabbitTemplate;

    public void send(){
        //直连
        rabbitTemplate.convertAndSend("DIRECT_EXCHANGE", "zbb.test",
                "this is a direct msg");
        //主题
        rabbitTemplate.convertAndSend("TOPIC_EXCHANGE","kaifa.zbb.IT", 
                "this is a Topic msg");

        //广播
        rabbitTemplate.convertAndSend("FANOUT_EXCHANGE", "",
                "this is a fanout msg");
    }
}
修改测试类:
package com.zbb.rabbitmq_producer;

import com.zbb.rabbitmq_producer.producer.MyProducer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

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

    @Autowired
    MyProducer myProducer;

    @Test
    public void contextLoads() {
        myProducer.send();
    }

}

我们先启动消息生产者,打开管理界面可以看到四个队列里都有一条消息堆积

Now after starting the message consumer, you will find that the console prints out the message, and the management interface changes:

This is the simple use of RabbitMQ in java. The specific use in the project needs to be combined with the business to send and receive messages.

The following will introduce an important thing in RabbitMQ: switch Exchange

Only three main switches are introduced here.

Direct Exchange direct switch

When a direct-connected switch is bound to a queue, an explicit binding key (binding key) needs to be specified.
Routing rules: When sending a message to a direct-connected switch, only when the routing key (routing key) exactly matches the binding key (binding key), the bound queue can receive the message.

queue:

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

switch:

@Bean
public DirectExchange directExchange(){
    return new DirectExchange("DIRECT_EXCHANGE");
}

bind:

@Bean
public Binding bindFirst(@Qualifier("firsQueue") Queue queue,
                         @Qualifier("directExchange") DirectExchange directExchange){
    return BindingBuilder.bind(queue).to(directExchange).with("zbb.test");
}

Send a message:

rabbitTemplate.convertAndSend("DIRECT_EXCHANGE", "zbb.test",
                "this is a direct msg");

Topic Exchange Topic Exchange

Definition: When a topic-type switch is bound to a queue, you can specify a routing key for pattern matching.
There are two wildcards, * means match a word. # stands for matching zero or more words. Separate words with .
Routing rules: When sending a message to a topic-type switch, the bound queue can only receive the message when the routing key matches the mode of the binding key

queue:

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

switch:

@Bean
public TopicExchange topicExchange(){
    return new TopicExchange("TOPIC_EXCHANGE");
}

bind:

@Bean
public Binding bindSecond(@Qualifier("secondQueue") Queue queue,
                          @Qualifier("topicExchange") TopicExchange topicExchange) {
    return BindingBuilder.bind(queue).to(topicExchange).with("*.zbb.*");
}

Send a message:

//主题
rabbitTemplate.convertAndSend("TOPIC_EXCHANGE","kaifa.zbb.IT",
                              "this is a Topic msg");

Fanout Exchange broadcast switch, bind two queues thirdQueue fourthQueue

Definition: When a broadcast switch is bound to a queue, it is not necessary to specify a binding key.
Routing rules: When a message is sent to a broadcast switch, it is not necessary to specify a routing key, and all queues bound to it can receive the message.

queue:

@Bean
public Queue thirdQueue(){
    return new Queue("THIRD_QUEUE");
}
@Bean
public Queue fourthQueue(){
    return new Queue("FOURTH_QUEUE");
}

switch:

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

Send a message:

//广播
rabbitTemplate.convertAndSend("FANOUT_EXCHANGE", "",
                "this is a fanout msg");

 

Guess you like

Origin blog.csdn.net/u010994966/article/details/86508625