• SpringBoot整合RabbitMQ之Direct交换器


    本实例需要两个项目:rabbitmq-provider (生产者),一个rabbitmq-consumer(消费者)。

    首先先建立rabbitmq-provider项目

    pom.xml配置

    <dependencies>
    <!--rabbitmq-->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
    <version>2.3.0.RELEASE</version>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.3.0.RELEASE</version>
    </dependency>
    </dependencies>

    创建application.yml文件

    server:
      port: 8021
    spring:
      #给项目来个名字
      application:
        name: rabbitmq-provider
      #配置rabbitMq 服务器
      rabbitmq:
        host: 127.0.0.1
        port: 5672
        username: guest
        password: guest
    #    connection-timeout: 60s
        #虚拟host 可以不设置,使用server默认host
        #virtual-host: admin

    创建DirectRabbitConfig配置类

    package com.rabbitmq.provider.config;
    
    import org.springframework.amqp.core.Binding;
    import org.springframework.amqp.core.BindingBuilder;
    import org.springframework.amqp.core.DirectExchange;
    import org.springframework.amqp.core.Queue;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    
    @Configuration
    public class DirectRabbitConfig {
    
        // 队列,起名:TestDirectQueue
        @Bean
        public Queue TestDirectQueue() {
            // durable:是否持久化,默认false,持久化队列:会被存储在磁盘上,当消息代理重启时仍然存在
            // exclusive:暂存队列:当前连接有效,默认也是false,只能被当前创建的连接使用,而且当连接关闭后队列即被删除。此参考优先级高于durable
            // autoDelete:是否自动删除,当没有生产者或者消费者使用此队列,该队列会自动删除。
            // return new Queue("TestDirectQueue",true,true,false);
            // 一般设置一下队列的持久化就好,其余两个就是默认false
            return new Queue("TestDirectQueue",true);
        }
    
        // Direct交换机 起名:TestDirectExchange
        @Bean
        DirectExchange TestDirectExchange() {
            // return new DirectExchange("TestDirectExchange",true,true);
            return new DirectExchange("TestDirectExchange",true,false);
        }
    
        // 绑定 将队列和交换机绑定,并设置用于匹配键:TestDirectRouting
        @Bean
        Binding bindingDirect() {
            return BindingBuilder.bind(TestDirectQueue()).to(TestDirectExchange()).with("TestDirectRouting");
        }
    
    }

    写一个简单的接口进行消息推送,创建SendMessageController

    package com.rabbitmq.provider.controller;
    
    import org.springframework.amqp.rabbit.core.RabbitTemplate;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.time.LocalDateTime;
    import java.time.format.DateTimeFormatter;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.UUID;
    
    @RestController
    public class SendMessageController {
    
        @Autowired
        RabbitTemplate rabbitTemplate; //使用RabbitTemplate,这提供了接收发送等方法
    
        @GetMapping("/sendDirectMessage")
        public String sendDirectMessage(){
            String messageId = String.valueOf(UUID.randomUUID());
            String messageData = "test message hello!";
            String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss"));
            Map<String,Object> map = new HashMap<>();
            map.put("messageId",messageId);
            map.put("messageData",messageData);
            map.put("createTime",createTime);
            rabbitTemplate.convertAndSend("TestDirectExchange","TestDirectRouting",map);
            return "ok";
        }
    }

    创建主启动类ProviderMain

    package com.rabbitmq.provider;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
    
    @SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
    public class ProviderMain {
        public static void main(String[] args) {
            SpringApplication.run(ProviderMain.class,args);
        }
    }

    启动项目,使用postman工具调用一下这个接口。

    打开浏览器,输入:http://127.0.0.1:15672

    进入管理页面查看消息是否增加

    至此,rabbitmq-provider (生产者)暂时结束,现在开始编写rabbitmq-consumer(消费者)

    创建项目rabbitmq-consumer(消费者)

    pom.xml

        <dependencies>
            <!--rabbitmq-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-amqp</artifactId>
                <version>2.3.0.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <version>2.3.0.RELEASE</version>
            </dependency>
        </dependencies>

    创建application.yml文件

    server:
      port: 8022
    spring:
      #给项目来个名字
      application:
        name: rabbitmq-consumer
      #配置rabbitMq 服务器
      rabbitmq:
        host: 127.0.0.1
        port: 5672
        username: guest
        password: guest

    创建DirectRabbitConfig配置类

    package com.rabbitmq.consumer.config;
    
    import org.springframework.amqp.core.Binding;
    import org.springframework.amqp.core.BindingBuilder;
    import org.springframework.amqp.core.DirectExchange;
    import org.springframework.amqp.core.Queue;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class DirectRabbitConfig {
    
    
        @Bean
        Queue TestDirectQueue() {
            return new Queue("TestDirectQueue",true);
        }
    
        @Bean
        DirectExchange TestDirectExchange() {
            return new DirectExchange("TestDirectExchange");
        }
    
        @Bean
        Binding bindingDirect() {
            return BindingBuilder.bind(TestDirectQueue()).to(TestDirectExchange()).with("TestDirectRouting");
        }
    }

    创建消息接收监听类,DirectReceiver.java:

    package com.rabbitmq.consumer.receiver;
    
    import org.springframework.amqp.rabbit.annotation.RabbitHandler;
    import org.springframework.amqp.rabbit.annotation.RabbitListener;
    import org.springframework.stereotype.Component;
    
    import java.util.Map;
    
    @Component
    @RabbitListener(queues = "TestDirectQueue") //监听的队列名称
    public class DirectReceiver {
    
        @RabbitHandler
        public void process(Map testMessage) {
            System.out.println("第一个DirectReceiver消费者收到消息 :" + testMessage);
        }
    }

    创建主启动类ConsumerMain

    package com.rabbitmq.consumer;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
    
    @SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
    public class ConsumerMain {
        public static void main(String[] args) {
            SpringApplication.run(ConsumerMain.class,args);
        }
    }

    运行rabbitmq-consumer项目,使用postman请求一下生产消息接口,可以看到消息被监听到并消费

     

     设想,如果有多个监听类监听一个队列会怎么样?

    在rabbitmq-consumer项目上创建监听类DirectReceiverNew

    package com.rabbitmq.consumer.receiver;
    
    import org.springframework.amqp.rabbit.annotation.RabbitHandler;
    import org.springframework.amqp.rabbit.annotation.RabbitListener;
    import org.springframework.stereotype.Component;
    
    import java.util.Map;
    
    @Component
    @RabbitListener(queues = "TestDirectQueue")
    public class DirectReceiverNew {
    
        @RabbitHandler
        public void process(Map testMessage) {
            System.out.println("第二个DirectReceiver消费者收到消息 :" + testMessage);
        }
    }

    重启rabbitmq-consumer服务,多调用几次postman查看一下

     可以看到是实现了轮询的方式对消息进行消费,而且不存在重复消费。

    案例学习于这位大佬的博客:https://blog.csdn.net/qq_35387940/article/details/100514134

    受益良多,记录一下笔记

  • 相关阅读:
    Java后端面试题大汇总,冲刺金三银四
    面试官:小伙子,Mybatis的本质和原理说一下
    面试官问:大量的 TIME_WAIT 状态 TCP 连接,对业务有什么影响?怎么处理?
    便捷搭建 Zookeeper 服务器的方法,好用,收藏~
    10 个冷门但又非常实用的 Docker 使用技巧
    mitmproxy 抓包工具(1)
    基于alpine创建Scrapy镜像
    强大的输入框-应用快速启动uTools
    Interceptor、Filter、Servlet的区别
    利用三层判断sql数据库中编码是否已经存在(个人拙作,不喜勿喷)
  • 原文地址:https://www.cnblogs.com/liweixml/p/14646297.html
Copyright © 2020-2023  润新知