SpringBoot整合RabbitMQ——Direct交换机


SpringBoot整合RabbitMQ——Direct交换机

前言

使用SpringBoot对RabbitMQ进行整合,模拟生产者服务器(9000)向向消费者服务器(8088)发送消息的过程,消息生产者通过接受Http请求向消息队列发送消息(Controller层、Service层),接收端则直接监听队列接收消息。这里Demo中通过请求两个不同的接口向不同的队列发送消息,在消费者端将会接收到对应监听队列的消息。

关于RabbitMQ的搭建及搭建中常见的问题参考连接:RabbitMQ搭建及问题

简介

Direct Exchange是RabbitMQ默认的交换机模式,也是最简单的模式,根据路由键全文匹配去寻找队列

Direct交换机

依赖

在pom.xml文件中添加依赖,主要是springboot中web和amqp的starter

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.0.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</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-amqp</artifactId>
        </dependency>
    </dependencies>

application.yml配置

消息生产者(发送端)配置,端口9000

server:
  port: 9000
spring:
  application:
    name: direct-sender
  rabbitmq:
    username: admin
    password: admin
    host: 192.168.108.128
    port: 5672

消费者(接收端)配置,端口8088

server:
  port: 8088
spring:
  application:
    name: direct-receiver
  rabbitmq:
    username: admin
    password: admin
    host: 192.168.108.128
    port: 5672

消息生产者(发送端)

配置SendConfig.java

配置中创建两个队列,分别为direct.queue.1和direct.queue.2,并且分别通过路由键direct.route.key.1和direct.route.key.2进行绑定。使用两个队列进行演示目的是展示交换机通过路由键将消息进行分发

@Configuration
public class SendConfig {
    public static final String DIRECT_QUEUE_1 = "direct.queue.1";
    public static final String DIRECT_QUEUE_2 = "direct.queue.2";
    public static final String DIRECT_EXCHANGE = "direct.exchange";
    public static final String DIRECT_ROUTE_KEY_1 = "direct.route.key.1";
    public static final String DIRECT_ROUTE_KEY_2 = "direct.route.key.2";

    @Bean
    public Queue directQueue1() {
        return new Queue(DIRECT_QUEUE_1);
    }

    @Bean
    public Queue directQueue2() {
        return new Queue(DIRECT_QUEUE_2);
    }

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

    @Bean
    public Binding binding1() {
        return BindingBuilder.bind(directQueue1()).to(directExchange()).with(DIRECT_ROUTE_KEY_1);
    }

    @Bean
    public Binding binding2() {
        return BindingBuilder.bind(directQueue2()).to(directExchange()).with(DIRECT_ROUTE_KEY_2);
    }

}

Controller层

设置访问路径和参数调用service层

@RestController
@RequestMapping("/direct")
public class SendController {

    @Autowired
    private DirectSendService directSendService;

    @GetMapping("/queue1/{msg}")
    public void sendQueue1(@PathVariable String msg) {
        directSendService.sendQueue1(msg);
    }

    @GetMapping("/queue2/{msg}")
    public void sendQueue2(@PathVariable String msg) {
        directSendService.sendQueue2(msg);
    }
}

Service层

使用RabbitTemplate的convertAndSend方法进行发送,方法有很多重载方法,选用convertAndSend(String exchange, String routingKey, Object object),指定交换机、路由键和发送的消息

@Service
public class DirectSendServiceImpl implements DirectSendService {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public void sendQueue1(String msg) {
        System.out.println("发送到队列1:" + msg);
        rabbitTemplate.convertAndSend(SendConfig.DIRECT_EXCHANGE, SendConfig.DIRECT_ROUTE_KEY_1, msg);
    }

    @Override
    public void sendQueue2(String msg) {
        System.out.println("发送到队列2:" + msg);
        rabbitTemplate.convertAndSend(SendConfig.DIRECT_EXCHANGE, SendConfig.DIRECT_ROUTE_KEY_2, msg);
    }
}

消费者(接收端)

