Springboot 2.x 使用消息队列 RabbitMQ 的 direct 模式(路由模式)

参考

  1. 《Spring Boot实战派》
  2. 消息队列RabbitMQ入门与5种模式详解(讲解了用户权限的问题,可以看一看)
  3. springboot(集成篇):RabbitMQ集成详解

必看

  • 如果要发送对象,发送的对象需要继承 Serializable 类。
  • 可以创建多个消费者,消息会均匀的分配给消费者。
    image
  • 任务失败后会自动重试,建议自己处理一下这方面的问题。
  • RabbitMQ 服务手动关闭(模拟宕机),调用生产者失败会产生错误,需要做异常的预处理。
  • 开启持久化以后,RabbitMQ 关闭后再重启,消息还存在。

建议

环境

环境 版本 操作
windows 10
vs code 1.84.2
Spring Boot Extension Pack v0.2.1 vscode插件
Extension Pack for Java v0.25.15 vscode插件
JDK 11
Springboot 2.3.12.RELEASE
mybatis-spring-boot-starter 2.1.4 mvn依赖
spring-boot-starter-amqp 3.2.0 mvn依赖
Apache Maven 3.8.6
Erlang 26.2.1 下载
RabbitMQ 3.12.10 下载

正文

  1. pom.xml添加依赖
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-amqp -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
    <version>3.2.0</version>
</dependency>
  1. 创建配置类、声明队列并绑定队列
package com.xiaqiuchu.demo.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 RabbitConfig {

    /**
     * 声明交互器/交换机 direct
     * @return
     */
    @Bean
    DirectExchange directExchange() {
        return new DirectExchange("direct.exchange");
    }

    @Bean
    public Queue studentToOld() {
        // true表示持久化该队列
        return new Queue("student.to.old", true);
    }

    /**
     * 绑定队列,并设置路由key,如果还有别的队列,再创建一个函数绑定即可
     * @return
     */
    @Bean
    public Binding bindingStudentToOld() {
        return BindingBuilder.bind(studentToOld()).to(directExchange()).with("student.to.old");
    }

    // @Bean
    // public Queue testDataPersistence() {
    //     // true表示持久化该队列
    //     return new Queue("test.data.persistence", true);
    // }

    // /**
    //  * 绑定队列,并设置路由key,如果还有别的队列,再创建一个函数绑定即可
    //  * @return
    //  */
    // @Bean
    // public Binding bindingTestDataPersistence() {
    //     return BindingBuilder.bind(testDataPersistence()).to(directExchange()).with("test.data.persistence");
    // }
}
  1. 创建生产者(可以发送对象)

package com.xiaqiuchu.demo.component;

import javax.annotation.Resource;

import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.stereotype.Component;

import com.xiaqiuchu.demo.entity.Student;

@Component
public class StudentToOldProducer {
    @Resource
    private AmqpTemplate amqpTemplate;

    /**
     * 发送队列
     * 
     * @param student
     */
    public void sendMessage(Student student) {
        System.out.println("生产者 student.to.old 发送消息: " + student);
        /**
         * 第一个参数指定交换机
         * 第二个参数指定队列
         * 第三个参数指定消息内容
         */
        amqpTemplate.convertAndSend("direct.exchange", "student.to.old", student);

    }
}

  1. 创建消费者
package com.xiaqiuchu.demo.component;

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

import com.xiaqiuchu.demo.entity.Student;

@Component
@RabbitListener(queues = "student.to.old")
public class StudentToOldConsumer {
    @RabbitHandler
    public void process(Student student){
            System.out.println("消费者 student.to.old  收到消息: "+student.getName()
        );
    }
}

  1. 用户实体
package com.xiaqiuchu.demo.entity;

import java.io.Serializable;
import java.sql.Date;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;
    
    private String name;

    private Byte age;

    private Integer teamId;

    private Date createdAt;

    private Date updatedAt;

    private Team team;
}

  1. 控制器(调用生产者)
package com.xiaqiuchu.demo.controller;


import javax.annotation.Resource;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.xiaqiuchu.demo.component.StudentToOldProducer;
import com.xiaqiuchu.demo.component.TestDataPersistenceProducer;
import com.xiaqiuchu.demo.entity.Student;
import com.xiaqiuchu.demo.service.StudentService;
import org.springframework.web.bind.annotation.GetMapping;



@RestController
@RequestMapping("/rabbit_mq")
public class RabbitMQController {
    
    @Resource
    TestDataPersistenceProducer testDataPersistenceProducer;

    @Resource
    StudentToOldProducer studentToOldProducer;

    @Resource
    StudentService studentService;

    // 127.0.0.1:8080/rabbit_mq/testDataPersistenceProducer
    // @GetMapping("testDataPersistenceProducer")
    // public String testDataPersistenceProducer() {
    //     testDataPersistenceProducer.sendMessage("测试持久化 " + System.currentTimeMillis());
    //     return "SUCCESS";
    // }

    // 127.0.0.1:8080/rabbit_mq/studentToOldProducer
    @GetMapping("studentToOldProducer")
    public String studentToOldProducer() {
        Student student = studentService.findById(1L);
        studentToOldProducer.sendMessage(student);
        return "SUCCESS";
    }
    
    
}

  1. application.properties 配置文件内添加配置参数
# 如果访问局域网的mq服务,需要配置账户并允许远程访问 ,参考:https://www.cnblogs.com/xiaqiuchu/p/15616432.html
spring.rabbitmq.host=192.168.211.2
# 指定端口号
spring.rabbitmq.port=5672
# 指定账号,默认账号不可以在其他机器登录
spring.rabbitmq.username=testmail
# 指定密码
spring.rabbitmq.password=testmail

测试

  1. 运行本项目

  2. 访问控制台可以看到该交换机
    image

  3. 点击进入交换机详情可以看到交换机内部的队列
    image

  4. 测试发送消息显示消费者接受到
    image

posted @   夏秋初  阅读(282)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
点击右上角即可分享
微信分享提示