头图
Let's study the message queue, now let's build it briefly.

1. Docker build RabbitMQ

1.1 Query and download RabbitMQ mirror

docker search rabbitmq

image.png

// 选择可以访问web管理界面的tag
docker pull rabbitmq:management

image.png

1.2 Run RabbitMQ mirroring

// 设置账号密码都为admin
docker run -dit --name myrabbitmq -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin -p 15672:15672 -p 5672:5672 rabbitmq:management

1.3 Access server IP on the browser: 15672

The following page appears to indicate successful startup
image.png

2. Build a SpringBoot project to integrate RabbitMQ

2.1 pom.xml

Add web and rabbitmq dependencies

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

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

2.2 aplication.yml

Configure rabbitmq's address, username, password, etc.

spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: admin
    password: admin

2.3 New Switch SenderConfig.java

There are the following three commonly used switches, we use the third one here

DirectExchange
Directly connected switch, according to the routing key carried in the message, forward the message to the corresponding queue
FanoutExchange
Sector switch, after receiving the message, it will forward the message to all queues
TopicExchange
The topic switch, according to the routing key carried in the message and the rules of the switch and the queue binding key, forward the message to the corresponding queue
rule:
* (Asterisk): Indicates that a character must appear
# (Pound sign): Represents any number of characters
/**
 * 交换机
 * @author zhouzhaodong
 */
@Configuration
public class SenderConfig {

    /**
     * ----- 交换机 -----
     * 参数意义:
     *   name: 名称
     *   durable: 持久化
     *   autoDelete: 自动删除
     */
    @Bean
    public TopicExchange topicExchange() {
        return new TopicExchange("topicExchange", true, false);
    }

    /**
     * ----- 队列 -----
     */
    @Bean
    public Queue queueOne() {
        return new Queue("queueOne", true);
    }

    @Bean
    public Queue queueTwo() {
        return new Queue("queueTwo", true);
    }

    @Bean
    public Queue queueThree() {
        return new Queue("queueThree", true);
    }

    /**
     * ----- 绑定 -----
     * routingKey就是路由规则,消息对应的队列,用来区分不同的消息队列
     */
    @Bean
    public Binding bindingFanoutOne() {
        return BindingBuilder.bind(queueOne()).to(topicExchange()).with("topic_one");
    }

    @Bean
    public Binding bindingFanoutTwo() {
        return BindingBuilder.bind(queueTwo()).to(topicExchange()).with("topic_two");
    }

    @Bean
    public Binding bindingFanoutThree() {
        return BindingBuilder.bind(queueThree()).to(topicExchange()).with("topic_one");
    }

}

2.4 Sender SenderController.java

/**
 * 消息发送者
 *
 * @author zhouzhaodong
 */
@RestController
public class SenderController {

    @Resource
    AmqpTemplate amqpTemplate;

    Logger logger = LoggerFactory.getLogger(SenderController.class);

    @RequestMapping(value = "/send")
    public String sendMessage(String message) {
        logger.info("消息发送开始时间:" + new Date());
        // 这里convertAndSend第一个参数是交换机的名称
        // 第二个参数可以是routingKey
        // 最后一个参数就是要发送的消息
        amqpTemplate.convertAndSend("topicExchange", "topic_one", message);
        return "发送成功";
    }

}

2.5 Consumer ReceiverController.java

/**
 * 消费者
 * @author zhouzhaodong
 */
@Component
public class ReceiverController {

    Logger logger = LoggerFactory.getLogger(ReceiverController.class);

    @RabbitHandler
    @RabbitListener(queues = "queueOne")
    public void processA(String message){
        logger.info("queueOne接收消息时间为:" + new Date());
        logger.info("queueOne接收消息为:" + message);
    }

    @RabbitHandler
    @RabbitListener(queues = "queueTwo")
    public void processB(String message){
        logger.info("queueTwo接收消息时间为:" + new Date());
        logger.info("queueTwo接收消息为:" + message);
    }

    @RabbitHandler
    @RabbitListener(queues = "queueThree")
    public void processC(String message){
        logger.info("queueThree接收消息时间为:" + new Date());
        logger.info("queueThree接收消息为:" + message);
    }

}

3. Start the project for testing

3.1 Call the producer interface

image.png
It is found that two queues have received the message, because the routingKey configured for both queues is the same, and both are topic_one
image.png

3.2 Access without routingKey

image.png
Found that there is no queue to receive the message
image.png

End of test

Personal blog address:

http://www.zhouzhaodong.xyz/

Source code address:

https://gitee.com/zhouzhaodong/springboot/tree/master/rabbitmq


周兆东
107 声望21 粉丝

一个java小白的成长之路。。。