Springboot 2.x 使用消息队列 RabbitMQ 的 direct 模式(路由模式)
参考
- 《Spring Boot实战派》
- 消息队列RabbitMQ入门与5种模式详解(讲解了用户权限的问题,可以看一看)
- springboot(集成篇):RabbitMQ集成详解
必看
- 如果要发送对象,发送的对象需要继承
Serializable
类。 - 可以创建多个消费者,消息会均匀的分配给消费者。
- 任务失败后会自动重试,建议自己处理一下这方面的问题。
- RabbitMQ 服务手动关闭(模拟宕机),调用生产者失败会产生错误,需要做异常的预处理。
- 开启持久化以后,RabbitMQ 关闭后再重启,消息还存在。
建议
- RabbitMQ 有多种模式及相关配置这里不再描述,建议搜索了解一下;本文只介绍 direct 模式的实现。
- 关于Windows下的安装及开启web管理面板可以参考一下 【2021/11/28 基于RabbitMQ3.9.10】Windows安装RabbitMQ,并解决远程登录guest账号提示User can only log in via localhost 的问题
环境
环境 | 版本 | 操作 |
---|---|---|
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 | 下载 |
正文
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>
- 创建配置类、声明队列并绑定队列
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");
// }
}
- 创建生产者(可以发送对象)
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);
}
}
- 创建消费者
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()
);
}
}
- 用户实体
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;
}
- 控制器(调用生产者)
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";
}
}
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
测试
-
运行本项目
-
访问控制台可以看到该交换机
-
点击进入交换机详情可以看到交换机内部的队列
-
测试发送消息显示消费者接受到
博 主 :夏秋初
地 址 :https://www.cnblogs.com/xiaqiuchu/p/15618485.html
如果对你有帮助,可以点一下 推荐 或者 关注 吗?会让我的分享变得更有动力~
转载时请带上原文链接,谢谢。
地 址 :https://www.cnblogs.com/xiaqiuchu/p/15618485.html
如果对你有帮助,可以点一下 推荐 或者 关注 吗?会让我的分享变得更有动力~
转载时请带上原文链接,谢谢。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .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 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义