消息接收端通过@RabbitListener注解监听队列,当队列有消息时自动读取

@Component
public class DirectReceiver {
    @RabbitListener(queues = "direct.queue.1")
    public void receiveDirect1(String msg) {
        System.out.println("接收到direct.queue.1的消息:" + msg);
    }

    @RabbitListener(queues = "direct.queue.2")
    public void receiveDirect2(String msg) {
        System.out.println("接收到direct.queue.2的消息:" + msg);
    }
}

验证

启动服务器,分别调用发送端接口

http://127.0.0.1:9000/direct/queue1/direct
http://127.0.0.1:9000/direct/queue2/direct

调用成功后RabbitMQ管理页面中便会新增两个队列,对列名为SendConfig中设置的名字
在这里插入图片描述

此时在消费者端控制台中会显示接收到的数据
在这里插入图片描述

此时如果关闭接收端服务器,然后一直调用发送接口,消息会都积累在队列中,在管理页面中显示为ready。
在这里插入图片描述

当再次启动接收端时便会以此将消息从队列中读取出来

代码地址

RabbitDemo代码

参考

初识RabbitMQ——AMQP 0-9-1

RabbitMQ——RabbitMQ搭建及问题

SpringBoot整合RabbitMQ——Direct交换机

SpringBoot整合RabbitMQ——Topic交换机

SpringBoot整合RabbitMQ——Headers交换机

### Spring Boot 集成 RabbitMQ 交换机与队列的工厂初始化实现 在 Spring Boot 中,可以通过声明式的配置类来完成 RabbitMQ交换机、队列以及绑定关系的初始化。以下是具体的实现方式: #### 添加依赖 为了支持 RabbitMQ 功能,在项目的 `pom.xml` 文件中需引入以下 Maven 依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> ``` 此依赖会自动导入 RabbitMQ 所需的核心库和 Spring AMQP 支持[^2]。 #### 创建配置类 通过定义一个 Java 配置类,可以利用 Spring 提供的 Bean 定义机制来初始化交换机、队列及其绑定关系。下面是一个完整的示例代码: ```java import org.springframework.amqp.core.*; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class RabbitMqConfig { // 定义队列 @Bean public Queue myQueue() { return new Queue("my.queue", true, false, false); } // 定义交换机 @Bean public TopicExchange myExchange() { return new TopicExchange("my.exchange"); } // 绑定队列到交换机 @Bean public Binding binding(Queue myQueue, TopicExchange myExchange) { return BindingBuilder.bind(myQueue).to(myExchange).with("routing.key"); } } ``` 在此代码片段中,分别创建了一个持久化的队列 (`my.queue`) 和一个主题类型的交换机 (`my.exchange`) 并将其绑定在一起,指定路由键为 `"routing.key"`[^3]。 #### 工厂模式下的自定义初始化 如果需要更复杂的逻辑控制或者动态参数化,则可通过继承默认的工厂类来自定义行为。例如,重写 `DirectExchange`, `FanoutExchange`, 或者 `TopicExchange` 来满足特定业务场景的要求。 对于高级特性如 **死信队列 (DLQ)** ,也可以通过扩展的方式实现: ```java @Bean public Queue deadLetterQueue() { Map<String, Object> args = new HashMap<>(); args.put("x-dead-letter-exchange", "dlx.exchange"); // 死信转发的目标交换机名称 args.put("x-message-ttl", 60000); // 设置消息存活时间(ms),超时进入 DLX return new Queue("dead.letter.queue", true, false, false, args); } ``` 上述例子展示了如何基于参数化构造函数传递额外属性给队列实例,从而启用死信功能[^3]。 --- #### 性能优化建议 当面对高并发环境时,考虑调整线程池大小或预取计数等性能调优选项可能有助于提升吞吐量和服务稳定性。这些设置通常位于 application.properties/yml 文件下,比如: ```properties spring.rabbitmq.listener.simple.concurrency=5-10 spring.rabbitmq.listener.direct.prefetch=10 ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值